You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/08/27 21:57:24 UTC
[commons-bcel] branch master updated: Add missing Java 9 and Java
11 class file attributes. (#33)
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git
The following commit(s) were added to refs/heads/master by this push:
new 8dc6bba Add missing Java 9 and Java 11 class file attributes. (#33)
8dc6bba is described below
commit 8dc6bbae4dff5434ae0a112f1a9ace6066074906
Author: Mark Roberts <ma...@users.noreply.github.com>
AuthorDate: Tue Aug 27 14:57:20 2019 -0700
Add missing Java 9 and Java 11 class file attributes. (#33)
* Add missing Java 9 and Java 11 class file attributes.
* update for newer attributes
* add missing visitor needed by java 11
* Correct version number comments.
Supply default visitMethodParameter implementation for Visitor interface.
---
src/examples/ClassDumper.java | 25 +-
src/main/java/org/apache/bcel/Const.java | 91 +++++---
.../java/org/apache/bcel/classfile/Attribute.java | 10 +
.../org/apache/bcel/classfile/BootstrapMethod.java | 6 +-
.../apache/bcel/classfile/BootstrapMethods.java | 11 +-
.../org/apache/bcel/classfile/ConstantPackage.java | 2 +-
.../org/apache/bcel/classfile/ConstantPool.java | 18 +-
.../apache/bcel/classfile/DescendingVisitor.java | 105 +++++++++
.../org/apache/bcel/classfile/EmptyVisitor.java | 54 ++++-
.../java/org/apache/bcel/classfile/InnerClass.java | 4 +-
.../org/apache/bcel/classfile/InnerClasses.java | 2 +-
.../java/org/apache/bcel/classfile/JavaClass.java | 2 +-
.../org/apache/bcel/classfile/MethodParameter.java | 4 +
.../java/org/apache/bcel/classfile/Module.java | 257 +++++++++++++++++++++
.../org/apache/bcel/classfile/ModuleExports.java | 125 ++++++++++
.../org/apache/bcel/classfile/ModuleMainClass.java | 137 +++++++++++
.../org/apache/bcel/classfile/ModuleOpens.java | 125 ++++++++++
.../org/apache/bcel/classfile/ModulePackages.java | 175 ++++++++++++++
.../org/apache/bcel/classfile/ModuleProvides.java | 121 ++++++++++
.../org/apache/bcel/classfile/ModuleRequires.java | 114 +++++++++
.../java/org/apache/bcel/classfile/NestHost.java | 138 +++++++++++
.../org/apache/bcel/classfile/NestMembers.java | 176 ++++++++++++++
.../java/org/apache/bcel/classfile/Visitor.java | 52 +++++
.../org/apache/bcel/generic/ConstantPoolGen.java | 4 +
.../verifier/statics/StringRepresentation.java | 9 +
.../org/apache/bcel/visitors/CounterVisitor.java | 101 ++++++++
26 files changed, 1816 insertions(+), 52 deletions(-)
diff --git a/src/examples/ClassDumper.java b/src/examples/ClassDumper.java
index bc2ed20..7fe2752 100644
--- a/src/examples/ClassDumper.java
+++ b/src/examples/ClassDumper.java
@@ -162,8 +162,8 @@ class ClassDumper {
// All eight byte constants take up two spots in the constant pool
tag = constant_items[i].getTag();
- if ((tag == Constants.CONSTANT_Double) ||
- (tag == Constants.CONSTANT_Long)) {
+ if ((tag == Const.CONSTANT_Double) ||
+ (tag == Const.CONSTANT_Long)) {
i++;
}
}
@@ -179,11 +179,11 @@ class ClassDumper {
/* Interfaces are implicitely abstract, the flag should be set
* according to the JVM specification.
*/
- if ((access_flags & Constants.ACC_INTERFACE) != 0) {
- access_flags |= Constants.ACC_ABSTRACT;
+ if ((access_flags & Const.ACC_INTERFACE) != 0) {
+ access_flags |= Const.ACC_ABSTRACT;
}
- if (((access_flags & Constants.ACC_ABSTRACT) != 0)
- && ((access_flags & Constants.ACC_FINAL) != 0)) {
+ if (((access_flags & Const.ACC_ABSTRACT) != 0)
+ && ((access_flags & Const.ACC_FINAL) != 0)) {
throw new ClassFormatException("Class " + file_name +
" can't be both final and abstract");
}
@@ -197,7 +197,10 @@ class ClassDumper {
superclass_name_index = file.readUnsignedShort();
System.out.printf(" super_class: %d (", superclass_name_index);
- System.out.println(constantToString(superclass_name_index) + ")");
+ if (superclass_name_index > 0) {
+ System.out.printf("%s", constantToString(superclass_name_index));
+ }
+ System.out.println(")");
}
/**
@@ -224,7 +227,7 @@ class ClassDumper {
}
System.out.println(interfaces[i] + " (" +
constant_pool.getConstantString(interfaces[i],
- Constants.CONSTANT_Class) + ")");
+ Const.CONSTANT_Class) + ")");
}
}
@@ -283,7 +286,11 @@ class ClassDumper {
for (int i = 0; i < attributes_count; i++) {
attributes[i] = Attribute.readAttribute(file, constant_pool);
- System.out.printf(" %s%n", attributes[i]);
+ // indent all lines by two spaces
+ String[] lines = attributes[i].toString().split("\\r?\\n");
+ for (String line : lines) {
+ System.out.println(" " + line);
+ }
}
}
diff --git a/src/main/java/org/apache/bcel/Const.java b/src/main/java/org/apache/bcel/Const.java
index 722daba..79268ae 100644
--- a/src/main/java/org/apache/bcel/Const.java
+++ b/src/main/java/org/apache/bcel/Const.java
@@ -208,12 +208,14 @@ public final class Const {
public static final int MAX_BYTE = 255; // 2^8 - 1
/** One of the access flags for fields, methods, or classes.
- * @see <a href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5'>
- * Flag definitions for Fields in the Java Virtual Machine Specification (Java SE 8 Edition).</a>
- * @see <a href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6'>
- * Flag definitions for Methods in the Java Virtual Machine Specification (Java SE 8 Edition).</a>
- * @see <a href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1'>
- * Flag definitions for Classes in the Java Virtual Machine Specification (Java SE 8 Edition).</a>
+ * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1'>
+ * Flag definitions for Classes in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
+ * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5'>
+ * Flag definitions for Fields in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
+ * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6'>
+ * Flag definitions for Methods in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
+ * @see <a href='http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1'>
+ * Flag definitions for Inner Classes in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
*/
public static final short ACC_PUBLIC = 0x0001;
@@ -237,89 +239,110 @@ public final class Const {
*/
public static final short ACC_FINAL = 0x0010;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for the Module attribute.
+ * @see #ACC_PUBLIC
+ */
+ public static final short ACC_OPEN = 0x0020;
+
+ /** One of the access flags for classes.
+ * @see #ACC_PUBLIC
+ */
+ public static final short ACC_SUPER = 0x0020;
+
+ /** One of the access flags for methods.
* @see #ACC_PUBLIC
*/
public static final short ACC_SYNCHRONIZED = 0x0020;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for the Module attribute.
* @see #ACC_PUBLIC
*/
- public static final short ACC_VOLATILE = 0x0040;
+ public static final short ACC_TRANSITIVE = 0x0020;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for methods.
* @see #ACC_PUBLIC
*/
public static final short ACC_BRIDGE = 0x0040;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for the Module attribute.
+ * @see #ACC_PUBLIC
+ */
+ public static final short ACC_STATIC_PHASE = 0x0040;
+
+ /** One of the access flags for fields.
+ * @see #ACC_PUBLIC
+ */
+ public static final short ACC_VOLATILE = 0x0040;
+
+ /** One of the access flags for fields.
* @see #ACC_PUBLIC
*/
public static final short ACC_TRANSIENT = 0x0080;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for methods.
* @see #ACC_PUBLIC
*/
public static final short ACC_VARARGS = 0x0080;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for methods.
* @see #ACC_PUBLIC
*/
public static final short ACC_NATIVE = 0x0100;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for classes.
* @see #ACC_PUBLIC
*/
public static final short ACC_INTERFACE = 0x0200;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for methods or classes.
* @see #ACC_PUBLIC
*/
public static final short ACC_ABSTRACT = 0x0400;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for methods.
* @see #ACC_PUBLIC
*/
public static final short ACC_STRICT = 0x0800;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for fields, methods, classes, MethodParameter attribute, or Module attribute.
* @see #ACC_PUBLIC
*/
public static final short ACC_SYNTHETIC = 0x1000;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for classes.
* @see #ACC_PUBLIC
*/
public static final short ACC_ANNOTATION = 0x2000;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for fields or classes.
* @see #ACC_PUBLIC
*/
public static final short ACC_ENUM = 0x4000;
- /** One of the access flags for fields, methods, or classes.
- * @see #ACC_PUBLIC
- */
- public static final short ACC_MANDATED = (short) 0x8000;
-
// Applies to classes compiled by new compilers only
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for MethodParameter or Module attributes.
* @see #ACC_PUBLIC
*/
- public static final short ACC_SUPER = 0x0020;
+ public static final short ACC_MANDATED = (short) 0x8000;
- /** One of the access flags for fields, methods, or classes.
+ /** One of the access flags for classes.
* @see #ACC_PUBLIC
*/
- public static final short MAX_ACC_FLAG = ACC_ENUM;
+ public static final short ACC_MODULE = (short) 0x8000;
+ public static final int MAX_ACC_FLAG = 0x8000; // ACC_MODULE is negative as a short
+ // Note that do to overloading:
+ // 'synchronized' is for methods, might be 'open' (if Module), 'super' (if class), or 'transitive' (if Module).
+ // 'volatile' is for fields, might be 'bridge' (if method) or 'static_phase' (if Module)
+ // 'transient' is for fields, might be 'varargs' (if method)
+ // 'module' is for classes, might be 'mandated' (if Module or MethodParameters)
/**
* The names of the access flags.
*/
private static final String[] ACCESS_NAMES = {
"public", "private", "protected", "static", "final", "synchronized",
"volatile", "transient", "native", "interface", "abstract", "strictfp",
- "synthetic", "annotation", "enum"
+ "synthetic", "annotation", "enum", "module"
};
/** @since 6.0 */
@@ -2288,8 +2311,13 @@ public final class Const {
public static final byte ATTR_STACK_MAP_TABLE = 19;
public static final byte ATTR_BOOTSTRAP_METHODS = 20;
public static final byte ATTR_METHOD_PARAMETERS = 21;
+ public static final byte ATTR_MODULE = 22;
+ public static final byte ATTR_MODULE_PACKAGES = 23;
+ public static final byte ATTR_MODULE_MAIN_CLASS = 24;
+ public static final byte ATTR_NEST_HOST = 25;
+ public static final byte ATTR_NEST_MEMBERS = 26;
- public static final short KNOWN_ATTRIBUTES = 22; // count of attributes
+ public static final short KNOWN_ATTRIBUTES = 27; // count of attributes
private static final String[] ATTRIBUTE_NAMES = {
"SourceFile", "ConstantValue", "Code", "Exceptions",
@@ -2299,7 +2327,8 @@ public final class Const {
"RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations",
"RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations",
"AnnotationDefault", "LocalVariableTypeTable", "EnclosingMethod", "StackMapTable",
- "BootstrapMethods", "MethodParameters"
+ "BootstrapMethods", "MethodParameters", "Module", "ModulePackages",
+ "ModuleMainClass", "NestHost", "NestMembers"
};
/**
diff --git a/src/main/java/org/apache/bcel/classfile/Attribute.java b/src/main/java/org/apache/bcel/classfile/Attribute.java
index cc4d93b..e833c96 100644
--- a/src/main/java/org/apache/bcel/classfile/Attribute.java
+++ b/src/main/java/org/apache/bcel/classfile/Attribute.java
@@ -182,6 +182,16 @@ public abstract class Attribute implements Cloneable, Node {
return new BootstrapMethods(name_index, length, file, constant_pool);
case Const.ATTR_METHOD_PARAMETERS:
return new MethodParameters(name_index, length, file, constant_pool);
+ case Const.ATTR_MODULE:
+ return new Module(name_index, length, file, constant_pool);
+ case Const.ATTR_MODULE_PACKAGES:
+ return new ModulePackages(name_index, length, file, constant_pool);
+ case Const.ATTR_MODULE_MAIN_CLASS:
+ return new ModuleMainClass(name_index, length, file, constant_pool);
+ case Const.ATTR_NEST_HOST:
+ return new NestHost(name_index, length, file, constant_pool);
+ case Const.ATTR_NEST_MEMBERS:
+ return new NestMembers(name_index, length, file, constant_pool);
default:
// Never reached
throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag);
diff --git a/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java b/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java
index a742aea..f5e7de3 100644
--- a/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java
+++ b/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java
@@ -129,12 +129,12 @@ public class BootstrapMethod implements Cloneable {
String bootstrap_method_name;
bootstrap_method_name = constant_pool.constantToString(bootstrap_method_ref,
Const.CONSTANT_MethodHandle);
- buf.append(Utility.compactClassName(bootstrap_method_name));
+ buf.append(Utility.compactClassName(bootstrap_method_name, false));
final int num_bootstrap_arguments = bootstrap_arguments.length;
if (num_bootstrap_arguments > 0) {
- buf.append("\n Method Arguments:");
+ buf.append("\nMethod Arguments:");
for (int i = 0; i < num_bootstrap_arguments; i++) {
- buf.append("\n ").append(i).append(": ");
+ buf.append("\n ").append(i).append(": ");
buf.append(constant_pool.constantToString(constant_pool.getConstant(bootstrap_arguments[i])));
}
}
diff --git a/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java b/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java
index acc17fb..9418e2d 100644
--- a/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java
+++ b/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java
@@ -134,10 +134,17 @@ public class BootstrapMethods extends Attribute {
final StringBuilder buf = new StringBuilder();
buf.append("BootstrapMethods(");
buf.append(bootstrap_methods.length);
- buf.append("):\n");
+ buf.append("):");
for (int i = 0; i < bootstrap_methods.length; i++) {
+ buf.append("\n");
+ final int start = buf.length();
buf.append(" ").append(i).append(": ");
- buf.append(bootstrap_methods[i].toString(super.getConstantPool())).append("\n");
+ final int indent_count = buf.length() - start;
+ final String[] lines = (bootstrap_methods[i].toString(super.getConstantPool())).split("\\r?\\n");
+ buf.append(lines[0]);
+ for (int j = 1; j < lines.length; j++) {
+ buf.append("\n").append(" ".substring(0,indent_count)).append(lines[j]);
+ }
}
return buf.toString();
}
diff --git a/src/main/java/org/apache/bcel/classfile/ConstantPackage.java b/src/main/java/org/apache/bcel/classfile/ConstantPackage.java
index ed43284..ee01317 100644
--- a/src/main/java/org/apache/bcel/classfile/ConstantPackage.java
+++ b/src/main/java/org/apache/bcel/classfile/ConstantPackage.java
@@ -67,7 +67,7 @@ public final class ConstantPackage extends Constant implements ConstantObject {
/**
- * Called by objects that are traversing the nodes of the tree implicitely
+ * Called by objects that are traversing the nodes of the tree implicitly
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
diff --git a/src/main/java/org/apache/bcel/classfile/ConstantPool.java b/src/main/java/org/apache/bcel/classfile/ConstantPool.java
index f7fdecf..f2c946a 100644
--- a/src/main/java/org/apache/bcel/classfile/ConstantPool.java
+++ b/src/main/java/org/apache/bcel/classfile/ConstantPool.java
@@ -154,6 +154,16 @@ public class ConstantPool implements Cloneable, Node {
+ ":" + constantToString(cid.getNameAndTypeIndex(),
Const.CONSTANT_NameAndType);
break;
+ case Const.CONSTANT_Module:
+ i = ((ConstantModule) c).getNameIndex();
+ c = getConstant(i, Const.CONSTANT_Utf8);
+ str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false);
+ break;
+ case Const.CONSTANT_Package:
+ i = ((ConstantPackage) c).getNameIndex();
+ c = getConstant(i, Const.CONSTANT_Utf8);
+ str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false);
+ break;
default: // Never reached
throw new RuntimeException("Unknown constant type " + tag);
}
@@ -279,7 +289,7 @@ public class ConstantPool implements Cloneable, Node {
Constant c;
int i;
c = getConstant(index, tag);
- /* This switch() is not that elegant, since the two classes have the
+ /* This switch() is not that elegant, since the four classes have the
* same contents, they just differ in the name of the index
* field variable.
* But we want to stick to the JVM naming conventions closely though
@@ -293,6 +303,12 @@ public class ConstantPool implements Cloneable, Node {
case Const.CONSTANT_String:
i = ((ConstantString) c).getStringIndex();
break;
+ case Const.CONSTANT_Module:
+ i = ((ConstantModule) c).getNameIndex();
+ break;
+ case Const.CONSTANT_Package:
+ i = ((ConstantPackage) c).getNameIndex();
+ break;
default:
throw new RuntimeException("getConstantString called with illegal tag " + tag);
}
diff --git a/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java b/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java
index fa89526..b2d9883 100644
--- a/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java
+++ b/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java
@@ -500,6 +500,21 @@ public class DescendingVisitor implements Visitor
{
stack.push(obj);
obj.accept(visitor);
+ final MethodParameter[] table = obj.getParameters();
+ for (final MethodParameter element : table) {
+ element.accept(this);
+ }
+ stack.pop();
+ }
+
+ /**
+ * @since 6.4
+ */
+ @Override
+ public void visitMethodParameter(final MethodParameter obj)
+ {
+ stack.push(obj);
+ obj.accept(visitor);
stack.pop();
}
@@ -550,4 +565,94 @@ public class DescendingVisitor implements Visitor
obj.accept(visitor);
stack.pop();
}
+
+ /** @since 6.4 */
+ @Override
+ public void visitModule(final Module obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ final ModuleRequires[] rtable = obj.getRequiresTable();
+ for (final ModuleRequires element : rtable) {
+ element.accept(this);
+ }
+ final ModuleExports[] etable = obj.getExportsTable();
+ for (final ModuleExports element : etable) {
+ element.accept(this);
+ }
+ stack.pop();
+ final ModuleOpens[] otable = obj.getOpensTable();
+ for (final ModuleOpens element : otable) {
+ element.accept(this);
+ }
+ stack.pop();
+ final ModuleProvides[] ptable = obj.getProvidesTable();
+ for (final ModuleProvides element : ptable) {
+ element.accept(this);
+ }
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleRequires(final ModuleRequires obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleExports(final ModuleExports obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleOpens(final ModuleOpens obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleProvides(final ModuleProvides obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModulePackages(final ModulePackages obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleMainClass(final ModuleMainClass obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitNestHost(final NestHost obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitNestMembers(final NestMembers obj) {
+ stack.push(obj);
+ obj.accept(visitor);
+ stack.pop();
+ }
}
diff --git a/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java b/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java
index 795e0ce..e60606f 100644
--- a/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java
+++ b/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java
@@ -275,6 +275,14 @@ public class EmptyVisitor implements Visitor
}
/**
+ * @since 6.4
+ */
+ @Override
+ public void visitMethodParameter(final MethodParameter obj)
+ {
+ }
+
+ /**
* @since 6.0
*/
@Override
@@ -310,11 +318,55 @@ public class EmptyVisitor implements Visitor
public void visitConstantModule(final ConstantModule constantModule) {
}
-
/**
* @since 6.3
*/
@Override
public void visitConstantDynamic(final ConstantDynamic obj) {
}
+
+ /** @since 6.4 */
+ @Override
+ public void visitModule(final Module obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleRequires(final ModuleRequires obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleExports(final ModuleExports obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleOpens(final ModuleOpens obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleProvides(final ModuleProvides obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModulePackages(final ModulePackages obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleMainClass(final ModuleMainClass obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitNestHost(final NestHost obj) {
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitNestMembers(final NestMembers obj) {
+ }
}
diff --git a/src/main/java/org/apache/bcel/classfile/InnerClass.java b/src/main/java/org/apache/bcel/classfile/InnerClass.java
index 287e481..94d2c88 100644
--- a/src/main/java/org/apache/bcel/classfile/InnerClass.java
+++ b/src/main/java/org/apache/bcel/classfile/InnerClass.java
@@ -182,11 +182,11 @@ public final class InnerClass implements Cloneable, Node {
String inner_name;
String inner_class_name = constant_pool.getConstantString(inner_class_index,
Const.CONSTANT_Class);
- inner_class_name = Utility.compactClassName(inner_class_name);
+ inner_class_name = Utility.compactClassName(inner_class_name, false);
if (outer_class_index != 0) {
outer_class_name = constant_pool.getConstantString(outer_class_index,
Const.CONSTANT_Class);
- outer_class_name = " of class " + Utility.compactClassName(outer_class_name);
+ outer_class_name = " of class " + Utility.compactClassName(outer_class_name, false);
} else {
outer_class_name = "";
}
diff --git a/src/main/java/org/apache/bcel/classfile/InnerClasses.java b/src/main/java/org/apache/bcel/classfile/InnerClasses.java
index 30f4f11..565294f 100644
--- a/src/main/java/org/apache/bcel/classfile/InnerClasses.java
+++ b/src/main/java/org/apache/bcel/classfile/InnerClasses.java
@@ -135,7 +135,7 @@ public final class InnerClasses extends Attribute {
for (final InnerClass inner_class : inner_classes) {
buf.append(inner_class.toString(super.getConstantPool())).append("\n");
}
- return buf.toString();
+ return buf.substring(0, buf.length()-1); // remove the last newline
}
diff --git a/src/main/java/org/apache/bcel/classfile/JavaClass.java b/src/main/java/org/apache/bcel/classfile/JavaClass.java
index bcafc05..b2ed8d7 100644
--- a/src/main/java/org/apache/bcel/classfile/JavaClass.java
+++ b/src/main/java/org/apache/bcel/classfile/JavaClass.java
@@ -721,7 +721,7 @@ public class JavaClass extends AccessFlags implements Cloneable, Node, Comparabl
boolean innerClassAttributeRefersToMe = false;
String inner_class_name = constant_pool.getConstantString(innerClasse.getInnerClassIndex(),
Const.CONSTANT_Class);
- inner_class_name = Utility.compactClassName(inner_class_name);
+ inner_class_name = Utility.compactClassName(inner_class_name, false);
if (inner_class_name.equals(getClassName())) {
innerClassAttributeRefersToMe = true;
}
diff --git a/src/main/java/org/apache/bcel/classfile/MethodParameter.java b/src/main/java/org/apache/bcel/classfile/MethodParameter.java
index e881af5..a0345b9 100644
--- a/src/main/java/org/apache/bcel/classfile/MethodParameter.java
+++ b/src/main/java/org/apache/bcel/classfile/MethodParameter.java
@@ -91,6 +91,10 @@ public class MethodParameter implements Cloneable {
return (access_flags & Const.ACC_MANDATED) != 0;
}
+ public void accept(final Visitor v) {
+ v.visitMethodParameter(this);
+ }
+
/**
* Dump object to file stream on binary format.
*
diff --git a/src/main/java/org/apache/bcel/classfile/Module.java b/src/main/java/org/apache/bcel/classfile/Module.java
new file mode 100644
index 0000000..28673a1
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/Module.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents the list of modules required, exported, opened or provided by a module.
+ * There may be at most one Module attribute in a ClassFile structure.
+ *
+ * @see Attribute
+ * @since 6.4
+ */
+public final class Module extends Attribute {
+
+ private int module_name_index;
+ private int module_flags;
+ private int module_version_index;
+
+ private ModuleRequires[] requires_table;
+ private ModuleExports[] exports_table;
+ private ModuleOpens[] opens_table;
+ private int uses_count;
+ private int uses_index[];
+ private ModuleProvides[] provides_table;
+
+ /**
+ * Construct object from input stream.
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param input Input stream
+ * @param constant_pool Array of constants
+ * @throws IOException
+ */
+ Module(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException {
+ super(Const.ATTR_MODULE, name_index, length, constant_pool);
+
+ module_name_index = input.readUnsignedShort();
+ module_flags = input.readUnsignedShort();
+ module_version_index = input.readUnsignedShort();
+
+ final int requires_count = input.readUnsignedShort();
+ requires_table = new ModuleRequires[requires_count];
+ for (int i = 0; i < requires_count; i++) {
+ requires_table[i] = new ModuleRequires(input);
+ }
+
+ final int exports_count = input.readUnsignedShort();
+ exports_table = new ModuleExports[exports_count];
+ for (int i = 0; i < exports_count; i++) {
+ exports_table[i] = new ModuleExports(input);
+ }
+
+ final int opens_count = input.readUnsignedShort();
+ opens_table = new ModuleOpens[opens_count];
+ for (int i = 0; i < opens_count; i++) {
+ opens_table[i] = new ModuleOpens(input);
+ }
+
+ uses_count = input.readUnsignedShort();
+ uses_index = new int[uses_count];
+ for (int i = 0; i < uses_count; i++) {
+ uses_index[i] = input.readUnsignedShort();
+ }
+
+ final int provides_count = input.readUnsignedShort();
+ provides_table = new ModuleProvides[provides_count];
+ for (int i = 0; i < provides_count; i++) {
+ provides_table[i] = new ModuleProvides(input);
+ }
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitModule(this);
+ }
+
+ // TODO add more getters and setters?
+
+ /**
+ * @return table of required modules
+ * @see ModuleRequires
+ */
+ public final ModuleRequires[] getRequiresTable() {
+ return requires_table;
+ }
+
+
+ /**
+ * @return table of exported interfaces
+ * @see ModuleExports
+ */
+ public final ModuleExports[] getExportsTable() {
+ return exports_table;
+ }
+
+
+ /**
+ * @return table of provided interfaces
+ * @see ModuleOpens
+ */
+ public final ModuleOpens[] getOpensTable() {
+ return opens_table;
+ }
+
+
+ /**
+ * @return table of provided interfaces
+ * @see ModuleProvides
+ */
+ public final ModuleProvides[] getProvidesTable() {
+ return provides_table;
+ }
+
+
+ /**
+ * Dump Module attribute to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException
+ */
+ @Override
+ public final void dump( final DataOutputStream file ) throws IOException {
+ super.dump(file);
+
+ file.writeShort(module_name_index);
+ file.writeShort(module_flags);
+ file.writeShort(module_version_index);
+
+ file.writeShort(requires_table.length);
+ for (final ModuleRequires entry : requires_table) {
+ entry.dump(file);
+ }
+
+ file.writeShort(exports_table.length);
+ for (final ModuleExports entry : exports_table) {
+ entry.dump(file);
+ }
+
+ file.writeShort(opens_table.length);
+ for (final ModuleOpens entry : opens_table) {
+ entry.dump(file);
+ }
+
+ file.writeShort(uses_index.length);
+ for (final int entry : uses_index) {
+ file.writeShort(entry);
+ }
+
+ file.writeShort(provides_table.length);
+ for (final ModuleProvides entry : provides_table) {
+ entry.dump(file);
+ }
+ }
+
+
+ /**
+ * @return String representation, i.e., a list of packages.
+ */
+ @Override
+ public final String toString() {
+ final ConstantPool cp = super.getConstantPool();
+ final StringBuilder buf = new StringBuilder();
+ buf.append("Module:\n");
+ buf.append(" name: ") .append(cp.getConstantString(module_name_index, Const.CONSTANT_Module).replace('/', '.')).append("\n");
+ buf.append(" flags: ") .append(String.format("%04x", module_flags)).append("\n");
+ final String version = (module_version_index == 0 ? "0" : cp.getConstantString(module_version_index, Const.CONSTANT_Utf8));
+ buf.append(" version: ") .append(version).append("\n");
+
+ buf.append(" requires(").append(requires_table.length).append("):\n");
+ for (final ModuleRequires module : requires_table) {
+ buf.append(" ").append(module.toString(cp)).append("\n");
+ }
+
+ buf.append(" exports(").append(exports_table.length).append("):\n");
+ for (final ModuleExports module : exports_table) {
+ buf.append(" ").append(module.toString(cp)).append("\n");
+ }
+
+ buf.append(" opens(").append(opens_table.length).append("):\n");
+ for (final ModuleOpens module : opens_table) {
+ buf.append(" ").append(module.toString(cp)).append("\n");
+ }
+
+ buf.append(" uses(").append(uses_index.length).append("):\n");
+ for (final int index : uses_index) {
+ final String class_name = cp.getConstantString(index, Const.CONSTANT_Class);
+ buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n");
+ }
+
+ buf.append(" provides(").append(provides_table.length).append("):\n");
+ for (final ModuleProvides module : provides_table) {
+ buf.append(" ").append(module.toString(cp)).append("\n");
+ }
+
+ return buf.substring(0, buf.length()-1); // remove the last newline
+ }
+
+
+ /**
+ * @return deep copy of this attribute
+ */
+ @Override
+ public Attribute copy( final ConstantPool _constant_pool ) {
+ final Module c = (Module) clone();
+
+ c.requires_table = new ModuleRequires[requires_table.length];
+ for (int i = 0; i < requires_table.length; i++) {
+ c.requires_table[i] = requires_table[i].copy();
+ }
+
+ c.exports_table = new ModuleExports[exports_table.length];
+ for (int i = 0; i < exports_table.length; i++) {
+ c.exports_table[i] = exports_table[i].copy();
+ }
+
+ c.opens_table = new ModuleOpens[opens_table.length];
+ for (int i = 0; i < opens_table.length; i++) {
+ c.opens_table[i] = opens_table[i].copy();
+ }
+
+ c.provides_table = new ModuleProvides[provides_table.length];
+ for (int i = 0; i < provides_table.length; i++) {
+ c.provides_table[i] = provides_table[i].copy();
+ }
+
+ c.setConstantPool(_constant_pool);
+ return c;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/ModuleExports.java b/src/main/java/org/apache/bcel/classfile/ModuleExports.java
new file mode 100644
index 0000000..2b7a984
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/ModuleExports.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class represents an entry in the exports table of the Module attribute.
+ * Each entry describes a package which may open the parent module.
+ *
+ * @see Module
+ * @since 6.4
+ */
+public final class ModuleExports implements Cloneable, Node {
+
+ private int exports_index; // points to CONSTANT_Package_info
+ private int exports_flags;
+ private int exports_to_count;
+ private int exports_to_index[]; // points to CONSTANT_Module_info
+
+
+ /**
+ * Construct object from file stream.
+ *
+ * @param file Input stream
+ * @throws IOException if an I/O Exception occurs in readUnsignedShort
+ */
+ ModuleExports(final DataInput file) throws IOException {
+ exports_index = file.readUnsignedShort();
+ exports_flags = file.readUnsignedShort();
+ exports_to_count = file.readUnsignedShort();
+ exports_to_index = new int[exports_to_count];
+ for (int i = 0; i < exports_to_count; i++) {
+ exports_to_index[i] = file.readUnsignedShort();
+ }
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitModuleExports(this);
+ }
+
+ // TODO add more getters and setters?
+
+ /**
+ * Dump table entry to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException if an I/O Exception occurs in writeShort
+ */
+ public final void dump( final DataOutputStream file ) throws IOException {
+ file.writeShort(exports_index);
+ file.writeShort(exports_flags);
+ file.writeShort(exports_to_count);
+ for (final int entry : exports_to_index) {
+ file.writeShort(entry);
+ }
+ }
+
+
+ /**
+ * @return String representation
+ */
+ @Override
+ public final String toString() {
+ return "exports(" + exports_index + ", " + exports_flags + ", " + exports_to_count + ", ...)";
+ }
+
+
+ /**
+ * @return Resolved string representation
+ */
+ public final String toString( final ConstantPool constant_pool ) {
+ final StringBuilder buf = new StringBuilder();
+ final String package_name = constant_pool.constantToString(exports_index, Const.CONSTANT_Package);
+ buf.append(Utility.compactClassName(package_name, false));
+ buf.append(", ").append(String.format("%04x", exports_flags));
+ buf.append(", to(").append(exports_to_count).append("):\n");
+ for (final int index : exports_to_index) {
+ final String module_name = constant_pool.getConstantString(index, Const.CONSTANT_Module);
+ buf.append(" ").append(Utility.compactClassName(module_name, false)).append("\n");
+ }
+ return buf.substring(0, buf.length()-1); // remove the last newline
+ }
+
+
+ /**
+ * @return deep copy of this object
+ */
+ public ModuleExports copy() {
+ try {
+ return (ModuleExports) clone();
+ } catch (final CloneNotSupportedException e) {
+ // TODO should this throw?
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/ModuleMainClass.java b/src/main/java/org/apache/bcel/classfile/ModuleMainClass.java
new file mode 100644
index 0000000..f270f05
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/ModuleMainClass.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class is derived from <em>Attribute</em> and indicates the main class of a module.
+ * There may be at most one ModuleMainClass attribute in a ClassFile structure.
+ *
+ * @see Attribute
+ */
+public final class ModuleMainClass extends Attribute {
+
+ private int main_class_index;
+
+
+ /**
+ * Initialize from another object. Note that both objects use the same
+ * references (shallow copy). Use copy() for a physical copy.
+ */
+ public ModuleMainClass(final ModuleMainClass c) {
+ this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool());
+ }
+
+
+ /**
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param int Host class index
+ * @param constant_pool Array of constants
+ */
+ public ModuleMainClass(final int name_index, final int length, final int main_class_index,
+ final ConstantPool constant_pool) {
+ super(Const.ATTR_NEST_MEMBERS, name_index, length, constant_pool);
+ this.main_class_index = main_class_index;
+ }
+
+
+ /**
+ * Construct object from input stream.
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param input Input stream
+ * @param constant_pool Array of constants
+ * @throws IOException
+ */
+ ModuleMainClass(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException {
+ this(name_index, length, 0, constant_pool);
+ main_class_index = input.readUnsignedShort();
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitModuleMainClass(this);
+ }
+
+
+ /**
+ * Dump ModuleMainClass attribute to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException
+ */
+ @Override
+ public final void dump( final DataOutputStream file ) throws IOException {
+ super.dump(file);
+ file.writeShort(main_class_index);
+ }
+
+
+ /**
+ * @return index into constant pool of host class name.
+ */
+ public final int getHostClassIndex() {
+ return main_class_index;
+ }
+
+
+ /**
+ * @param int the host class index
+ */
+ public final void setHostClassIndex( final int main_class_index ) {
+ this.main_class_index = main_class_index;
+ }
+
+
+ /**
+ * @return String representation
+ */
+ @Override
+ public final String toString() {
+ final StringBuilder buf = new StringBuilder();
+ buf.append("ModuleMainClass: ");
+ final String class_name = super.getConstantPool().getConstantString(main_class_index, Const.CONSTANT_Class);
+ buf.append(Utility.compactClassName(class_name, false));
+ return buf.toString();
+ }
+
+
+ /**
+ * @return deep copy of this attribute
+ */
+ @Override
+ public Attribute copy( final ConstantPool _constant_pool ) {
+ final ModuleMainClass c = (ModuleMainClass) clone();
+ c.setConstantPool(_constant_pool);
+ return c;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/ModuleOpens.java b/src/main/java/org/apache/bcel/classfile/ModuleOpens.java
new file mode 100644
index 0000000..a197676
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/ModuleOpens.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class represents an entry in the opens table of the Module attribute.
+ * Each entry describes a package which the parent module opens.
+ *
+ * @see Module
+ * @since 6.4
+ */
+public final class ModuleOpens implements Cloneable, Node {
+
+ private int opens_index; // points to CONSTANT_Package_info
+ private int opens_flags;
+ private int opens_to_count;
+ private int opens_to_index[]; // points to CONSTANT_Module_info
+
+
+ /**
+ * Construct object from file stream.
+ *
+ * @param file Input stream
+ * @throws IOException if an I/O Exception occurs in readUnsignedShort
+ */
+ ModuleOpens(final DataInput file) throws IOException {
+ opens_index = file.readUnsignedShort();
+ opens_flags = file.readUnsignedShort();
+ opens_to_count = file.readUnsignedShort();
+ opens_to_index = new int[opens_to_count];
+ for (int i = 0; i < opens_to_count; i++) {
+ opens_to_index[i] = file.readUnsignedShort();
+ }
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitModuleOpens(this);
+ }
+
+ // TODO add more getters and setters?
+
+ /**
+ * Dump table entry to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException if an I/O Exception occurs in writeShort
+ */
+ public final void dump( final DataOutputStream file ) throws IOException {
+ file.writeShort(opens_index);
+ file.writeShort(opens_flags);
+ file.writeShort(opens_to_count);
+ for (final int entry : opens_to_index) {
+ file.writeShort(entry);
+ }
+ }
+
+
+ /**
+ * @return String representation
+ */
+ @Override
+ public final String toString() {
+ return "opens(" + opens_index + ", " + opens_flags + ", " + opens_to_count + ", ...)";
+ }
+
+
+ /**
+ * @return Resolved string representation
+ */
+ public final String toString( final ConstantPool constant_pool ) {
+ final StringBuilder buf = new StringBuilder();
+ final String package_name = constant_pool.constantToString(opens_index, Const.CONSTANT_Package);
+ buf.append(Utility.compactClassName(package_name, false));
+ buf.append(", ").append(String.format("%04x", opens_flags));
+ buf.append(", to(").append(opens_to_count).append("):\n");
+ for (final int index : opens_to_index) {
+ final String module_name = constant_pool.getConstantString(index, Const.CONSTANT_Module);
+ buf.append(" ").append(Utility.compactClassName(module_name, false)).append("\n");
+ }
+ return buf.substring(0, buf.length()-1); // remove the last newline
+ }
+
+
+ /**
+ * @return deep copy of this object
+ */
+ public ModuleOpens copy() {
+ try {
+ return (ModuleOpens) clone();
+ } catch (final CloneNotSupportedException e) {
+ // TODO should this throw?
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/ModulePackages.java b/src/main/java/org/apache/bcel/classfile/ModulePackages.java
new file mode 100644
index 0000000..95df9dc
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/ModulePackages.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents the list of packages that are exported or opened by the Module attribute.
+ * There may be at most one ModulePackages attribute in a ClassFile structure.
+ *
+ * @see Attribute
+ */
+public final class ModulePackages extends Attribute {
+
+ private int[] package_index_table;
+
+
+ /**
+ * Initialize from another object. Note that both objects use the same
+ * references (shallow copy). Use copy() for a physical copy.
+ */
+ public ModulePackages(final ModulePackages c) {
+ this(c.getNameIndex(), c.getLength(), c.getPackageIndexTable(), c.getConstantPool());
+ }
+
+
+ /**
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param package_index_table Table of indices in constant pool
+ * @param constant_pool Array of constants
+ */
+ public ModulePackages(final int name_index, final int length, final int[] package_index_table,
+ final ConstantPool constant_pool) {
+ super(Const.ATTR_MODULE_PACKAGES, name_index, length, constant_pool);
+ this.package_index_table = package_index_table != null ? package_index_table : new int[0];
+ }
+
+
+ /**
+ * Construct object from input stream.
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param input Input stream
+ * @param constant_pool Array of constants
+ * @throws IOException
+ */
+ ModulePackages(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException {
+ this(name_index, length, (int[]) null, constant_pool);
+ final int number_of_packages = input.readUnsignedShort();
+ package_index_table = new int[number_of_packages];
+ for (int i = 0; i < number_of_packages; i++) {
+ package_index_table[i] = input.readUnsignedShort();
+ }
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitModulePackages(this);
+ }
+
+
+ /**
+ * Dump ModulePackages attribute to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException
+ */
+ @Override
+ public final void dump( final DataOutputStream file ) throws IOException {
+ super.dump(file);
+ file.writeShort(package_index_table.length);
+ for (final int index : package_index_table) {
+ file.writeShort(index);
+ }
+ }
+
+
+ /**
+ * @return array of indices into constant pool of package names.
+ */
+ public final int[] getPackageIndexTable() {
+ return package_index_table;
+ }
+
+
+ /**
+ * @return Length of package table.
+ */
+ public final int getNumberOfPackages() {
+ return package_index_table == null ? 0 : package_index_table.length;
+ }
+
+
+ /**
+ * @return string array of package names
+ */
+ public final String[] getPackageNames() {
+ final String[] names = new String[package_index_table.length];
+ for (int i = 0; i < package_index_table.length; i++) {
+ names[i] = super.getConstantPool().getConstantString(package_index_table[i],
+ Const.CONSTANT_Package).replace('/', '.');
+ }
+ return names;
+ }
+
+
+ /**
+ * @param package_index_table the list of package indexes
+ * Also redefines number_of_packages according to table length.
+ */
+ public final void setPackageIndexTable( final int[] package_index_table ) {
+ this.package_index_table = package_index_table != null ? package_index_table : new int[0];
+ }
+
+
+ /**
+ * @return String representation, i.e., a list of packages.
+ */
+ @Override
+ public final String toString() {
+ final StringBuilder buf = new StringBuilder();
+ buf.append("ModulePackages(");
+ buf.append(package_index_table.length);
+ buf.append("):\n");
+ for (final int index : package_index_table) {
+ final String package_name = super.getConstantPool().getConstantString(index, Const.CONSTANT_Package);
+ buf.append(" ").append(Utility.compactClassName(package_name, false)).append("\n");
+ }
+ return buf.substring(0, buf.length()-1); // remove the last newline
+ }
+
+
+ /**
+ * @return deep copy of this attribute
+ */
+ @Override
+ public Attribute copy( final ConstantPool _constant_pool ) {
+ final ModulePackages c = (ModulePackages) clone();
+ if (package_index_table != null) {
+ c.package_index_table = new int[package_index_table.length];
+ System.arraycopy(package_index_table, 0, c.package_index_table, 0,
+ package_index_table.length);
+ }
+ c.setConstantPool(_constant_pool);
+ return c;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/ModuleProvides.java b/src/main/java/org/apache/bcel/classfile/ModuleProvides.java
new file mode 100644
index 0000000..4edebf5
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/ModuleProvides.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class represents an entry in the provides table of the Module attribute.
+ * Each entry describes a service implementation that the parent module provides.
+ *
+ * @see Module
+ * @since 6.4
+ */
+public final class ModuleProvides implements Cloneable, Node {
+
+ private int provides_index; // points to CONSTANT_Class_info
+ private int provides_with_count;
+ private int provides_with_index[]; // points to CONSTANT_Class_info
+
+
+ /**
+ * Construct object from file stream.
+ *
+ * @param file Input stream
+ * @throws IOException if an I/O Exception occurs in readUnsignedShort
+ */
+ ModuleProvides(final DataInput file) throws IOException {
+ provides_index = file.readUnsignedShort();
+ provides_with_count = file.readUnsignedShort();
+ provides_with_index = new int[provides_with_count];
+ for (int i = 0; i < provides_with_count; i++) {
+ provides_with_index[i] = file.readUnsignedShort();
+ }
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitModuleProvides(this);
+ }
+
+ // TODO add more getters and setters?
+
+ /**
+ * Dump table entry to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException if an I/O Exception occurs in writeShort
+ */
+ public final void dump( final DataOutputStream file ) throws IOException {
+ file.writeShort(provides_index);
+ file.writeShort(provides_with_count);
+ for (final int entry : provides_with_index) {
+ file.writeShort(entry);
+ }
+ }
+
+
+ /**
+ * @return String representation
+ */
+ @Override
+ public final String toString() {
+ return "provides(" + provides_index + ", " + provides_with_count + ", ...)";
+ }
+
+
+ /**
+ * @return Resolved string representation
+ */
+ public final String toString( final ConstantPool constant_pool ) {
+ final StringBuilder buf = new StringBuilder();
+ final String interface_name = constant_pool.constantToString(provides_index, Const.CONSTANT_Class);
+ buf.append(Utility.compactClassName(interface_name, false));
+ buf.append(", with(").append(provides_with_count).append("):\n");
+ for (final int index : provides_with_index) {
+ final String class_name = constant_pool.getConstantString(index, Const.CONSTANT_Class);
+ buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n");
+ }
+ return buf.substring(0, buf.length()-1); // remove the last newline
+ }
+
+
+ /**
+ * @return deep copy of this object
+ */
+ public ModuleProvides copy() {
+ try {
+ return (ModuleProvides) clone();
+ } catch (final CloneNotSupportedException e) {
+ // TODO should this throw?
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/ModuleRequires.java b/src/main/java/org/apache/bcel/classfile/ModuleRequires.java
new file mode 100644
index 0000000..674ce1e
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/ModuleRequires.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class represents an entry in the requires table of the Module attribute.
+ * Each entry describes a module on which the parent module depends.
+ *
+ * @see Module
+ * @since 6.4
+ */
+public final class ModuleRequires implements Cloneable, Node {
+
+ private int requires_index; // points to CONSTANT_Module_info
+ private int requires_flags;
+ private int requires_version_index; // either 0 or points to CONSTANT_Utf8_info
+
+
+ /**
+ * Construct object from file stream.
+ *
+ * @param file Input stream
+ * @throws IOException if an I/O Exception occurs in readUnsignedShort
+ */
+ ModuleRequires(final DataInput file) throws IOException {
+ requires_index = file.readUnsignedShort();
+ requires_flags = file.readUnsignedShort();
+ requires_version_index = file.readUnsignedShort();
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitModuleRequires(this);
+ }
+
+ // TODO add more getters and setters?
+
+ /**
+ * Dump table entry to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException if an I/O Exception occurs in writeShort
+ */
+ public final void dump( final DataOutputStream file ) throws IOException {
+ file.writeShort(requires_index);
+ file.writeShort(requires_flags);
+ file.writeShort(requires_version_index);
+ }
+
+
+ /**
+ * @return String representation
+ */
+ @Override
+ public final String toString() {
+ return "requires(" + requires_index + ", " + String.format("%04x", requires_flags) + ", " + requires_version_index + ")";
+ }
+
+
+ /**
+ * @return Resolved string representation
+ */
+ public final String toString( final ConstantPool constant_pool ) {
+ final StringBuilder buf = new StringBuilder();
+ final String module_name = constant_pool.constantToString(requires_index, Const.CONSTANT_Module);
+ buf.append(Utility.compactClassName(module_name, false));
+ buf.append(", ").append(String.format("%04x", requires_flags));
+ final String version = (requires_version_index == 0 ? "0" : constant_pool.getConstantString(requires_version_index, Const.CONSTANT_Utf8));
+ buf.append(", ").append(version);
+ return buf.toString();
+ }
+
+
+ /**
+ * @return deep copy of this object
+ */
+ public ModuleRequires copy() {
+ try {
+ return (ModuleRequires) clone();
+ } catch (final CloneNotSupportedException e) {
+ // TODO should this throw?
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/NestHost.java b/src/main/java/org/apache/bcel/classfile/NestHost.java
new file mode 100644
index 0000000..44843c2
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/NestHost.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class is derived from <em>Attribute</em> and records the nest host of the nest
+ * to which the current class or interface claims to belong.
+ * There may be at most one NestHost attribute in a ClassFile structure.
+ *
+ * @see Attribute
+ */
+public final class NestHost extends Attribute {
+
+ private int host_class_index;
+
+
+ /**
+ * Initialize from another object. Note that both objects use the same
+ * references (shallow copy). Use copy() for a physical copy.
+ */
+ public NestHost(final NestHost c) {
+ this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool());
+ }
+
+
+ /**
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param int Host class index
+ * @param constant_pool Array of constants
+ */
+ public NestHost(final int name_index, final int length, final int host_class_index,
+ final ConstantPool constant_pool) {
+ super(Const.ATTR_NEST_MEMBERS, name_index, length, constant_pool);
+ this.host_class_index = host_class_index;
+ }
+
+
+ /**
+ * Construct object from input stream.
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param input Input stream
+ * @param constant_pool Array of constants
+ * @throws IOException
+ */
+ NestHost(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException {
+ this(name_index, length, 0, constant_pool);
+ host_class_index = input.readUnsignedShort();
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitNestHost(this);
+ }
+
+
+ /**
+ * Dump NestHost attribute to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException
+ */
+ @Override
+ public final void dump( final DataOutputStream file ) throws IOException {
+ super.dump(file);
+ file.writeShort(host_class_index);
+ }
+
+
+ /**
+ * @return index into constant pool of host class name.
+ */
+ public final int getHostClassIndex() {
+ return host_class_index;
+ }
+
+
+ /**
+ * @param int the host class index
+ */
+ public final void setHostClassIndex( final int host_class_index ) {
+ this.host_class_index = host_class_index;
+ }
+
+
+ /**
+ * @return String representation
+ */
+ @Override
+ public final String toString() {
+ final StringBuilder buf = new StringBuilder();
+ buf.append("NestHost: ");
+ final String class_name = super.getConstantPool().getConstantString(host_class_index, Const.CONSTANT_Class);
+ buf.append(Utility.compactClassName(class_name, false));
+ return buf.toString();
+ }
+
+
+ /**
+ * @return deep copy of this attribute
+ */
+ @Override
+ public Attribute copy( final ConstantPool _constant_pool ) {
+ final NestHost c = (NestHost) clone();
+ c.setConstantPool(_constant_pool);
+ return c;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/NestMembers.java b/src/main/java/org/apache/bcel/classfile/NestMembers.java
new file mode 100644
index 0000000..da9b6b4
--- /dev/null
+++ b/src/main/java/org/apache/bcel/classfile/NestMembers.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.bcel.Const;
+
+/**
+ * This class is derived from <em>Attribute</em> and records the classes and interfaces that
+ * are authorized to claim membership in the nest hosted by the current class or interface.
+ * There may be at most one NestMembers attribute in a ClassFile structure.
+ *
+ * @see Attribute
+ */
+public final class NestMembers extends Attribute {
+
+ private int[] classes;
+
+
+ /**
+ * Initialize from another object. Note that both objects use the same
+ * references (shallow copy). Use copy() for a physical copy.
+ */
+ public NestMembers(final NestMembers c) {
+ this(c.getNameIndex(), c.getLength(), c.getClasses(), c.getConstantPool());
+ }
+
+
+ /**
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param classes Table of indices in constant pool
+ * @param constant_pool Array of constants
+ */
+ public NestMembers(final int name_index, final int length, final int[] classes,
+ final ConstantPool constant_pool) {
+ super(Const.ATTR_NEST_MEMBERS, name_index, length, constant_pool);
+ this.classes = classes != null ? classes : new int[0];
+ }
+
+
+ /**
+ * Construct object from input stream.
+ * @param name_index Index in constant pool
+ * @param length Content length in bytes
+ * @param input Input stream
+ * @param constant_pool Array of constants
+ * @throws IOException
+ */
+ NestMembers(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException {
+ this(name_index, length, (int[]) null, constant_pool);
+ final int number_of_classes = input.readUnsignedShort();
+ classes = new int[number_of_classes];
+ for (int i = 0; i < number_of_classes; i++) {
+ classes[i] = input.readUnsignedShort();
+ }
+ }
+
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ @Override
+ public void accept( final Visitor v ) {
+ v.visitNestMembers(this);
+ }
+
+
+ /**
+ * Dump NestMembers attribute to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException
+ */
+ @Override
+ public final void dump( final DataOutputStream file ) throws IOException {
+ super.dump(file);
+ file.writeShort(classes.length);
+ for (final int index : classes) {
+ file.writeShort(index);
+ }
+ }
+
+
+ /**
+ * @return array of indices into constant pool of class names.
+ */
+ public final int[] getClasses() {
+ return classes;
+ }
+
+
+ /**
+ * @return Length of classes table.
+ */
+ public final int getNumberClasses() {
+ return classes == null ? 0 : classes.length;
+ }
+
+
+ /**
+ * @return string array of class names
+ */
+ public final String[] getClassNames() {
+ final String[] names = new String[classes.length];
+ for (int i = 0; i < classes.length; i++) {
+ names[i] = super.getConstantPool().getConstantString(classes[i],
+ Const.CONSTANT_Class).replace('/', '.');
+ }
+ return names;
+ }
+
+
+ /**
+ * @param classes the list of class indexes
+ * Also redefines number_of_classes according to table length.
+ */
+ public final void setClasses( final int[] classes ) {
+ this.classes = classes != null ? classes : new int[0];
+ }
+
+
+ /**
+ * @return String representation, i.e., a list of classes.
+ */
+ @Override
+ public final String toString() {
+ final StringBuilder buf = new StringBuilder();
+ buf.append("NestMembers(");
+ buf.append(classes.length);
+ buf.append("):\n");
+ for (final int index : classes) {
+ final String class_name = super.getConstantPool().getConstantString(index, Const.CONSTANT_Class);
+ buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n");
+ }
+ return buf.substring(0, buf.length()-1); // remove the last newline
+ }
+
+
+ /**
+ * @return deep copy of this attribute
+ */
+ @Override
+ public Attribute copy( final ConstantPool _constant_pool ) {
+ final NestMembers c = (NestMembers) clone();
+ if (classes != null) {
+ c.classes = new int[classes.length];
+ System.arraycopy(classes, 0, c.classes, 0,
+ classes.length);
+ }
+ c.setConstantPool(_constant_pool);
+ return c;
+ }
+}
diff --git a/src/main/java/org/apache/bcel/classfile/Visitor.java b/src/main/java/org/apache/bcel/classfile/Visitor.java
index b8b7d61..1fb2943 100644
--- a/src/main/java/org/apache/bcel/classfile/Visitor.java
+++ b/src/main/java/org/apache/bcel/classfile/Visitor.java
@@ -132,6 +132,13 @@ public interface Visitor
void visitMethodParameters(MethodParameters obj);
/**
+ * @since 6.4
+ */
+ default void visitMethodParameter(MethodParameter obj) {
+ // empty
+ }
+
+ /**
* @since 6.0
*/
void visitConstantMethodType(ConstantMethodType obj);
@@ -162,4 +169,49 @@ public interface Visitor
default void visitConstantDynamic(ConstantDynamic constantDynamic) {
// empty
}
+
+ /**
+ * @since 6.4
+ */
+ void visitModule(Module constantModule);
+
+ /**
+ * @since 6.4
+ */
+ void visitModuleRequires(ModuleRequires constantModule);
+
+ /**
+ * @since 6.4
+ */
+ void visitModuleExports(ModuleExports constantModule);
+
+ /**
+ * @since 6.4
+ */
+ void visitModuleOpens(ModuleOpens constantModule);
+
+ /**
+ * @since 6.4
+ */
+ void visitModuleProvides(ModuleProvides constantModule);
+
+ /**
+ * @since 6.4
+ */
+ void visitModulePackages(ModulePackages constantModule);
+
+ /**
+ * @since 6.4
+ */
+ void visitModuleMainClass(ModuleMainClass obj);
+
+ /**
+ * @since 6.4
+ */
+ void visitNestHost(NestHost obj);
+
+ /**
+ * @since 6.4
+ */
+ void visitNestMembers(NestMembers obj);
}
diff --git a/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java b/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
index 88e8f40..fd0af47 100644
--- a/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
+++ b/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
@@ -193,6 +193,10 @@ public class ConstantPoolGen {
// TODO should this be handled somehow?
} else if (c instanceof org.apache.bcel.classfile.ConstantMethodHandle) {
// TODO should this be handled somehow?
+ } else if (c instanceof org.apache.bcel.classfile.ConstantModule) {
+ // TODO should this be handled somehow?
+ } else if (c instanceof org.apache.bcel.classfile.ConstantPackage) {
+ // TODO should this be handled somehow?
} else {
assert false : "Unexpected constant type: " + c.getClass().getName();
}
diff --git a/src/main/java/org/apache/bcel/verifier/statics/StringRepresentation.java b/src/main/java/org/apache/bcel/verifier/statics/StringRepresentation.java
index 9409428..16031ba 100644
--- a/src/main/java/org/apache/bcel/verifier/statics/StringRepresentation.java
+++ b/src/main/java/org/apache/bcel/verifier/statics/StringRepresentation.java
@@ -54,6 +54,7 @@ import org.apache.bcel.classfile.LocalVariableTable;
import org.apache.bcel.classfile.LocalVariableTypeTable;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.classfile.MethodParameters;
+import org.apache.bcel.classfile.NestMembers;
import org.apache.bcel.classfile.Node;
import org.apache.bcel.classfile.ParameterAnnotationEntry;
import org.apache.bcel.classfile.ParameterAnnotations;
@@ -403,4 +404,12 @@ public class StringRepresentation extends org.apache.bcel.classfile.EmptyVisitor
public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) {
tostring = toString(obj);
}
+
+ /**
+ * @since 6.4
+ */
+ @Override
+ public void visitNestMembers(final NestMembers obj) {
+ tostring = toString(obj);
+ }
}
diff --git a/src/test/java/org/apache/bcel/visitors/CounterVisitor.java b/src/test/java/org/apache/bcel/visitors/CounterVisitor.java
index 3b2a22b..866d619 100644
--- a/src/test/java/org/apache/bcel/visitors/CounterVisitor.java
+++ b/src/test/java/org/apache/bcel/visitors/CounterVisitor.java
@@ -56,7 +56,17 @@ import org.apache.bcel.classfile.LocalVariable;
import org.apache.bcel.classfile.LocalVariableTable;
import org.apache.bcel.classfile.LocalVariableTypeTable;
import org.apache.bcel.classfile.Method;
+import org.apache.bcel.classfile.MethodParameter;
import org.apache.bcel.classfile.MethodParameters;
+import org.apache.bcel.classfile.Module;
+import org.apache.bcel.classfile.ModuleExports;
+import org.apache.bcel.classfile.ModuleOpens;
+import org.apache.bcel.classfile.ModuleProvides;
+import org.apache.bcel.classfile.ModuleRequires;
+import org.apache.bcel.classfile.ModuleMainClass;
+import org.apache.bcel.classfile.ModulePackages;
+import org.apache.bcel.classfile.NestHost;
+import org.apache.bcel.classfile.NestMembers;
import org.apache.bcel.classfile.ParameterAnnotationEntry;
import org.apache.bcel.classfile.ParameterAnnotations;
import org.apache.bcel.classfile.Signature;
@@ -150,6 +160,9 @@ public class CounterVisitor implements Visitor
public int bootstrapMethodsCount = 0;
/** @since 6.0 */
+ public int methodParameterCount = 0;
+
+ /** @since 6.0 */
public int methodParametersCount = 0;
/** @since 6.0 */
@@ -163,6 +176,33 @@ public class CounterVisitor implements Visitor
/** @since 6.3 */
public int constantDynamicCount = 0;
+
+ /** @since 6.4 */
+ public int moduleCount = 0;
+
+ /** @since 6.4 */
+ public int moduleExportsCount = 0;
+
+ /** @since 6.4 */
+ public int moduleOpensCount = 0;
+
+ /** @since 6.4 */
+ public int moduleProvidesCount = 0;
+
+ /** @since 6.4 */
+ public int moduleRequiresCount = 0;
+
+ /** @since 6.4 */
+ public int moduleMainClassCount = 0;
+
+ /** @since 6.4 */
+ public int modulePackagesCount = 0;
+
+ /** @since 6.4 */
+ public int nestHostCount = 0;
+
+ /** @since 6.4 */
+ public int nestMembersCount = 0;
// CHECKSTYLE:ON
@@ -403,6 +443,13 @@ public class CounterVisitor implements Visitor
/** @since 6.0 */
@Override
+ public void visitMethodParameter(final MethodParameter obj)
+ {
+ methodParameterCount++;
+ }
+
+ /** @since 6.0 */
+ @Override
public void visitMethodParameters(final MethodParameters obj)
{
methodParametersCount++;
@@ -450,4 +497,58 @@ public class CounterVisitor implements Visitor
public void visitConstantDynamic(final ConstantDynamic constantDynamic) {
constantDynamicCount++;
}
+
+ /** @since 6.4 */
+ @Override
+ public void visitModule(final Module obj) {
+ moduleCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleExports(final ModuleExports obj) {
+ moduleExportsCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleOpens(final ModuleOpens obj) {
+ moduleOpensCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleProvides(final ModuleProvides obj) {
+ moduleProvidesCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleRequires(final ModuleRequires obj) {
+ moduleRequiresCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModuleMainClass(final ModuleMainClass obj) {
+ moduleMainClassCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitModulePackages(final ModulePackages obj) {
+ modulePackagesCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitNestHost(final NestHost obj) {
+ nestHostCount++;
+ }
+
+ /** @since 6.4 */
+ @Override
+ public void visitNestMembers(final NestMembers obj) {
+ nestMembersCount++;
+ }
}