From 951295ab099c5243640d4b349403289578ea5a1b Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Wed, 20 Sep 2017 16:16:48 -0700 Subject: [PATCH] Upgrading bcel to latest J9 attributes --- .../org/aspectj/apache/bcel/Constants.java | 33 +- .../apache/bcel/classfile/Attribute.java | 6 + .../apache/bcel/classfile/ClassParser.java | 1 - .../apache/bcel/classfile/ClassVisitor.java | 9 +- .../apache/bcel/classfile/Constant.java | 2 + .../apache/bcel/classfile/ConstantModule.java | 111 ++++++ .../bcel/classfile/ConstantPackage.java | 111 ++++++ .../apache/bcel/classfile/ConstantPool.java | 22 ++ .../aspectj/apache/bcel/classfile/Module.java | 357 ++++++++++++++---- .../bcel/classfile/ModuleMainClass.java | 106 ++++++ .../apache/bcel/classfile/ModulePackages.java | 126 +++++++ bcel-builder/testdata/modules/cpl.sh | 25 +- .../testdata/modules/one/module-info.class | Bin 124 -> 146 bytes .../testdata/modules/two/a/module-info.class | Bin 126 -> 148 bytes .../testdata/modules/two/a/module-info.java | 3 +- .../testdata/modules/two/b/module-info.class | Bin 126 -> 148 bytes .../testdata/modules/two/c/module-info.class | Bin 126 -> 148 bytes .../testdata/modules/two/d/module-info.class | Bin 150 -> 199 bytes .../testdata/modules/two/d/module-info.java | 3 +- .../testdata/modules/two/e/module-info.class | Bin 193 -> 236 bytes .../testdata/modules/two/f/module-info.class | Bin 145 -> 167 bytes .../testdata/modules/two/g/module-info.class | Bin 202 -> 268 bytes .../testdata/modules/two/g/module-info.java | 2 + bcel-builder/testdata/modules/two/h/C1.java | 3 + bcel-builder/testdata/modules/two/h/C2.java | 3 + bcel-builder/testdata/modules/two/h/C3.java | 3 + .../testdata/modules/two/h/com/foo1/C1.class | Bin 0 -> 187 bytes .../testdata/modules/two/h/com/foo2/C2.class | Bin 0 -> 187 bytes .../testdata/modules/two/h/com/foo3/C3.class | Bin 0 -> 187 bytes .../testdata/modules/two/h/module-info.class | Bin 0 -> 236 bytes .../testdata/modules/two/h/module-info.java | 5 + .../bcel/classfile/tests/ModuleTest.java | 49 +-- .../bcel/verifier/DescendingVisitor.java | 28 ++ .../bcel/verifier/EmptyClassVisitor.java | 18 +- 34 files changed, 924 insertions(+), 102 deletions(-) create mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java create mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java create mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ModuleMainClass.java create mode 100644 bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java create mode 100644 bcel-builder/testdata/modules/two/h/C1.java create mode 100644 bcel-builder/testdata/modules/two/h/C2.java create mode 100644 bcel-builder/testdata/modules/two/h/C3.java create mode 100644 bcel-builder/testdata/modules/two/h/com/foo1/C1.class create mode 100644 bcel-builder/testdata/modules/two/h/com/foo2/C2.class create mode 100644 bcel-builder/testdata/modules/two/h/com/foo3/C3.class create mode 100644 bcel-builder/testdata/modules/two/h/module-info.class create mode 100644 bcel-builder/testdata/modules/two/h/module-info.java diff --git a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java b/bcel-builder/src/org/aspectj/apache/bcel/Constants.java index 8d8427006..41d75a7cf 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/Constants.java @@ -114,10 +114,19 @@ public interface Constants { public final static short ACC_BRIDGE = 0x0040; public final static short ACC_VARARGS = 0x0080; - // module related - public final static int MODULE_ACC_PUBLIC = 0x0020; - public final static int MODULE_ACC_SYNTHETIC = 0x1000; - public final static int MODULE_ACC_MANDATED = 0x8000; + // Module related + // Indicates that any module which depends on the current module, + // implicitly declares a dependence on the module indicated by this entry. + public final static int MODULE_ACC_TRANSITIVE = 0x0020; + // Indicates that this dependence is mandatory in the static phase, i.e., at + // compile time, but is optional in the dynamic phase, i.e., at run time. + public final static int MODULE_ACC_STATIC_PHASE = 0x0040; + // Indicates that this dependence was not explicitly or implicitly declared + // in the source of the module declaration. + public final static int MODULE_ACC_SYNTHETIC = 0x1000; + // Indicates that this dependence was implicitly declared in the source of + // the module declaration + public final static int MODULE_ACC_MANDATED = 0x8000; // Applies to classes compiled by new compilers only public final static short ACC_SUPER = 0x0020; @@ -143,6 +152,11 @@ public interface Constants { public final static byte CONSTANT_MethodHandle = 15; public final static byte CONSTANT_MethodType = 16; public final static byte CONSTANT_InvokeDynamic = 18; + + // Java 9 + public final static byte CONSTANT_Module = 19; + public final static byte CONSTANT_Package = 20; + public final static String[] CONSTANT_NAMES = { "", "CONSTANT_Utf8", "", "CONSTANT_Integer", "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double", "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", "CONSTANT_Methodref", @@ -624,8 +638,13 @@ public interface Constants { public static final byte ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 20; public static final byte ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 21; public static final byte ATTR_METHOD_PARAMETERS = 22; - - public static final short KNOWN_ATTRIBUTES = 23; + + // J9: + public static final byte ATTR_MODULE = 23; + public static final byte ATTR_MODULE_PACKAGES = 24; + public static final byte ATTR_MODULE_MAIN_CLASS = 25; + + public static final short KNOWN_ATTRIBUTES = 26; public static final String[] ATTRIBUTE_NAMES = { "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", @@ -633,7 +652,7 @@ public interface Constants { "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", "AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", - "MethodParameters" + "MethodParameters", "Module", "ModulePackages", "ModuleMainClass" }; /** diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java index 34ed08f5e..edc8d22c9 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java @@ -167,6 +167,12 @@ public abstract class Attribute implements Cloneable, Node, Serializable { return new RuntimeInvisTypeAnnos(idx, len, file, cpool); case Constants.ATTR_METHOD_PARAMETERS: return new MethodParameters(idx, len, file, cpool); + case Constants.ATTR_MODULE: + return new Module(idx, len, file, cpool); + case Constants.ATTR_MODULE_PACKAGES: + return new ModulePackages(idx, len, file, cpool); + case Constants.ATTR_MODULE_MAIN_CLASS: + return new ModuleMainClass(idx, len, file, cpool); default: throw new IllegalStateException(); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java index f7e794c8c..54882beee 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassParser.java @@ -180,7 +180,6 @@ public final class ClassParser { superclassnameIndex = file.readUnsignedShort(); } - /** Read constant pool entries */ private final void readConstantPool() throws IOException { try { cpool = new ConstantPool(file); diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java index f72da47ee..0a9340649 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java @@ -103,6 +103,10 @@ public interface ClassVisitor { public void visitConstantString(ConstantString obj); + public void visitConstantModule(ConstantModule obj); + + public void visitConstantPackage(ConstantPackage obj); + public void visitConstantUtf8(ConstantUtf8 obj); public void visitConstantValue(ConstantValue obj); @@ -163,5 +167,8 @@ public interface ClassVisitor { public void visitMethodParameters(MethodParameters methodParameters); - public void visitModule(Module m); + // J9: + public void visitModule(Module module); + public void visitModulePackages(ModulePackages modulePackage); + public void visitModuleMainClass(ModuleMainClass moduleMainClass); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java index 2110bdc08..6fbbff3a3 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Constant.java @@ -135,6 +135,8 @@ public abstract class Constant implements Cloneable, Node { return new ConstantMethodType(dis); case Constants.CONSTANT_InvokeDynamic: return new ConstantInvokeDynamic(dis); + case Constants.CONSTANT_Module: return new ConstantModule(dis); + case Constants.CONSTANT_Package: return new ConstantPackage(dis); default: throw new ClassFormatException("Invalid byte tag in constant pool: " + b); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java new file mode 100644 index 000000000..efe4d3a1b --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantModule.java @@ -0,0 +1,111 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Represents a module. + * + * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.11 + * + * @author Andy Clement + */ +public final class ConstantModule extends Constant { + + private int nameIndex; + + ConstantModule(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantModule(int nameIndex) { + super(Constants.CONSTANT_Module); + this.nameIndex = nameIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantModule(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(nameIndex); + } + + @Override + public Integer getValue() { + return nameIndex; + } + + public final int getNameIndex() { + return nameIndex; + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + nameIndex + ")"; + } + + public String getModuleName(ConstantPool cpool) { + Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java new file mode 100644 index 000000000..70f22c749 --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPackage.java @@ -0,0 +1,111 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Represents a module. + * + * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.12 + * + * @author Andy Clement + */ +public final class ConstantPackage extends Constant { + + private int nameIndex; + + ConstantPackage(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + + public ConstantPackage(int nameIndex) { + super(Constants.CONSTANT_Package); + this.nameIndex = nameIndex; + } + + @Override + public void accept(ClassVisitor v) { + v.visitConstantPackage(this); + } + + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(nameIndex); + } + + @Override + public Integer getValue() { + return nameIndex; + } + + public final int getNameIndex() { + return nameIndex; + } + + @Override + public final String toString() { + return super.toString() + "(name_index = " + nameIndex + ")"; + } + + public String getPackageName(ConstantPool cpool) { + Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getValue(); + } +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java index 4e160ba3d..be5b84564 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ConstantPool.java @@ -275,6 +275,20 @@ public class ConstantPool implements Node { assert c.tag == Constants.CONSTANT_Utf8; return (ConstantUtf8) c; } + + public ConstantModule getConstantModule(int index) { + Constant c = getConstant(index); + assert c != null; + assert c.tag == Constants.CONSTANT_Module; + return (ConstantModule)c; + } + + public ConstantPackage getConstantPackage(int index) { + Constant c = getConstant(index); + assert c != null; + assert c.tag == Constants.CONSTANT_Package; + return (ConstantPackage)c; + } public String getConstantString_CONSTANTClass(int index) { ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class); @@ -770,4 +784,12 @@ public class ConstantPool implements Node { System.arraycopy(pool, 0, cs, 0, poolSize); return new ConstantPool(cs); } + + public String getModuleName(int moduleIndex) { + return getConstantModule(moduleIndex).getModuleName(this); + } + + public String getPackageName(int packageIndex) { + return getConstantPackage(packageIndex).getPackageName(this); + } } \ No newline at end of file diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java index 3041add34..5eef18cde 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Module.java @@ -1,7 +1,7 @@ /* ==================================================================== * The Apache Software License, Version 1.1 * - * Copyright (c) 2001 The Apache Software Foundation. All rights + * Copyright (c) 2016-17 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,18 +53,17 @@ */ package org.aspectj.apache.bcel.classfile; -import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.classfile.Module.Export; /** * This class is derived from Attribute and represents the module * information captured in a class file. * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 * * @author Andy Clement */ @@ -72,89 +71,143 @@ public final class Module extends Attribute { private static final String[] NO_MODULE_NAMES = {}; - private byte[] moduleInfo; - private int ptr; - private boolean unpacked = false; + private int moduleNameIndex; // u2 module_name_index + private int moduleFlags; // u2 module_flags + private int moduleVersionIndex; // u2 module_version_index private Require[] requires; private Export[] exports; + private Open[] opens; private Uses[] uses; private Provide[] provides; - /** - * Build a Module attribute from a previously Unknown attribute. - */ - public Module(Unknown unknown) { - super(unknown.getTag(), unknown.getNameIndex(), unknown.getLength(), unknown.getConstantPool()); - moduleInfo = unknown.getBytes(); - } + private byte[] moduleInfo; + private int ptr; + private boolean unpacked = false; + public Module(Module module) { + super(module.getTag(), module.getNameIndex(), module.getLength(), module.getConstantPool()); + moduleInfo = module.getBytes(); + } + + public Module(int nameIndex, int length, byte[] data, ConstantPool cp) { + super(Constants.ATTR_MODULE, nameIndex, length, cp); + } + + Module(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, (byte[])null, cp); + moduleInfo = new byte[length]; + stream.read(moduleInfo); + unpacked = false; + } + public class Require { - private final int moduleNameIndex; - private final int requiresFlags; + private final int moduleIndex; + private final int flags; + private final int versionIndex; - public Require(int moduleNameIndex, int requiresFlags) { - this.moduleNameIndex = moduleNameIndex; - this.requiresFlags = requiresFlags; + public Require(int moduleIndex, int flags, int versionIndex) { + this.moduleIndex = moduleIndex; + this.flags = flags; + this.versionIndex = versionIndex; } public String getModuleName() { - return cpool.getConstantUtf8(moduleNameIndex).getStringValue(); + return cpool.getModuleName(moduleIndex); + } + + public int getFlags() { + return flags; } - public int getRequiresFlags() { - return requiresFlags; + public int getVersionIndex() { + return versionIndex; + } + + public String getVersionString() { + if (versionIndex == 0) { + return null; + } else { + return cpool.getConstantUtf8(versionIndex).getValue(); + } } - public String getRequiresFlagsAsString() { + public String getFlagsAsString() { StringBuilder s = new StringBuilder(); - if ((requiresFlags & Constants.MODULE_ACC_PUBLIC)!=0) { - s.append("public "); + if ((flags & Constants.MODULE_ACC_TRANSITIVE)!=0) { + s.append(" transitive"); + } + if ((flags & Constants.MODULE_ACC_STATIC_PHASE)!=0) { + s.append(" static"); } - if ((requiresFlags & Constants.MODULE_ACC_SYNTHETIC)!=0) { - s.append("synthetic "); + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); } - if ((requiresFlags & Constants.MODULE_ACC_MANDATED)!=0) { - s.append("mandated "); + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" mandated"); } return s.toString(); } public String toString() { - return "requires "+getRequiresFlagsAsString()+getModuleName(); + return "requires"+getFlagsAsString()+" "+getModuleName()+(versionIndex==0?"":" "+getVersionString()); } - } public class Export { - private final int exportedPackageNameIndex; - private final int[] toModuleNameIndices; + private final int packageIndex; + private final int flags; + private final int[] toModuleIndices; - public Export(int exportedPackageNameIndex, int[] toModuleNameIndices) { - this.exportedPackageNameIndex = exportedPackageNameIndex; - this.toModuleNameIndices = toModuleNameIndices; + public Export(int packageIndex, int flags, int[] toModuleIndices) { + this.packageIndex = packageIndex; + this.flags = flags; + this.toModuleIndices = toModuleIndices; } - public String getExportedPackage() { - return cpool.getConstantUtf8(exportedPackageNameIndex).getStringValue(); + public int getPackageIndex() { + return packageIndex; + } + + public int getFlags() { + return flags; + } + + public int[] getToModuleIndices() { + return toModuleIndices; + } + + public String getPackage() { + return cpool.getPackageName(packageIndex); + } + + public String getFlagsAsString() { + StringBuilder s = new StringBuilder(); + if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) { + s.append(" synthetic"); + } + if ((flags & Constants.MODULE_ACC_MANDATED)!=0) { + s.append(" synthetic"); + } + return s.toString(); } public String[] getToModuleNames() { - if (toModuleNameIndices==null) { + if (toModuleIndices==null) { return NO_MODULE_NAMES; } - String[] toModuleNames = new String[toModuleNameIndices.length]; - for (int i=0;i0) { + s.append(", "); + } + s.append(toModules[i]); + } + } + return s.toString().trim(); + } + } + public class Provide { private final int providedTypeIndex; - private final int withTypeIndex; + private final int[] withTypeIndices; - public Provide(int providedTypeIndex, int withTypeIndex) { + public Provide(int providedTypeIndex, int[] withTypeIndices) { this.providedTypeIndex = providedTypeIndex; - this.withTypeIndex = withTypeIndex; + this.withTypeIndices = withTypeIndices; } public String getProvidedType() { @@ -186,18 +307,27 @@ public final class Module extends Attribute { return providedTypeIndex; } - public String getWithType() { - return cpool.getConstantString_CONSTANTClass(withTypeIndex); + public String[] getWithTypeStrings() { + String[] result = new String[withTypeIndices.length]; + for (int i=0;i0) s.append(","); + s.append(withtypes[i].replace('/','.')); + } return s.toString(); } } @@ -237,24 +367,44 @@ public final class Module extends Attribute { return ((moduleInfo[offset++] & 0xff) << 8) + (moduleInfo[offset] & 0xff); } + // Format: http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 private void ensureUnpacked() { if (!unpacked) { ptr = 0; + moduleNameIndex = readUnsignedShort(); + moduleFlags = readUnsignedShort(); + moduleVersionIndex = readUnsignedShort(); + int count = readUnsignedShort(); requires = new Require[count]; for (int i = 0; i < count; i++) { - requires[i] = new Require(readUnsignedShort(), readUnsignedShort()); + requires[i] = new Require(readUnsignedShort(), readUnsignedShort(), readUnsignedShort()); } + count = readUnsignedShort(); exports = new Export[count]; for (int i = 0; i < count; i++) { int index = readUnsignedShort(); + int flags = readUnsignedShort(); int toCount = readUnsignedShort(); int[] to = new int[toCount]; for (int j = 0; j < toCount; j++) { to[j] = readUnsignedShort(); } - exports[i] = new Export(index, to); + exports[i] = new Export(index, flags, to); + } + + count = readUnsignedShort(); + opens = new Open[count]; + for (int i = 0; i < count; i++) { + int index = readUnsignedShort(); + int flags = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + opens[i] = new Open(index, flags, to); } count = readUnsignedShort(); uses = new Uses[count]; @@ -264,7 +414,13 @@ public final class Module extends Attribute { count = readUnsignedShort(); provides = new Provide[count]; for (int i = 0; i < count; i++) { - provides[i] = new Provide(readUnsignedShort(), readUnsignedShort()); + int index = readUnsignedShort(); + int toCount = readUnsignedShort(); + int[] to = new int[toCount]; + for (int j = 0; j < toCount; j++) { + to[j] = readUnsignedShort(); + } + provides[i] = new Provide(index, to); } unpacked = true; } @@ -276,15 +432,30 @@ public final class Module extends Attribute { if (!unpacked) { file.write(moduleInfo); } else { + + file.writeShort(moduleNameIndex); + file.writeShort(moduleFlags); + file.writeShort(moduleVersionIndex); + file.writeShort(requires.length); for (int i = 0; i < requires.length; i++) { - file.writeShort(requires[i].moduleNameIndex); - file.writeShort(requires[i].requiresFlags); + file.writeShort(requires[i].moduleIndex); + file.writeShort(requires[i].flags); + file.writeShort(requires[i].versionIndex); } file.writeShort(exports.length); for (Export export : exports) { - file.writeShort(export.exportedPackageNameIndex); - int[] toIndices = export.toModuleNameIndices; + file.writeShort(export.packageIndex); + int[] toIndices = export.toModuleIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } + } + file.writeShort(opens.length); + for (Open open : opens) { + file.writeShort(open.packageIndex); + int[] toIndices = open.toModuleIndices; file.writeShort(toIndices.length); for (int index : toIndices) { file.writeShort(index); @@ -297,7 +468,11 @@ public final class Module extends Attribute { file.writeShort(provides.length); for (Provide provide : provides) { file.writeShort(provide.providedTypeIndex); - file.writeShort(provide.withTypeIndex); + int[] toIndices = provide.withTypeIndices; + file.writeShort(toIndices.length); + for (int index : toIndices) { + file.writeShort(index); + } } } } @@ -308,7 +483,7 @@ public final class Module extends Attribute { if (requires.length > 0) { for (Require require : requires) { s.append(' '); - s.append(require.moduleNameIndex).append(':').append(require.requiresFlags); + s.append(require.moduleIndex).append(':').append(require.flags); } } return s.toString(); @@ -320,8 +495,27 @@ public final class Module extends Attribute { if (exports.length > 0) { for (Export export : exports) { s.append(' '); - s.append(export.exportedPackageNameIndex).append(":["); - int[] toIndices = export.toModuleNameIndices; + s.append(export.packageIndex).append(":["); + int[] toIndices = export.toModuleIndices; + for (int i = 0; i < toIndices.length; i++) { + if (i > 0) + s.append(','); + s.append(toIndices[i]); + } + s.append("]"); + } + } + return s.toString(); + } + + public String toStringOpens() { + StringBuilder s = new StringBuilder(); + s.append('#').append(opens.length); + if (opens.length > 0) { + for (Open open : opens) { + s.append(' '); + s.append(open.packageIndex).append(":["); + int[] toIndices = open.toModuleIndices; for (int i = 0; i < toIndices.length; i++) { if (i > 0) s.append(','); @@ -351,7 +545,14 @@ public final class Module extends Attribute { if (provides.length > 0) { for (Provide provide : provides) { s.append(' '); - s.append(provide.providedTypeIndex).append(':').append(provide.withTypeIndex); + s.append(provide.providedTypeIndex).append(":["); + int[] indices = provide.withTypeIndices; + for (int i = 0; i < indices.length; i++) { + if (i > 0) + s.append(','); + s.append(indices[i]); + } + s.append("]"); } } return s.toString(); @@ -372,6 +573,11 @@ public final class Module extends Attribute { s.append(toStringExports()); s.append(" "); } + if (opens.length != 0) { + s.append("opens="); + s.append(toStringOpens()); + s.append(" "); + } if (uses.length != 0) { s.append("uses="); s.append(toStringUses()); @@ -407,7 +613,7 @@ public final class Module extends Attribute { ensureUnpacked(); String[] results = new String[requires.length]; for (int i=0;i. + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Indicates the main class of a module. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 + * + * @author Andy Clement + */ +public final class ModuleMainClass extends Attribute { + + private int mainClassIndex; + + public ModuleMainClass(ModuleMainClass c) { + this(c.getNameIndex(), c.getLength(), c.getMainClassIndex(), c.getConstantPool()); + } + + public ModuleMainClass(int nameIndex, int length, int mainClassIndex, ConstantPool cp) { + super(Constants.ATTR_MODULE_MAIN_CLASS, nameIndex, length, cp); + this.mainClassIndex = mainClassIndex; + } + + ModuleMainClass(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, 0, cp); + this.mainClassIndex = stream.readUnsignedShort(); + } + + @Override + public void accept(ClassVisitor v) { + v.visitModuleMainClass(this); + } + + @Override + public final void dump(DataOutputStream stream) throws IOException { + super.dump(stream); + stream.writeShort(mainClassIndex); + } + + public final int getMainClassIndex() { + return mainClassIndex; + } + + @Override + public final String toString() { + return cpool.getConstantString_CONSTANTClass(mainClassIndex); + } + +} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java new file mode 100644 index 000000000..37da4bc47 --- /dev/null +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ModulePackages.java @@ -0,0 +1,126 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2017 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.aspectj.apache.bcel.classfile; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.apache.bcel.Constants; + +/** + * Indicates all the packages of a module that are exported or opened by the module attribute. + * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26 + * + * @author Andy Clement + */ +public final class ModulePackages extends Attribute { + + private static int[] NO_PACKAGES = new int[0]; + private int[] packageIndices; + + public ModulePackages(ModulePackages c) { + this(c.getNameIndex(), c.getLength(), c.getPackageIndices(), c.getConstantPool()); + } + + public ModulePackages(int nameIndex, int length, int[] packageIndices, ConstantPool cp) { + super(Constants.ATTR_MODULE_PACKAGES, nameIndex, length, cp); + setPackageIndices(packageIndices); + } + + ModulePackages(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException { + this(nameIndex, length, (int[]) null, cp); + int packageIndicesCount = stream.readUnsignedShort(); + packageIndices = new int[packageIndicesCount]; + for (int i = 0; i < packageIndicesCount; i++) { + packageIndices[i] = stream.readUnsignedShort(); + } + } + + @Override + public void accept(ClassVisitor v) { + v.visitModulePackages(this); + } + + @Override + public final void dump(DataOutputStream stream) throws IOException { + super.dump(stream); + stream.writeShort(packageIndices.length); + for (int i = 0; i < packageIndices.length; i++) { + stream.writeShort(packageIndices[i]); + } + } + + public final int[] getPackageIndices() { + return packageIndices; + } + + public final void setPackageIndices(int[] packageIndices) { + if (packageIndices == null) { + this.packageIndices = NO_PACKAGES; + } else { + this.packageIndices = packageIndices; + } + } + + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < packageIndices.length; i++) { + buf.append(cpool.getPackageName(packageIndices[i]) + "\n"); + } + return buf.toString(); + } + +} diff --git a/bcel-builder/testdata/modules/cpl.sh b/bcel-builder/testdata/modules/cpl.sh index 0ac21453d..e2988772f 100755 --- a/bcel-builder/testdata/modules/cpl.sh +++ b/bcel-builder/testdata/modules/cpl.sh @@ -1,24 +1,45 @@ +echo "Build simple empty module definition" cd one javac module-info.java + +# A pre java9 jar e.g. a-b-c-1.6.10.jar would become a module a.b.c (automated module) +echo "Build empty module definition with automated name a.b.c" cd .. cd two/a javac module-info.java + +echo "Build helper module: b.c.d" cd ../.. cd two/b javac module-info.java + +echo "Build helper module: c.d.e" cd ../.. cd two/c javac module-info.java + +echo "Build code using require variants" cd ../.. cd two/d -javac module-info.java -modulepath ../a:../b +javac module-info.java --module-path ../a:../b:../c + +echo "Exports variants" cd ../.. cd two/e -javac module-info.java C1.java C2.java C3.java -d . -modulepath ../a:../b +javac module-info.java C1.java C2.java C3.java -d . --module-path ../a:../b + +echo "Uses variants" cd ../.. cd two/f javac module-info.java I1.java -d . + +echo "Provides variants" cd ../.. cd two/g javac module-info.java I1.java I2.java C1.java C2.java -d . + +echo "Opens variants" +cd ../.. +cd two/h +javac module-info.java C1.java C2.java C3.java --module-path ../a:../b -d . cd ../.. diff --git a/bcel-builder/testdata/modules/one/module-info.class b/bcel-builder/testdata/modules/one/module-info.class index 0088bd13a0e308b65b063c2294d4212ae7aed54b..f852a1790c49171fb0b3b00872e248151759d9c9 100644 GIT binary patch delta 113 zcmb=K#K?Q<->!WO3=F0W-0Tb-6L~dbgc&%68Mqi37%dqYxO4MUN^??mGxO5&85x-K z^HLcZII|MV67`Z2i&GmI7#M+CA%Ka23CLh#U}j(e(qas(U|~iEwgv_Ub}$=A000Oj B5TF16 delta 68 zcmbQlSi^hj->!WO3=F0W?CcC|6L~e|7#TRT63Y_xk`jwk85#KV^HTM5^HWN5Qgt)) U(()%JNb~YAFfy<<05yRC0Ec)GivR!s diff --git a/bcel-builder/testdata/modules/two/a/module-info.class b/bcel-builder/testdata/modules/two/a/module-info.class index c0003b8f6b0a3f2814d820d2949bffadeaf73b23..1e64df02975f7d9b3032064a21ccf5c307b0f871 100644 GIT binary patch delta 115 zcmb=M!pM8-->!WO3=F0W-0Tb-6L~e`gc&%68Mqi37%dqYxO4MUN^??mGxO5&85vj; z^^)|G85uaU63c+h#NyNj1_nl;W(Z(nU;;9j7?>GYfV3C`D_EG3fvtgofgQ{S5&$v{ B5a<8^ delta 93 zcmbQjSjT(n->!WO3=F0W?CcC|6L~c~7#TRT63Y_xk`jwk85sl<^^^3I^>g!6N^??m jGxO5&8yFZEff^uyiGc~oU}9iqU;)xRKpEBshztV&5MB^+ diff --git a/bcel-builder/testdata/modules/two/a/module-info.java b/bcel-builder/testdata/modules/two/a/module-info.java index 8ab4a7dc9..d4873ccd7 100644 --- a/bcel-builder/testdata/modules/two/a/module-info.java +++ b/bcel-builder/testdata/modules/two/a/module-info.java @@ -1,2 +1 @@ -module a.b.c { -} +module a.b.c { } diff --git a/bcel-builder/testdata/modules/two/b/module-info.class b/bcel-builder/testdata/modules/two/b/module-info.class index 6721be124d00ff7894eec5adccdd08ea9d3fc46b..226c01309402366cfa744c6069601acf8bde18e3 100644 GIT binary patch delta 115 zcmb=M!pM8-->!WO3=F0W-0Tb-6L~e`gc&%68Mqi37%dqYxO4MUN^??mGxO5&85vlU z^pf>b7#TRT63Y_xk`jwk8yFZEftn$JiGc~oU}9iqU;)x%46I;bMh3P91_pL88%O{E DGSCp~ delta 93 zcmbQjSjT(n->!WO3=F0W?CcC|6L~c~7#TRT63Y_xk`jwk85snV^po{d^mFr5N^??m jGxO5&8yFZEff^uyiGc~oU}9iqU;)xRKpEBshztV&5d#o) diff --git a/bcel-builder/testdata/modules/two/c/module-info.class b/bcel-builder/testdata/modules/two/c/module-info.class index 0c81601d50e6b38d79ec5620937f7c305608dfc7..6feb99fc1bb754f7ac97b519609dd88399f309cc 100644 GIT binary patch delta 115 zcmb=M!pM8-->!WO3=F0W-0Tb-6L~e`gc&%68Mqi37%dqYxO4MUN^??mGxO5&85vlU z^-}aw85uaU63Y_xk`jwk8yFZEftn$JiGc~oU}9iqU;)x%46I;bMh3P91_pL88%O{E DGm{YR delta 93 zcmbQjSjT(n->!WO3=F0W?CcC|6L~c~7#TRT63Y_xk`jwk85snV^;7gy^>g!6N^??m jGxO5&8yFZEff^uyiGc~oU}9iqU;)xRKpEBshztV&5vUM& diff --git a/bcel-builder/testdata/modules/two/d/module-info.class b/bcel-builder/testdata/modules/two/d/module-info.class index 358624633050f635dde98ed7fdb3b8a366da5f4d..f4f8de0c3b80fd0b2a4ad9faa56910a2c4d3c286 100644 GIT binary patch delta 141 zcmbQnc$|^<)W2Q(7#J8#83frGxF_;zY6>&(2s7|9GB8>SGw=yB@C!2tFfwrG=BJeA zr0QnorR6g+u%_sx>ZMIIlk;Lt)&sH|7#J9VW+xf1CZuoPyqA51OT4n5mW#G delta 91 zcmX@kIE|6_)W2Q(7#J8#893P)I41IHPK=jx5=_xg)lbvU%}*)KN!88FOUrLyU|R!HXxgwK>2!Ru&bO)-vNBfj)Nc2O2E=~+&*7{% aI&_VZENP+FKyJ35_P|mYQW%|alq^5Nj1Xx6 delta 103 zcmaFEc#x6z)W2Q(7#J8#8F<(kxF_;zPE57+V`LCa)lbt;*U!yQDa}dM&CE;7Z(v|x q1ge7oCI%)TgNcEefdxp*0cBVl7=S!BAdel$<6z(f%5ni|AOHZ97!NQ2 diff --git a/bcel-builder/testdata/modules/two/f/module-info.class b/bcel-builder/testdata/modules/two/f/module-info.class index 9377bb8cc48adf353c85d95b3952d31602d671ab..f2730410d0517b33b31607063949e7881f308ec3 100644 GIT binary patch delta 98 zcmbQpxSWyq)W2Q(7#J8#8F<+lI4AOI>I*Y)2{UjrGB8@QGw?7naOdWyl;))BX6B{k wGcvHI>80ysFfwpvC6*=XB_$T8PK?x)lwe>58o|K8$iUXXz`zb=b1*Of01ZkJumAu6 delta 76 zcmZ3^IFXU})W2Q(7#J8#893P)*eCL8Dl;;0W+j#->Ln!>r?N9}Ffs_H>8I;w=;!9A dl;))BX6B{kPfXS1=VM@GU~K^E1k!8_3;^|F5k3F_ diff --git a/bcel-builder/testdata/modules/two/g/module-info.class b/bcel-builder/testdata/modules/two/g/module-info.class index 415a54036a56c34818dec2d21570052849f289bd..e92cb26b3b81a16f5e0e24e48936235cfd799674 100644 GIT binary patch delta 157 zcmX@b*u%to>ff$?3=9mW4C3qzd=q&!LxdUlg&71G85k`^7z9NagxDE`*%?IG8ARC` z#26X4bMsS5b5eCP^V0Ge8CcWxGW0ST891{N%M$gH5{pwA890*jbM@2m^9>P9qlrnu o`g#nkKzkS%7#Y|a7#P?Ym>4*~d`>V4BA6JsfU?{SJV25c07$bLDgXcg delta 91 zcmeBSI>pF)>ff$?3=9mW4E*d2ToZXUbr=~qvl7b^^^y{cQ`s4~*%^4)8F<+l_!t=k s)Acj-Gxc-xQ%ZAEbu;tQ@+Wo$i;6HXGO#uPjQ|2B1~vwE1`Y;J0M#cFB>(^b diff --git a/bcel-builder/testdata/modules/two/g/module-info.java b/bcel-builder/testdata/modules/two/g/module-info.java index 00633c573..ac20edce2 100644 --- a/bcel-builder/testdata/modules/two/g/module-info.java +++ b/bcel-builder/testdata/modules/two/g/module-info.java @@ -1,4 +1,6 @@ module g.h.i { + exports com.foo1; + exports com.foo2; provides com.foo1.I1 with com.foo1.C1; provides com.foo2.I2 with com.foo2.C2; } diff --git a/bcel-builder/testdata/modules/two/h/C1.java b/bcel-builder/testdata/modules/two/h/C1.java new file mode 100644 index 000000000..eb087840d --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/C1.java @@ -0,0 +1,3 @@ +package com.foo1; + +public class C1 {} diff --git a/bcel-builder/testdata/modules/two/h/C2.java b/bcel-builder/testdata/modules/two/h/C2.java new file mode 100644 index 000000000..528b87e02 --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/C2.java @@ -0,0 +1,3 @@ +package com.foo2; + +public class C2 {} diff --git a/bcel-builder/testdata/modules/two/h/C3.java b/bcel-builder/testdata/modules/two/h/C3.java new file mode 100644 index 000000000..205f75fac --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/C3.java @@ -0,0 +1,3 @@ +package com.foo3; + +public class C3 {} diff --git a/bcel-builder/testdata/modules/two/h/com/foo1/C1.class b/bcel-builder/testdata/modules/two/h/com/foo1/C1.class new file mode 100644 index 0000000000000000000000000000000000000000..6b5bb5fd4e4b3946e91cb1606e18fa25d29d2f7c GIT binary patch literal 187 zcmW-ay$ZrW5QJy*cbY`>1uX2;!jQsFYywuIg<^k+r(8&K5E9?ZO0e(&d?;~~U6|#Y zVc75Q{Q1uX2;!a%@IYywuIg<^k+r(8&K5E9?ZO0e(&d?;~~U6|#Y zVc75Q{Q1uX2;!W6+yYywuIg<^k+r(8&K5E9?ZO0e(&d?;~~U6|#Y zVc75Q{QtyB@38OrHrsGpulgm2k(1sBMoz?*Hg})FGYy=$iST)=h^IbLI Tv3KCNB;d^7AY>J+!-jqVAY~|F literal 0 HcmV?d00001 diff --git a/bcel-builder/testdata/modules/two/h/module-info.java b/bcel-builder/testdata/modules/two/h/module-info.java new file mode 100644 index 000000000..253e8c47e --- /dev/null +++ b/bcel-builder/testdata/modules/two/h/module-info.java @@ -0,0 +1,5 @@ +module e.f.g { + opens com.foo1; + opens com.foo2 to a.b.c; + opens com.foo3 to a.b.c, b.c.d; +} diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java index d6e2b456b..454817df8 100644 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java @@ -1,13 +1,10 @@ /* ******************************************************************* - * Copyright (c) 2016 Contributors + * Copyright (c) 2016-2017 Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - initial implementation * ******************************************************************/ package org.aspectj.apache.bcel.classfile.tests; @@ -21,11 +18,11 @@ import org.aspectj.apache.bcel.classfile.ClassParser; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.Module; import org.aspectj.apache.bcel.classfile.Module.Export; +import org.aspectj.apache.bcel.classfile.Module.Open; import org.aspectj.apache.bcel.classfile.Module.Provide; import org.aspectj.apache.bcel.classfile.Module.Require; import org.aspectj.apache.bcel.classfile.Module.Uses; import org.aspectj.apache.bcel.classfile.SourceFile; -import org.aspectj.apache.bcel.classfile.Unknown; /** * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html @@ -49,7 +46,7 @@ public class ModuleTest extends BcelTestCase { Attribute[] attrs = javaClass.getAttributes(); assertEquals(2,attrs.length); SourceFile sourceFile = (SourceFile) getAttribute(attrs,Constants.ATTR_SOURCE_FILE); - Module moduleAttr = new Module((Unknown)getAttribute(attrs,Constants.ATTR_UNKNOWN)); + Module moduleAttr = (Module) getAttribute(attrs, Constants.ATTR_MODULE); byte[] originalData = moduleAttr.getBytes(); String[] requiredModuleNames = moduleAttr.getRequiredModuleNames(); assertEquals(1,requiredModuleNames.length); @@ -73,28 +70,39 @@ public class ModuleTest extends BcelTestCase { public void testRequires() throws Exception { Module moduleAttr = getModuleAttribute("testdata/modules/two/d/module-info.class"); Require[] requires = moduleAttr.getRequires(); - assertEquals(3,requires.length); - assertEquals("requires mandated java.base",requires[0].toString()); + assertEquals(4, requires.length); + assertEquals("requires mandated java.base 9",requires[0].toString()); assertEquals("requires a.b.c",requires[1].toString()); - assertEquals("requires public b.c.d",requires[2].toString()); + assertEquals("requires static b.c.d",requires[2].toString()); + assertEquals("requires transitive c.d.e",requires[3].toString()); assertEquals("java.base",requires[0].getModuleName()); assertEquals("a.b.c",requires[1].getModuleName()); assertEquals("b.c.d",requires[2].getModuleName()); + assertEquals("c.d.e",requires[3].getModuleName()); } public void testExports() throws Exception { Module moduleAttr = getModuleAttribute("testdata/modules/two/e/module-info.class"); Export[] exports = moduleAttr.getExports(); - assertEquals(3,exports.length); - assertEquals("exports com.foo1",exports[0].toString()); + assertEquals(3, exports.length); + assertEquals("exports com.foo1", exports[0].toString()); assertEquals("exports com.foo2 to a.b.c",exports[1].toString()); - assertEquals("exports com.foo3 to b.c.d, a.b.c",exports[2].toString()); - assertEquals("com/foo1",exports[0].getExportedPackage()); - assertEquals("com/foo2",exports[1].getExportedPackage()); - assertEquals("com/foo3",exports[2].getExportedPackage()); + assertEquals("exports com.foo3 to a.b.c, b.c.d",exports[2].toString()); + assertEquals("com/foo1",exports[0].getPackage()); + assertEquals("com/foo2",exports[1].getPackage()); + assertEquals("com/foo3",exports[2].getPackage()); assertEquals("a.b.c",exports[1].getToModuleNames()[0]); - assertEquals("b.c.d",exports[2].getToModuleNames()[0]); - assertEquals("a.b.c",exports[2].getToModuleNames()[1]); + assertEquals("a.b.c",exports[2].getToModuleNames()[0]); + assertEquals("b.c.d",exports[2].getToModuleNames()[1]); + } + + public void testOpens() throws Exception { + Module moduleAttr = getModuleAttribute("testdata/modules/two/h/module-info.class"); + Open[] opens = moduleAttr.getOpens(); + assertEquals(3, opens.length); + assertEquals("opens com.foo1", opens[0].toString()); + assertEquals("opens com.foo2 to a.b.c", opens[1].toString()); + assertEquals("opens com.foo3 to a.b.c, b.c.d", opens[2].toString()); } public void testUses() throws Exception { @@ -112,9 +120,9 @@ public class ModuleTest extends BcelTestCase { assertEquals("provides com.foo1.I1 with com.foo1.C1",provides[0].toString()); assertEquals("provides com.foo2.I2 with com.foo2.C2",provides[1].toString()); assertEquals("com/foo1/I1",provides[0].getProvidedType()); - assertEquals("com/foo1/C1",provides[0].getWithType()); + assertEquals("com/foo1/C1",provides[0].getWithTypeStrings()[0]); assertEquals("com/foo2/I2",provides[1].getProvidedType()); - assertEquals("com/foo2/C2",provides[1].getWithType()); + assertEquals("com/foo2/C2",provides[1].getWithTypeStrings()[0]); } // --- @@ -122,8 +130,7 @@ public class ModuleTest extends BcelTestCase { private Module getModuleAttribute(String moduleInfoClass) throws Exception { ClassParser classParser = new ClassParser(moduleInfoClass); JavaClass javaClass = classParser.parse(); - Module moduleAttr = new Module((Unknown)getAttribute(javaClass.getAttributes(),Constants.ATTR_UNKNOWN)); - return moduleAttr; + return (Module)getAttribute(javaClass.getAttributes(), Constants.ATTR_MODULE); } } diff --git a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java index be8a558f3..69b9e1321 100644 --- a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java +++ b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/DescendingVisitor.java @@ -73,7 +73,9 @@ import org.aspectj.apache.bcel.classfile.ConstantLong; import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; import org.aspectj.apache.bcel.classfile.ConstantMethodType; import org.aspectj.apache.bcel.classfile.ConstantMethodref; +import org.aspectj.apache.bcel.classfile.ConstantModule; import org.aspectj.apache.bcel.classfile.ConstantNameAndType; +import org.aspectj.apache.bcel.classfile.ConstantPackage; import org.aspectj.apache.bcel.classfile.ConstantPool; import org.aspectj.apache.bcel.classfile.ConstantString; import org.aspectj.apache.bcel.classfile.ConstantUtf8; @@ -93,6 +95,8 @@ import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.apache.bcel.classfile.MethodParameters; import org.aspectj.apache.bcel.classfile.Module; +import org.aspectj.apache.bcel.classfile.ModuleMainClass; +import org.aspectj.apache.bcel.classfile.ModulePackages; import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.classfile.SourceFile; import org.aspectj.apache.bcel.classfile.StackMap; @@ -369,6 +373,18 @@ public class DescendingVisitor implements ClassVisitor { stack.pop(); } + public void visitConstantModule(ConstantModule constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantPackage(ConstantPackage constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + public void visitConstantUtf8(ConstantUtf8 constant) { stack.push(constant); constant.accept(visitor); @@ -491,4 +507,16 @@ public class DescendingVisitor implements ClassVisitor { attribute.accept(visitor); stack.pop(); } + + public void visitModulePackages(ModulePackages attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitModuleMainClass(ModuleMainClass attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } } diff --git a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java index 117d8d320..039d204dd 100644 --- a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java +++ b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/EmptyClassVisitor.java @@ -68,7 +68,9 @@ import org.aspectj.apache.bcel.classfile.ConstantLong; import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; import org.aspectj.apache.bcel.classfile.ConstantMethodType; import org.aspectj.apache.bcel.classfile.ConstantMethodref; +import org.aspectj.apache.bcel.classfile.ConstantModule; import org.aspectj.apache.bcel.classfile.ConstantNameAndType; +import org.aspectj.apache.bcel.classfile.ConstantPackage; import org.aspectj.apache.bcel.classfile.ConstantPool; import org.aspectj.apache.bcel.classfile.ConstantString; import org.aspectj.apache.bcel.classfile.ConstantUtf8; @@ -88,6 +90,8 @@ import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.apache.bcel.classfile.MethodParameters; import org.aspectj.apache.bcel.classfile.Module; +import org.aspectj.apache.bcel.classfile.ModuleMainClass; +import org.aspectj.apache.bcel.classfile.ModulePackages; import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.classfile.SourceFile; import org.aspectj.apache.bcel.classfile.StackMap; @@ -131,6 +135,8 @@ public class EmptyClassVisitor implements ClassVisitor { public void visitConstantNameAndType(ConstantNameAndType obj) {} public void visitConstantPool(ConstantPool obj) {} public void visitConstantString(ConstantString obj) {} + public void visitConstantModule(ConstantModule obj) {} + public void visitConstantPackage(ConstantPackage obj) {} public void visitConstantUtf8(ConstantUtf8 obj) {} public void visitConstantValue(ConstantValue obj) {} public void visitDeprecated(Deprecated obj) {} @@ -151,9 +157,8 @@ public class EmptyClassVisitor implements ClassVisitor { public void visitUnknown(Unknown obj) {} public void visitStackMap(StackMap obj) {} public void visitStackMapEntry(StackMapEntry obj) {} - public void visitModule(Module obj) {} - - // J5SUPPORT: + + // J5: public void visitEnclosingMethod(EnclosingMethod obj) {} public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos attribute) {} public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos attribute) {} @@ -162,9 +167,14 @@ public class EmptyClassVisitor implements ClassVisitor { public void visitAnnotationDefault(AnnotationDefault attribute) {} public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {} - // J8SUPPORT: + // J8: public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) {} public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) {} public void visitMethodParameters(MethodParameters attribute) {} + // J9: + public void visitModule(Module attribute) {} + public void visitModulePackages(ModulePackages attribute) {} + public void visitModuleMainClass(ModuleMainClass attribute) {} + } -- 2.39.5