14 changed files with 847 additions and 105 deletions
@ -0,0 +1,178 @@
@@ -0,0 +1,178 @@
|
||||
/*** |
||||
* ASM: a very small and fast Java bytecode manipulation framework |
||||
* Copyright (c) 2000-2011 INRIA, France Telecom |
||||
* 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. Neither the name of the copyright holders nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. |
||||
*/ |
||||
|
||||
package org.springframework.asm; |
||||
|
||||
/** |
||||
* A visitor to visit a Java module. The methods of this class must be called in |
||||
* the following order: <tt>visitVersion</tt> | <tt>visitMainClass</tt> | |
||||
* <tt>visitTargetPlatform</tt> | ( <tt>visitConcealedPackage</tt> | <tt>visitRequire</tt> | |
||||
* <tt>visitExport</tt> | <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>. |
||||
* |
||||
* @author Remi Forax |
||||
*/ |
||||
public abstract class ModuleVisitor { |
||||
/** |
||||
* The ASM API version implemented by this visitor. The value of this field |
||||
* must be {@link Opcodes#ASM6}. |
||||
*/ |
||||
protected final int api; |
||||
|
||||
/** |
||||
* The module visitor to which this visitor must delegate method calls. May |
||||
* be null. |
||||
*/ |
||||
protected ModuleVisitor mv; |
||||
|
||||
|
||||
public ModuleVisitor(final int api) { |
||||
this(api, null); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a new {@link MethodVisitor}. |
||||
* |
||||
* @param api |
||||
* the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}. |
||||
* @param mv |
||||
* the method visitor to which this visitor must delegate method |
||||
* calls. May be null. |
||||
*/ |
||||
public ModuleVisitor(final int api, final ModuleVisitor mv) { |
||||
if (api != Opcodes.ASM6) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
this.api = api; |
||||
this.mv = mv; |
||||
} |
||||
|
||||
/** |
||||
* Visit the main class of the current module. |
||||
* |
||||
* @param mainClass the main class of the current module. |
||||
*/ |
||||
public void visitMainClass(String mainClass) { |
||||
if (mv != null) { |
||||
mv.visitMainClass(mainClass); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit a concealed package of the current module. |
||||
* |
||||
* @param packaze name of a concealed package
|
||||
*/ |
||||
public void visitPackage(String packaze) { |
||||
if (mv != null) { |
||||
mv.visitPackage(packaze); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visits a dependence of the current module. |
||||
* |
||||
* @param module the module name of the dependence |
||||
* @param access the access flag of the dependence among |
||||
* ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC |
||||
* and ACC_MANDATED. |
||||
* @param version the module version at compile time or null. |
||||
*/ |
||||
public void visitRequire(String module, int access, String version) { |
||||
if (mv != null) { |
||||
mv.visitRequire(module, access, version); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit an exported package of the current module. |
||||
* |
||||
* @param packaze the name of the exported package. |
||||
* @param access the access flag of the exported package, |
||||
* valid values are among {@code ACC_SYNTHETIC} and |
||||
* {@code ACC_MANDATED}. |
||||
* @param modules names of the modules that can access to |
||||
* the public classes of the exported package or |
||||
* <tt>null</tt>. |
||||
*/ |
||||
public void visitExport(String packaze, int access, String... modules) { |
||||
if (mv != null) { |
||||
mv.visitExport(packaze, access, modules); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit an open package of the current module. |
||||
* |
||||
* @param packaze the name of the opened package. |
||||
* @param access the access flag of the opened package, |
||||
* valid values are among {@code ACC_SYNTHETIC} and |
||||
* {@code ACC_MANDATED}. |
||||
* @param modules names of the modules that can use deep |
||||
* reflection to the classes of the open package or |
||||
* <tt>null</tt>. |
||||
*/ |
||||
public void visitOpen(String packaze, int access, String... modules) { |
||||
if (mv != null) { |
||||
mv.visitOpen(packaze, access, modules); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit a service used by the current module. |
||||
* The name must be the name of an interface or an |
||||
* abstract class. |
||||
* |
||||
* @param service the internal name of the service. |
||||
*/ |
||||
public void visitUse(String service) { |
||||
if (mv != null) { |
||||
mv.visitUse(service); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Visit an implementation of a service. |
||||
* |
||||
* @param service the internal name of the service |
||||
* @param providers the internal names of the implementations |
||||
* of the service (there is at least one provider). |
||||
*/ |
||||
public void visitProvide(String service, String... providers) { |
||||
if (mv != null) { |
||||
mv.visitProvide(service, providers); |
||||
} |
||||
} |
||||
|
||||
public void visitEnd() { |
||||
if (mv != null) { |
||||
mv.visitEnd(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,293 @@
@@ -0,0 +1,293 @@
|
||||
/*** |
||||
* ASM: a very small and fast Java bytecode manipulation framework |
||||
* Copyright (c) 2000-2011 INRIA, France Telecom |
||||
* 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. Neither the name of the copyright holders nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. |
||||
*/ |
||||
|
||||
package org.springframework.asm; |
||||
|
||||
/** |
||||
* @author Remi Forax |
||||
*/ |
||||
final class ModuleWriter extends ModuleVisitor { |
||||
/** |
||||
* The class writer to which this Module attribute must be added. |
||||
*/ |
||||
private final ClassWriter cw; |
||||
|
||||
/** |
||||
* size in byte of the Module attribute. |
||||
*/ |
||||
int size; |
||||
|
||||
/** |
||||
* Number of attributes associated with the current module |
||||
* (Version, ConcealPackages, etc) |
||||
*/ |
||||
int attributeCount; |
||||
|
||||
/** |
||||
* Size in bytes of the attributes associated with the current module |
||||
*/ |
||||
int attributesSize; |
||||
|
||||
/** |
||||
* module name index in the constant pool |
||||
*/ |
||||
private final int name; |
||||
|
||||
/** |
||||
* module access flags |
||||
*/ |
||||
private final int access; |
||||
|
||||
/** |
||||
* module version index in the constant pool or 0 |
||||
*/ |
||||
private final int version; |
||||
|
||||
/** |
||||
* module main class index in the constant pool or 0 |
||||
*/ |
||||
private int mainClass; |
||||
|
||||
/** |
||||
* number of packages |
||||
*/ |
||||
private int packageCount; |
||||
|
||||
/** |
||||
* The packages in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in packageCount |
||||
*/ |
||||
private ByteVector packages; |
||||
|
||||
/** |
||||
* number of requires items |
||||
*/ |
||||
private int requireCount; |
||||
|
||||
/** |
||||
* The requires items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in requireCount |
||||
*/ |
||||
private ByteVector requires; |
||||
|
||||
/** |
||||
* number of exports items |
||||
*/ |
||||
private int exportCount; |
||||
|
||||
/** |
||||
* The exports items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in exportCount |
||||
*/ |
||||
private ByteVector exports; |
||||
|
||||
/** |
||||
* number of opens items |
||||
*/ |
||||
private int openCount; |
||||
|
||||
/** |
||||
* The opens items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in openCount |
||||
*/ |
||||
private ByteVector opens; |
||||
|
||||
/** |
||||
* number of uses items |
||||
*/ |
||||
private int useCount; |
||||
|
||||
/** |
||||
* The uses items in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in useCount |
||||
*/ |
||||
private ByteVector uses; |
||||
|
||||
/** |
||||
* number of provides items |
||||
*/ |
||||
private int provideCount; |
||||
|
||||
/** |
||||
* The uses provides in bytecode form. This byte vector only contains |
||||
* the items themselves, the number of items is store in provideCount |
||||
*/ |
||||
private ByteVector provides; |
||||
|
||||
ModuleWriter(final ClassWriter cw, final int name, |
||||
final int access, final int version) { |
||||
super(Opcodes.ASM6); |
||||
this.cw = cw; |
||||
this.size = 16; // name + access + version + 5 counts
|
||||
this.name = name; |
||||
this.access = access; |
||||
this.version = version; |
||||
} |
||||
|
||||
@Override |
||||
public void visitMainClass(String mainClass) { |
||||
if (this.mainClass == 0) { // protect against several calls to visitMainClass
|
||||
cw.newUTF8("ModuleMainClass"); |
||||
attributeCount++; |
||||
attributesSize += 8; |
||||
} |
||||
this.mainClass = cw.newClass(mainClass); |
||||
} |
||||
|
||||
@Override |
||||
public void visitPackage(String packaze) { |
||||
if (packages == null) { |
||||
// protect against several calls to visitPackage
|
||||
cw.newUTF8("ModulePackages"); |
||||
packages = new ByteVector(); |
||||
attributeCount++; |
||||
attributesSize += 8; |
||||
} |
||||
packages.putShort(cw.newPackage(packaze)); |
||||
packageCount++; |
||||
attributesSize += 2; |
||||
} |
||||
|
||||
@Override |
||||
public void visitRequire(String module, int access, String version) { |
||||
if (requires == null) { |
||||
requires = new ByteVector(); |
||||
} |
||||
requires.putShort(cw.newModule(module)) |
||||
.putShort(access) |
||||
.putShort(version == null? 0: cw.newUTF8(version)); |
||||
requireCount++; |
||||
size += 6; |
||||
} |
||||
|
||||
@Override |
||||
public void visitExport(String packaze, int access, String... modules) { |
||||
if (exports == null) { |
||||
exports = new ByteVector(); |
||||
} |
||||
exports.putShort(cw.newPackage(packaze)).putShort(access); |
||||
if (modules == null) { |
||||
exports.putShort(0); |
||||
size += 6; |
||||
} else { |
||||
exports.putShort(modules.length); |
||||
for(String module: modules) { |
||||
exports.putShort(cw.newModule(module)); |
||||
} |
||||
size += 6 + 2 * modules.length; |
||||
} |
||||
exportCount++; |
||||
} |
||||
|
||||
@Override |
||||
public void visitOpen(String packaze, int access, String... modules) { |
||||
if (opens == null) { |
||||
opens = new ByteVector(); |
||||
} |
||||
opens.putShort(cw.newPackage(packaze)).putShort(access); |
||||
if (modules == null) { |
||||
opens.putShort(0); |
||||
size += 6; |
||||
} else { |
||||
opens.putShort(modules.length); |
||||
for(String module: modules) { |
||||
opens.putShort(cw.newModule(module)); |
||||
} |
||||
size += 6 + 2 * modules.length; |
||||
} |
||||
openCount++; |
||||
} |
||||
|
||||
@Override |
||||
public void visitUse(String service) { |
||||
if (uses == null) { |
||||
uses = new ByteVector(); |
||||
} |
||||
uses.putShort(cw.newClass(service)); |
||||
useCount++; |
||||
size += 2; |
||||
} |
||||
|
||||
@Override |
||||
public void visitProvide(String service, String... providers) { |
||||
if (provides == null) { |
||||
provides = new ByteVector(); |
||||
} |
||||
provides.putShort(cw.newClass(service)); |
||||
provides.putShort(providers.length); |
||||
for(String provider: providers) { |
||||
provides.putShort(cw.newClass(provider)); |
||||
} |
||||
provideCount++; |
||||
size += 4 + 2 * providers.length; |
||||
} |
||||
|
||||
@Override |
||||
public void visitEnd() { |
||||
// empty
|
||||
} |
||||
|
||||
void putAttributes(ByteVector out) { |
||||
if (mainClass != 0) { |
||||
out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass); |
||||
} |
||||
if (packages != null) { |
||||
out.putShort(cw.newUTF8("ModulePackages")) |
||||
.putInt(2 + 2 * packageCount) |
||||
.putShort(packageCount) |
||||
.putByteArray(packages.data, 0, packages.length); |
||||
} |
||||
} |
||||
|
||||
void put(ByteVector out) { |
||||
out.putInt(size); |
||||
out.putShort(name).putShort(access).putShort(version); |
||||
out.putShort(requireCount); |
||||
if (requires != null) { |
||||
out.putByteArray(requires.data, 0, requires.length); |
||||
} |
||||
out.putShort(exportCount); |
||||
if (exports != null) { |
||||
out.putByteArray(exports.data, 0, exports.length); |
||||
} |
||||
out.putShort(openCount); |
||||
if (opens != null) { |
||||
out.putByteArray(opens.data, 0, opens.length); |
||||
} |
||||
out.putShort(useCount); |
||||
if (uses != null) { |
||||
out.putByteArray(uses.data, 0, uses.length); |
||||
} |
||||
out.putShort(provideCount); |
||||
if (provides != null) { |
||||
out.putByteArray(provides.data, 0, provides.length); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue