123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- /* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2016-17 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;
-
- /**
- * 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
- */
- public final class Module extends Attribute {
-
- private static final String[] NO_MODULE_NAMES = {};
-
- 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;
-
- 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 moduleIndex;
- private final int flags;
- private final int versionIndex;
-
- public Require(int moduleIndex, int flags, int versionIndex) {
- this.moduleIndex = moduleIndex;
- this.flags = flags;
- this.versionIndex = versionIndex;
- }
-
- public String getModuleName() {
- return cpool.getModuleName(moduleIndex);
- }
-
- public int getFlags() {
- return flags;
- }
-
- public int getVersionIndex() {
- return versionIndex;
- }
-
- public String getVersionString() {
- if (versionIndex == 0) {
- return null;
- } else {
- return cpool.getConstantUtf8(versionIndex).getValue();
- }
- }
-
- public String getFlagsAsString() {
- StringBuilder s = new StringBuilder();
- if ((flags & Constants.MODULE_ACC_TRANSITIVE)!=0) {
- s.append(" transitive");
- }
- if ((flags & Constants.MODULE_ACC_STATIC_PHASE)!=0) {
- s.append(" static");
- }
- if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) {
- s.append(" synthetic");
- }
- if ((flags & Constants.MODULE_ACC_MANDATED)!=0) {
- s.append(" mandated");
- }
- return s.toString();
- }
-
- public String toString() {
- return "requires"+getFlagsAsString()+" "+getModuleName()+(versionIndex==0?"":" "+getVersionString());
- }
- }
-
-
- public class Export {
-
- private final int packageIndex;
- private final int flags;
- private final int[] toModuleIndices;
-
- public Export(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("exports").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 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[] withTypeIndices;
-
- public Provide(int providedTypeIndex, int[] withTypeIndices) {
- this.providedTypeIndex = providedTypeIndex;
- this.withTypeIndices = withTypeIndices;
- }
-
- public String getProvidedType() {
- return cpool.getConstantString_CONSTANTClass(providedTypeIndex);
- }
-
- public int getProvidedTypeIndex() {
- return providedTypeIndex;
- }
-
- 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[] getWithTypeIndices() {
- return withTypeIndices;
- }
-
- public String toString() {
- StringBuilder s =new StringBuilder();
- s.append("provides ").append(getProvidedType().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();
- }
- }
-
- public class Uses {
- private final int typeNameIndex;
-
- public Uses(int typeNameIndex) {
- this.typeNameIndex = typeNameIndex;
- }
-
- public String getTypeName() {
- return cpool.getConstantString_CONSTANTClass(typeNameIndex);
- }
-
- public int getTypeNameIndex() {
- return typeNameIndex;
- }
-
- public String toString() {
- StringBuilder s =new StringBuilder();
- s.append("uses ").append(getTypeName().replace('/', '.'));
- return s.toString().trim();
- }
- }
-
- private final int readInt() {
- return ((moduleInfo[ptr++] & 0xFF) << 24) + ((moduleInfo[ptr++] & 0xFF) << 16)
- + ((moduleInfo[ptr++] & 0xFF) << 8) + (moduleInfo[ptr++] & 0xFF);
- }
-
- private final int readUnsignedShort() {
- return ((moduleInfo[ptr++] & 0xff) << 8) + (moduleInfo[ptr++] & 0xff);
- }
-
- private final int readUnsignedShort(int offset) {
- 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(), 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, 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];
- for (int i = 0; i < count; i++) {
- uses[i] = new Uses(readUnsignedShort());
- }
- count = readUnsignedShort();
- provides = new Provide[count];
- for (int i = 0; i < count; i++) {
- 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;
- }
- }
-
- @Override
- public final void dump(DataOutputStream file) throws IOException {
- super.dump(file);
- if (!unpacked) {
- file.write(moduleInfo);
- } else {
-
- file.writeShort(moduleNameIndex);
- file.writeShort(moduleFlags);
- file.writeShort(moduleVersionIndex);
-
- file.writeShort(requires.length);
- for (Require require : requires) {
- file.writeShort(require.moduleIndex);
- file.writeShort(require.flags);
- file.writeShort(require.versionIndex);
- }
- file.writeShort(exports.length);
- for (Export export : exports) {
- 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);
- }
- }
- file.writeShort(uses.length);
- for (Uses use : uses) {
- file.writeShort(use.getTypeNameIndex());
- }
- file.writeShort(provides.length);
- for (Provide provide : provides) {
- file.writeShort(provide.providedTypeIndex);
- int[] toIndices = provide.withTypeIndices;
- file.writeShort(toIndices.length);
- for (int index : toIndices) {
- file.writeShort(index);
- }
- }
- }
- }
-
- public String toStringRequires() {
- StringBuilder s = new StringBuilder();
- s.append('#').append(requires.length);
- if (requires.length > 0) {
- for (Require require : requires) {
- s.append(' ');
- s.append(require.moduleIndex).append(':').append(require.flags);
- }
- }
- return s.toString();
- }
-
- public String toStringExports() {
- StringBuilder s = new StringBuilder();
- s.append('#').append(exports.length);
- if (exports.length > 0) {
- for (Export export : exports) {
- s.append(' ');
- 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(',');
- s.append(toIndices[i]);
- }
- s.append("]");
- }
- }
- return s.toString();
- }
-
- public String toStringUses() {
- StringBuilder s = new StringBuilder();
- s.append('#').append(uses.length);
- if (uses.length > 0) {
- for (Uses use : uses) {
- s.append(' ');
- s.append(use.getTypeName());
- }
- }
- return s.toString();
- }
-
- public String toStringProvides() {
- StringBuilder s = new StringBuilder();
- s.append('#').append(provides.length);
- if (provides.length > 0) {
- for (Provide provide : provides) {
- s.append(' ');
- 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();
- }
-
- @Override
- public final String toString() {
- StringBuilder s = new StringBuilder();
- ensureUnpacked();
- s.append("Module(");
- if (requires.length != 0) {
- s.append("requires=");
- s.append(toStringRequires());
- s.append(" ");
- }
- if (exports.length != 0) {
- s.append("exports=");
- 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());
- s.append(" ");
- }
- if (provides.length != 0) {
- s.append("provides=");
- s.append(toStringProvides());
- s.append(" ");
- }
- return s.toString().trim()+")";
- }
-
- /**
- * @return deep copy of this attribute //
- */
- // @Override
- // public Attribute copy(ConstantPool constant_pool) {
- // return (Module) clone();
- // }
-
- @Override
- public void accept(ClassVisitor v) {
- v.visitModule(this);
- }
-
- public Require[] getRequires() {
- ensureUnpacked();
- return requires;
- }
-
- public String[] getRequiredModuleNames() {
- ensureUnpacked();
- String[] results = new String[requires.length];
- for (int i=0;i<requires.length;i++) {
- results[i] = cpool.getModuleName(requires[i].moduleIndex);
- }
- return results;
- }
-
- public byte[] getBytes() {
- return moduleInfo;
- }
-
- public Export[] getExports() {
- ensureUnpacked();
- return exports;
- }
-
- public Open[] getOpens() {
- ensureUnpacked();
- return opens;
- }
-
- public Uses[] getUses() {
- ensureUnpacked();
- return uses;
- }
-
- public Provide[] getProvides() {
- 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();
- }
- }
- }
|