public final static short ACC_BRIDGE = 0x0040; | public final static short ACC_BRIDGE = 0x0040; | ||||
public final static short ACC_VARARGS = 0x0080; | 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 | // Applies to classes compiled by new compilers only | ||||
public final static short ACC_SUPER = 0x0020; | public final static short ACC_SUPER = 0x0020; | ||||
public final static byte CONSTANT_MethodHandle = 15; | public final static byte CONSTANT_MethodHandle = 15; | ||||
public final static byte CONSTANT_MethodType = 16; | public final static byte CONSTANT_MethodType = 16; | ||||
public final static byte CONSTANT_InvokeDynamic = 18; | 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", | public final static String[] CONSTANT_NAMES = { "", "CONSTANT_Utf8", "", "CONSTANT_Integer", "CONSTANT_Float", "CONSTANT_Long", | ||||
"CONSTANT_Double", "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", "CONSTANT_Methodref", | "CONSTANT_Double", "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", "CONSTANT_Methodref", | ||||
public static final byte ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 20; | 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_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 21; | ||||
public static final byte ATTR_METHOD_PARAMETERS = 22; | 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 = { | public static final String[] ATTRIBUTE_NAMES = { | ||||
"SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", | "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", | ||||
"RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", | "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", | ||||
"RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", | "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", | ||||
"AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", | "AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", | ||||
"MethodParameters" | |||||
"MethodParameters", "Module", "ModulePackages", "ModuleMainClass" | |||||
}; | }; | ||||
/** | /** |
return new RuntimeInvisTypeAnnos(idx, len, file, cpool); | return new RuntimeInvisTypeAnnos(idx, len, file, cpool); | ||||
case Constants.ATTR_METHOD_PARAMETERS: | case Constants.ATTR_METHOD_PARAMETERS: | ||||
return new MethodParameters(idx, len, file, cpool); | 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: | default: | ||||
throw new IllegalStateException(); | throw new IllegalStateException(); | ||||
} | } |
superclassnameIndex = file.readUnsignedShort(); | superclassnameIndex = file.readUnsignedShort(); | ||||
} | } | ||||
/** Read constant pool entries */ | |||||
private final void readConstantPool() throws IOException { | private final void readConstantPool() throws IOException { | ||||
try { | try { | ||||
cpool = new ConstantPool(file); | cpool = new ConstantPool(file); |
public void visitConstantString(ConstantString obj); | public void visitConstantString(ConstantString obj); | ||||
public void visitConstantModule(ConstantModule obj); | |||||
public void visitConstantPackage(ConstantPackage obj); | |||||
public void visitConstantUtf8(ConstantUtf8 obj); | public void visitConstantUtf8(ConstantUtf8 obj); | ||||
public void visitConstantValue(ConstantValue obj); | public void visitConstantValue(ConstantValue obj); | ||||
public void visitMethodParameters(MethodParameters methodParameters); | 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); | |||||
} | } |
return new ConstantMethodType(dis); | return new ConstantMethodType(dis); | ||||
case Constants.CONSTANT_InvokeDynamic: | case Constants.CONSTANT_InvokeDynamic: | ||||
return new ConstantInvokeDynamic(dis); | return new ConstantInvokeDynamic(dis); | ||||
case Constants.CONSTANT_Module: return new ConstantModule(dis); | |||||
case Constants.CONSTANT_Package: return new ConstantPackage(dis); | |||||
default: | default: | ||||
throw new ClassFormatException("Invalid byte tag in constant pool: " + b); | throw new ClassFormatException("Invalid byte tag in constant pool: " + b); | ||||
} | } |
/* ==================================================================== | |||||
* 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(); | |||||
} | |||||
} |
/* ==================================================================== | |||||
* 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(); | |||||
} | |||||
} |
assert c.tag == Constants.CONSTANT_Utf8; | assert c.tag == Constants.CONSTANT_Utf8; | ||||
return (ConstantUtf8) c; | 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) { | public String getConstantString_CONSTANTClass(int index) { | ||||
ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class); | ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class); | ||||
System.arraycopy(pool, 0, cs, 0, poolSize); | System.arraycopy(pool, 0, cs, 0, poolSize); | ||||
return new ConstantPool(cs); | return new ConstantPool(cs); | ||||
} | } | ||||
public String getModuleName(int moduleIndex) { | |||||
return getConstantModule(moduleIndex).getModuleName(this); | |||||
} | |||||
public String getPackageName(int packageIndex) { | |||||
return getConstantPackage(packageIndex).getPackageName(this); | |||||
} | |||||
} | } |
/* ==================================================================== | /* ==================================================================== | ||||
* The Apache Software License, Version 1.1 | * 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. | * reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
*/ | */ | ||||
package org.aspectj.apache.bcel.classfile; | package org.aspectj.apache.bcel.classfile; | ||||
import java.io.ByteArrayInputStream; | |||||
import java.io.DataInputStream; | import java.io.DataInputStream; | ||||
import java.io.DataOutputStream; | import java.io.DataOutputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import org.aspectj.apache.bcel.Constants; | 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 | * This class is derived from <em>Attribute</em> and represents the module | ||||
* information captured in a class file. | * 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/lang-vm.html | ||||
* http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25 | |||||
* | * | ||||
* @author Andy Clement | * @author Andy Clement | ||||
*/ | */ | ||||
private static final String[] NO_MODULE_NAMES = {}; | 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 Require[] requires; | ||||
private Export[] exports; | private Export[] exports; | ||||
private Open[] opens; | |||||
private Uses[] uses; | private Uses[] uses; | ||||
private Provide[] provides; | 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 { | 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() { | 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(); | 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(); | return s.toString(); | ||||
} | } | ||||
public String toString() { | public String toString() { | ||||
return "requires "+getRequiresFlagsAsString()+getModuleName(); | |||||
return "requires"+getFlagsAsString()+" "+getModuleName()+(versionIndex==0?"":" "+getVersionString()); | |||||
} | } | ||||
} | } | ||||
public class Export { | 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() { | public String[] getToModuleNames() { | ||||
if (toModuleNameIndices==null) { | |||||
if (toModuleIndices==null) { | |||||
return NO_MODULE_NAMES; | 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; | return toModuleNames; | ||||
} | } | ||||
public String toString() { | public String toString() { | ||||
StringBuilder s =new StringBuilder(); | StringBuilder s =new StringBuilder(); | ||||
s.append("exports ").append(getExportedPackage().replace('/', '.')); | |||||
s.append("exports").append(getFlagsAsString()).append(" ").append(getPackage().replace('/', '.')); | |||||
String[] toModules = getToModuleNames(); | String[] toModules = getToModuleNames(); | ||||
if (toModules.length!=0) { | if (toModules.length!=0) { | ||||
s.append(" to "); | s.append(" to "); | ||||
return s.toString().trim(); | 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 { | public class Provide { | ||||
private final int providedTypeIndex; | 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.providedTypeIndex = providedTypeIndex; | ||||
this.withTypeIndex = withTypeIndex; | |||||
this.withTypeIndices = withTypeIndices; | |||||
} | } | ||||
public String getProvidedType() { | public String getProvidedType() { | ||||
return providedTypeIndex; | 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() { | public String toString() { | ||||
StringBuilder s =new StringBuilder(); | StringBuilder s =new StringBuilder(); | ||||
s.append("provides ").append(getProvidedType().replace('/', '.')); | 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(); | return s.toString(); | ||||
} | } | ||||
} | } | ||||
return ((moduleInfo[offset++] & 0xff) << 8) + (moduleInfo[offset] & 0xff); | 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() { | private void ensureUnpacked() { | ||||
if (!unpacked) { | if (!unpacked) { | ||||
ptr = 0; | ptr = 0; | ||||
moduleNameIndex = readUnsignedShort(); | |||||
moduleFlags = readUnsignedShort(); | |||||
moduleVersionIndex = readUnsignedShort(); | |||||
int count = readUnsignedShort(); | int count = readUnsignedShort(); | ||||
requires = new Require[count]; | requires = new Require[count]; | ||||
for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
requires[i] = new Require(readUnsignedShort(), readUnsignedShort()); | |||||
requires[i] = new Require(readUnsignedShort(), readUnsignedShort(), readUnsignedShort()); | |||||
} | } | ||||
count = readUnsignedShort(); | count = readUnsignedShort(); | ||||
exports = new Export[count]; | exports = new Export[count]; | ||||
for (int i = 0; i < count; i++) { | for (int i = 0; i < count; i++) { | ||||
int index = readUnsignedShort(); | int index = readUnsignedShort(); | ||||
int flags = readUnsignedShort(); | |||||
int toCount = readUnsignedShort(); | int toCount = readUnsignedShort(); | ||||
int[] to = new int[toCount]; | int[] to = new int[toCount]; | ||||
for (int j = 0; j < toCount; j++) { | for (int j = 0; j < toCount; j++) { | ||||
to[j] = readUnsignedShort(); | 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(); | count = readUnsignedShort(); | ||||
uses = new Uses[count]; | uses = new Uses[count]; | ||||
count = readUnsignedShort(); | count = readUnsignedShort(); | ||||
provides = new Provide[count]; | provides = new Provide[count]; | ||||
for (int i = 0; i < count; i++) { | 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; | unpacked = true; | ||||
} | } | ||||
if (!unpacked) { | if (!unpacked) { | ||||
file.write(moduleInfo); | file.write(moduleInfo); | ||||
} else { | } else { | ||||
file.writeShort(moduleNameIndex); | |||||
file.writeShort(moduleFlags); | |||||
file.writeShort(moduleVersionIndex); | |||||
file.writeShort(requires.length); | file.writeShort(requires.length); | ||||
for (int i = 0; i < requires.length; i++) { | 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); | file.writeShort(exports.length); | ||||
for (Export export : exports) { | 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); | file.writeShort(toIndices.length); | ||||
for (int index : toIndices) { | for (int index : toIndices) { | ||||
file.writeShort(index); | file.writeShort(index); | ||||
file.writeShort(provides.length); | file.writeShort(provides.length); | ||||
for (Provide provide : provides) { | for (Provide provide : provides) { | ||||
file.writeShort(provide.providedTypeIndex); | file.writeShort(provide.providedTypeIndex); | ||||
file.writeShort(provide.withTypeIndex); | |||||
int[] toIndices = provide.withTypeIndices; | |||||
file.writeShort(toIndices.length); | |||||
for (int index : toIndices) { | |||||
file.writeShort(index); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (requires.length > 0) { | if (requires.length > 0) { | ||||
for (Require require : requires) { | for (Require require : requires) { | ||||
s.append(' '); | s.append(' '); | ||||
s.append(require.moduleNameIndex).append(':').append(require.requiresFlags); | |||||
s.append(require.moduleIndex).append(':').append(require.flags); | |||||
} | } | ||||
} | } | ||||
return s.toString(); | return s.toString(); | ||||
if (exports.length > 0) { | if (exports.length > 0) { | ||||
for (Export export : exports) { | for (Export export : exports) { | ||||
s.append(' '); | 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++) { | for (int i = 0; i < toIndices.length; i++) { | ||||
if (i > 0) | if (i > 0) | ||||
s.append(','); | s.append(','); | ||||
if (provides.length > 0) { | if (provides.length > 0) { | ||||
for (Provide provide : provides) { | for (Provide provide : provides) { | ||||
s.append(' '); | 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(); | return s.toString(); | ||||
s.append(toStringExports()); | s.append(toStringExports()); | ||||
s.append(" "); | s.append(" "); | ||||
} | } | ||||
if (opens.length != 0) { | |||||
s.append("opens="); | |||||
s.append(toStringOpens()); | |||||
s.append(" "); | |||||
} | |||||
if (uses.length != 0) { | if (uses.length != 0) { | ||||
s.append("uses="); | s.append("uses="); | ||||
s.append(toStringUses()); | s.append(toStringUses()); | ||||
ensureUnpacked(); | ensureUnpacked(); | ||||
String[] results = new String[requires.length]; | String[] results = new String[requires.length]; | ||||
for (int i=0;i<requires.length;i++) { | 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; | return results; | ||||
} | } | ||||
ensureUnpacked(); | ensureUnpacked(); | ||||
return exports; | return exports; | ||||
} | } | ||||
public Open[] getOpens() { | |||||
ensureUnpacked(); | |||||
return opens; | |||||
} | |||||
public Uses[] getUses() { | public Uses[] getUses() { | ||||
ensureUnpacked(); | ensureUnpacked(); | ||||
ensureUnpacked(); | ensureUnpacked(); | ||||
return provides; | 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(); | |||||
} | |||||
} | |||||
} | } |
/* ==================================================================== | |||||
* 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); | |||||
} | |||||
} |
/* ==================================================================== | |||||
* 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(); | |||||
} | |||||
} |
echo "Build simple empty module definition" | |||||
cd one | cd one | ||||
javac module-info.java | 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 .. | ||||
cd two/a | cd two/a | ||||
javac module-info.java | javac module-info.java | ||||
echo "Build helper module: b.c.d" | |||||
cd ../.. | cd ../.. | ||||
cd two/b | cd two/b | ||||
javac module-info.java | javac module-info.java | ||||
echo "Build helper module: c.d.e" | |||||
cd ../.. | cd ../.. | ||||
cd two/c | cd two/c | ||||
javac module-info.java | javac module-info.java | ||||
echo "Build code using require variants" | |||||
cd ../.. | cd ../.. | ||||
cd two/d | cd two/d | ||||
javac module-info.java -modulepath ../a:../b | |||||
javac module-info.java --module-path ../a:../b:../c | |||||
echo "Exports variants" | |||||
cd ../.. | cd ../.. | ||||
cd two/e | 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 ../.. | ||||
cd two/f | cd two/f | ||||
javac module-info.java I1.java -d . | javac module-info.java I1.java -d . | ||||
echo "Provides variants" | |||||
cd ../.. | cd ../.. | ||||
cd two/g | cd two/g | ||||
javac module-info.java I1.java I2.java C1.java C2.java -d . | 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 ../.. | cd ../.. |
module a.b.c { | |||||
} | |||||
module a.b.c { } |
module d.e.f { | module d.e.f { | ||||
requires a.b.c; | requires a.b.c; | ||||
requires public b.c.d; | |||||
requires static b.c.d; | |||||
requires transitive c.d.e; | |||||
} | } |
module g.h.i { | module g.h.i { | ||||
exports com.foo1; | |||||
exports com.foo2; | |||||
provides com.foo1.I1 with com.foo1.C1; | provides com.foo1.I1 with com.foo1.C1; | ||||
provides com.foo2.I2 with com.foo2.C2; | provides com.foo2.I2 with com.foo2.C2; | ||||
} | } |
package com.foo1; | |||||
public class C1 {} |
package com.foo2; | |||||
public class C2 {} |
package com.foo3; | |||||
public class C3 {} |
module e.f.g { | |||||
opens com.foo1; | |||||
opens com.foo2 to a.b.c; | |||||
opens com.foo3 to a.b.c, b.c.d; | |||||
} |
/* ******************************************************************* | /* ******************************************************************* | ||||
* Copyright (c) 2016 Contributors | |||||
* Copyright (c) 2016-2017 Contributors | |||||
* All rights reserved. | * All rights reserved. | ||||
* This program and the accompanying materials are made available | * This program and the accompanying materials are made available | ||||
* under the terms of the Eclipse Public License v1.0 | * under the terms of the Eclipse Public License v1.0 | ||||
* which accompanies this distribution and is available at | * which accompanies this distribution and is available at | ||||
* http://www.eclipse.org/legal/epl-v10.html | * http://www.eclipse.org/legal/epl-v10.html | ||||
* | |||||
* Contributors: | |||||
* Andy Clement - initial implementation | |||||
* ******************************************************************/ | * ******************************************************************/ | ||||
package org.aspectj.apache.bcel.classfile.tests; | package org.aspectj.apache.bcel.classfile.tests; | ||||
import org.aspectj.apache.bcel.classfile.JavaClass; | import org.aspectj.apache.bcel.classfile.JavaClass; | ||||
import org.aspectj.apache.bcel.classfile.Module; | import org.aspectj.apache.bcel.classfile.Module; | ||||
import org.aspectj.apache.bcel.classfile.Module.Export; | 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.Provide; | ||||
import org.aspectj.apache.bcel.classfile.Module.Require; | import org.aspectj.apache.bcel.classfile.Module.Require; | ||||
import org.aspectj.apache.bcel.classfile.Module.Uses; | import org.aspectj.apache.bcel.classfile.Module.Uses; | ||||
import org.aspectj.apache.bcel.classfile.SourceFile; | 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 | * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html | ||||
Attribute[] attrs = javaClass.getAttributes(); | Attribute[] attrs = javaClass.getAttributes(); | ||||
assertEquals(2,attrs.length); | assertEquals(2,attrs.length); | ||||
SourceFile sourceFile = (SourceFile) getAttribute(attrs,Constants.ATTR_SOURCE_FILE); | 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(); | byte[] originalData = moduleAttr.getBytes(); | ||||
String[] requiredModuleNames = moduleAttr.getRequiredModuleNames(); | String[] requiredModuleNames = moduleAttr.getRequiredModuleNames(); | ||||
assertEquals(1,requiredModuleNames.length); | assertEquals(1,requiredModuleNames.length); | ||||
public void testRequires() throws Exception { | public void testRequires() throws Exception { | ||||
Module moduleAttr = getModuleAttribute("testdata/modules/two/d/module-info.class"); | Module moduleAttr = getModuleAttribute("testdata/modules/two/d/module-info.class"); | ||||
Require[] requires = moduleAttr.getRequires(); | 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 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("java.base",requires[0].getModuleName()); | ||||
assertEquals("a.b.c",requires[1].getModuleName()); | assertEquals("a.b.c",requires[1].getModuleName()); | ||||
assertEquals("b.c.d",requires[2].getModuleName()); | assertEquals("b.c.d",requires[2].getModuleName()); | ||||
assertEquals("c.d.e",requires[3].getModuleName()); | |||||
} | } | ||||
public void testExports() throws Exception { | public void testExports() throws Exception { | ||||
Module moduleAttr = getModuleAttribute("testdata/modules/two/e/module-info.class"); | Module moduleAttr = getModuleAttribute("testdata/modules/two/e/module-info.class"); | ||||
Export[] exports = moduleAttr.getExports(); | 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.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("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 { | public void testUses() throws Exception { | ||||
assertEquals("provides com.foo1.I1 with com.foo1.C1",provides[0].toString()); | 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("provides com.foo2.I2 with com.foo2.C2",provides[1].toString()); | ||||
assertEquals("com/foo1/I1",provides[0].getProvidedType()); | 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/I2",provides[1].getProvidedType()); | ||||
assertEquals("com/foo2/C2",provides[1].getWithType()); | |||||
assertEquals("com/foo2/C2",provides[1].getWithTypeStrings()[0]); | |||||
} | } | ||||
// --- | // --- | ||||
private Module getModuleAttribute(String moduleInfoClass) throws Exception { | private Module getModuleAttribute(String moduleInfoClass) throws Exception { | ||||
ClassParser classParser = new ClassParser(moduleInfoClass); | ClassParser classParser = new ClassParser(moduleInfoClass); | ||||
JavaClass javaClass = classParser.parse(); | 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); | |||||
} | } | ||||
} | } |
import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; | import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; | ||||
import org.aspectj.apache.bcel.classfile.ConstantMethodType; | import org.aspectj.apache.bcel.classfile.ConstantMethodType; | ||||
import org.aspectj.apache.bcel.classfile.ConstantMethodref; | 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.ConstantNameAndType; | ||||
import org.aspectj.apache.bcel.classfile.ConstantPackage; | |||||
import org.aspectj.apache.bcel.classfile.ConstantPool; | import org.aspectj.apache.bcel.classfile.ConstantPool; | ||||
import org.aspectj.apache.bcel.classfile.ConstantString; | import org.aspectj.apache.bcel.classfile.ConstantString; | ||||
import org.aspectj.apache.bcel.classfile.ConstantUtf8; | import org.aspectj.apache.bcel.classfile.ConstantUtf8; | ||||
import org.aspectj.apache.bcel.classfile.Method; | import org.aspectj.apache.bcel.classfile.Method; | ||||
import org.aspectj.apache.bcel.classfile.MethodParameters; | import org.aspectj.apache.bcel.classfile.MethodParameters; | ||||
import org.aspectj.apache.bcel.classfile.Module; | 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.Signature; | ||||
import org.aspectj.apache.bcel.classfile.SourceFile; | import org.aspectj.apache.bcel.classfile.SourceFile; | ||||
import org.aspectj.apache.bcel.classfile.StackMap; | import org.aspectj.apache.bcel.classfile.StackMap; | ||||
stack.pop(); | 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) { | public void visitConstantUtf8(ConstantUtf8 constant) { | ||||
stack.push(constant); | stack.push(constant); | ||||
constant.accept(visitor); | constant.accept(visitor); | ||||
attribute.accept(visitor); | attribute.accept(visitor); | ||||
stack.pop(); | 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(); | |||||
} | |||||
} | } |
import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; | import org.aspectj.apache.bcel.classfile.ConstantMethodHandle; | ||||
import org.aspectj.apache.bcel.classfile.ConstantMethodType; | import org.aspectj.apache.bcel.classfile.ConstantMethodType; | ||||
import org.aspectj.apache.bcel.classfile.ConstantMethodref; | 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.ConstantNameAndType; | ||||
import org.aspectj.apache.bcel.classfile.ConstantPackage; | |||||
import org.aspectj.apache.bcel.classfile.ConstantPool; | import org.aspectj.apache.bcel.classfile.ConstantPool; | ||||
import org.aspectj.apache.bcel.classfile.ConstantString; | import org.aspectj.apache.bcel.classfile.ConstantString; | ||||
import org.aspectj.apache.bcel.classfile.ConstantUtf8; | import org.aspectj.apache.bcel.classfile.ConstantUtf8; | ||||
import org.aspectj.apache.bcel.classfile.Method; | import org.aspectj.apache.bcel.classfile.Method; | ||||
import org.aspectj.apache.bcel.classfile.MethodParameters; | import org.aspectj.apache.bcel.classfile.MethodParameters; | ||||
import org.aspectj.apache.bcel.classfile.Module; | 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.Signature; | ||||
import org.aspectj.apache.bcel.classfile.SourceFile; | import org.aspectj.apache.bcel.classfile.SourceFile; | ||||
import org.aspectj.apache.bcel.classfile.StackMap; | import org.aspectj.apache.bcel.classfile.StackMap; | ||||
public void visitConstantNameAndType(ConstantNameAndType obj) {} | public void visitConstantNameAndType(ConstantNameAndType obj) {} | ||||
public void visitConstantPool(ConstantPool obj) {} | public void visitConstantPool(ConstantPool obj) {} | ||||
public void visitConstantString(ConstantString obj) {} | public void visitConstantString(ConstantString obj) {} | ||||
public void visitConstantModule(ConstantModule obj) {} | |||||
public void visitConstantPackage(ConstantPackage obj) {} | |||||
public void visitConstantUtf8(ConstantUtf8 obj) {} | public void visitConstantUtf8(ConstantUtf8 obj) {} | ||||
public void visitConstantValue(ConstantValue obj) {} | public void visitConstantValue(ConstantValue obj) {} | ||||
public void visitDeprecated(Deprecated obj) {} | public void visitDeprecated(Deprecated obj) {} | ||||
public void visitUnknown(Unknown obj) {} | public void visitUnknown(Unknown obj) {} | ||||
public void visitStackMap(StackMap obj) {} | public void visitStackMap(StackMap obj) {} | ||||
public void visitStackMapEntry(StackMapEntry obj) {} | public void visitStackMapEntry(StackMapEntry obj) {} | ||||
public void visitModule(Module obj) {} | |||||
// J5SUPPORT: | |||||
// J5: | |||||
public void visitEnclosingMethod(EnclosingMethod obj) {} | public void visitEnclosingMethod(EnclosingMethod obj) {} | ||||
public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos attribute) {} | public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos attribute) {} | ||||
public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos attribute) {} | public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos attribute) {} | ||||
public void visitAnnotationDefault(AnnotationDefault attribute) {} | public void visitAnnotationDefault(AnnotationDefault attribute) {} | ||||
public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {} | public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {} | ||||
// J8SUPPORT: | |||||
// J8: | |||||
public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) {} | public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) {} | ||||
public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) {} | public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) {} | ||||
public void visitMethodParameters(MethodParameters attribute) {} | public void visitMethodParameters(MethodParameters attribute) {} | ||||
// J9: | |||||
public void visitModule(Module attribute) {} | |||||
public void visitModulePackages(ModulePackages attribute) {} | |||||
public void visitModuleMainClass(ModuleMainClass attribute) {} | |||||
} | } |