14 changed files with 847 additions and 105 deletions
@ -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 @@ |
|||||||
|
/*** |
||||||
|
* 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