@@ -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" | |||
}; | |||
/** |
@@ -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(); | |||
} |
@@ -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); |
@@ -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); | |||
} |
@@ -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); | |||
} |
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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(); | |||
} | |||
} |
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 <em>Attribute</em> 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;i<toModuleNameIndices.length;i++) { | |||
toModuleNames[i] = cpool.getConstantUtf8(toModuleNameIndices[i]).getStringValue(); | |||
String[] toModuleNames = new String[toModuleIndices.length]; | |||
for (int i=0;i<toModuleIndices.length;i++) { | |||
toModuleNames[i] = cpool.getModuleName(toModuleIndices[i]); | |||
} | |||
return toModuleNames; | |||
} | |||
public String toString() { | |||
StringBuilder s =new StringBuilder(); | |||
s.append("exports ").append(getExportedPackage().replace('/', '.')); | |||
s.append("exports").append(getFlagsAsString()).append(" ").append(getPackage().replace('/', '.')); | |||
String[] toModules = getToModuleNames(); | |||
if (toModules.length!=0) { | |||
s.append(" to "); | |||
@@ -168,14 +221,82 @@ public final class Module extends Attribute { | |||
return s.toString().trim(); | |||
} | |||
} | |||
public class Open { | |||
private final int packageIndex; | |||
private final int flags; | |||
private final int[] toModuleIndices; | |||
public Open(int packageIndex, int flags, int[] toModuleIndices) { | |||
this.packageIndex = packageIndex; | |||
this.flags = flags; | |||
this.toModuleIndices = toModuleIndices; | |||
} | |||
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 (toModuleIndices==null) { | |||
return NO_MODULE_NAMES; | |||
} | |||
String[] toModuleNames = new String[toModuleIndices.length]; | |||
for (int i=0;i<toModuleIndices.length;i++) { | |||
toModuleNames[i] = cpool.getModuleName(toModuleIndices[i]); | |||
} | |||
return toModuleNames; | |||
} | |||
public String toString() { | |||
StringBuilder s =new StringBuilder(); | |||
s.append("opens").append(getFlagsAsString()).append(" ").append(getPackage().replace('/', '.')); | |||
String[] toModules = getToModuleNames(); | |||
if (toModules.length!=0) { | |||
s.append(" to "); | |||
for (int i=0;i<toModules.length;i++) { | |||
if (i>0) { | |||
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;i<withTypeIndices.length;i++) { | |||
result[i] = cpool.getConstantString_CONSTANTClass(withTypeIndices[i]); | |||
} | |||
return result; | |||
} | |||
public int getWithTypeIndex() { | |||
return withTypeIndex; | |||
public int[] getWithTypeIndices() { | |||
return withTypeIndices; | |||
} | |||
public String toString() { | |||
StringBuilder s =new StringBuilder(); | |||
s.append("provides ").append(getProvidedType().replace('/', '.')); | |||
s.append(" with ").append(getWithType().replace('/','.')); | |||
s.append(" with "); | |||
String[] withtypes = getWithTypeStrings(); | |||
for (int i=0;i< withtypes.length;i++) { | |||
if (i>0) 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<requires.length;i++) { | |||
results[i] = cpool.getConstantUtf8(requires[i].moduleNameIndex).getStringValue(); | |||
results[i] = cpool.getModuleName(requires[i].moduleIndex); | |||
} | |||
return results; | |||
} | |||
@@ -420,6 +626,11 @@ public final class Module extends Attribute { | |||
ensureUnpacked(); | |||
return exports; | |||
} | |||
public Open[] getOpens() { | |||
ensureUnpacked(); | |||
return opens; | |||
} | |||
public Uses[] getUses() { | |||
ensureUnpacked(); | |||
@@ -430,4 +641,24 @@ public final class Module extends Attribute { | |||
ensureUnpacked(); | |||
return provides; | |||
} | |||
public String getModuleName() { | |||
return ((ConstantModule)cpool.getConstant(moduleNameIndex)).getModuleName(cpool); | |||
} | |||
public int getModuleFlags() { | |||
// 0x0020 (ACC_OPEN) - Indicates that this module is open. | |||
// 0x1000 (ACC_SYNTHETIC) - Indicates that this module was not explicitly or implicitly declared. | |||
// 0x8000 (ACC_MANDATED) - Indicates that this module was implicitly declared | |||
return moduleFlags; | |||
} | |||
/** @return the module version or null if no version information specified */ | |||
public String getModuleVersion() { | |||
if (moduleVersionIndex == 0) { | |||
return null; | |||
} else { | |||
return cpool.getConstantUtf8(moduleVersionIndex).getValue(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,106 @@ | |||
/* ==================================================================== | |||
* 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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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); | |||
} | |||
} |
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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(); | |||
} | |||
} |
@@ -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 ../.. |
@@ -1,2 +1 @@ | |||
module a.b.c { | |||
} | |||
module a.b.c { } |
@@ -1,4 +1,5 @@ | |||
module d.e.f { | |||
requires a.b.c; | |||
requires public b.c.d; | |||
requires static b.c.d; | |||
requires transitive c.d.e; | |||
} |
@@ -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; | |||
} |
@@ -0,0 +1,3 @@ | |||
package com.foo1; | |||
public class C1 {} |
@@ -0,0 +1,3 @@ | |||
package com.foo2; | |||
public class C2 {} |
@@ -0,0 +1,3 @@ | |||
package com.foo3; | |||
public class C3 {} |
@@ -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; | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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) {} | |||
} |