diff options
-rw-r--r-- | .classpath | 1 | ||||
-rw-r--r-- | src/java/lombok/ClassLoaderWorkaround.java | 74 | ||||
-rw-r--r-- | src/lombok/agent/eclipse/EclipseParserTransformer.java | 83 | ||||
-rw-r--r-- | src/lombok/agent/eclipse/TransformCompilationUnitDeclaration.java | 22 | ||||
-rw-r--r-- | src/lombok/eclipse/HandleGetter_ecj.java (renamed from src/lombok/agent/eclipse/HandleGetter_ecj.java) | 9 | ||||
-rw-r--r-- | src/lombok/eclipse/TransformEclipseAST.java | 60 | ||||
-rw-r--r-- | src_eclipseagent/java/lombok/ClassLoaderWorkaround.java | 104 | ||||
-rw-r--r-- | src_eclipseagent/lombok/agent/eclipse/EclipseParserPatcher.java (renamed from src/lombok/agent/eclipse/EclipseParserPatcher.java) | 0 | ||||
-rw-r--r-- | src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java | 157 |
9 files changed, 329 insertions, 181 deletions
@@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="src_eclipseagent"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="lib" path="lib/asm-3.1.jar" sourcepath="contrib/asm-3.1-src.zip"> <attributes> diff --git a/src/java/lombok/ClassLoaderWorkaround.java b/src/java/lombok/ClassLoaderWorkaround.java deleted file mode 100644 index c533424d..00000000 --- a/src/java/lombok/ClassLoaderWorkaround.java +++ /dev/null @@ -1,74 +0,0 @@ -package java.lombok; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; - -/** - * Allows you to load a class off of any place that is injected into a class loader (which doesn't know how to load the class you're injecting). - * - * Example: Injecting lombok's Eclipse Parser patching code into eclipse's OSGi BundleLoader. - * - * @author rzwitserloot - */ -public class ClassLoaderWorkaround { - private static boolean initialized; - private static Method m; - - public static void transformCompilationUnitDeclaration(Object cud) throws Exception { - if ( !initialized ) initialize(cud); - if ( m == null ) throw new ClassNotFoundException("lombok.agent.eclipse.TransformCompilationUnitDeclaration"); - m.invoke(null, cud); - } - - private static void initialize(Object cud) { - final ClassLoader parent = cud.getClass().getClassLoader(); - ClassLoader loader = new ClassLoader() { - @Override public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - if ( name.startsWith("lombok.") ) { - InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/") + ".class"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - byte[] b = new byte[65536]; - try { - while ( true ) { - int r = in.read(b); - if ( r == -1 ) break; - if ( r > 0 ) out.write(b, 0, r); - } - - in.close(); - byte[] data = out.toByteArray(); - Class<?> result = defineClass(name, data, 0, data.length); - if ( resolve ) resolveClass(result); - return result; - } catch ( IOException e ) { - throw new ClassNotFoundException(); - } - } else { - try { - Class<?> result = ClassLoader.getSystemClassLoader().loadClass(name); - if ( resolve ) resolveClass(result); - return result; - } catch ( ClassNotFoundException e ) { - Class<?> result = parent.loadClass(name); - if ( resolve ) resolveClass(result); - return result; - } - } - } - }; - - try { - Class<?> c = loader.loadClass("lombok.agent.eclipse.TransformCompilationUnitDeclaration"); - for ( Method m : c.getMethods() ) { - if ( m.getName().equals("transform") ) { - ClassLoaderWorkaround.m = m; - break; - } - } - } catch ( ClassNotFoundException ignore ) {} - initialized = true; - } -} diff --git a/src/lombok/agent/eclipse/EclipseParserTransformer.java b/src/lombok/agent/eclipse/EclipseParserTransformer.java deleted file mode 100644 index fa549ff8..00000000 --- a/src/lombok/agent/eclipse/EclipseParserTransformer.java +++ /dev/null @@ -1,83 +0,0 @@ -package lombok.agent.eclipse; - -import org.objectweb.asm.ClassAdapter; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.MethodAdapter; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -class EclipseParserTransformer { - private static final String COMPILATION_UNIT_DECLARATION_SIG = - "Lorg/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration;"; - - private static final String TOPATCH_METHOD_NAME = "endParse"; - private static final String TOPATCH_METHOD_DESC = "(I)" + COMPILATION_UNIT_DECLARATION_SIG; - - private final byte[] in; - - EclipseParserTransformer(byte[] classfileBuffer) { - in = classfileBuffer; - } - - byte[] transform() { - ClassReader reader = new ClassReader(in); - ClassWriter writer = new ClassWriter(reader, 0); - ClassAdapter adapter = new ParserPatcherAdapter(writer); - reader.accept(adapter, 0); - return writer.toByteArray(); - } - - private static class ParserPatcherAdapter extends ClassAdapter { - public ParserPatcherAdapter(ClassVisitor cv) { - super(cv); - } - - @Override public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - MethodVisitor writerVisitor = super.visitMethod(access, name, desc, signature, exceptions); - if ( !TOPATCH_METHOD_NAME.equals(name) || !TOPATCH_METHOD_DESC.equals(desc) ) return writerVisitor; - - return new PatcherMethodVisitor(writerVisitor); - } - } - - static class PatcherMethodVisitor extends MethodAdapter { - private static final String TARGET_STATIC_CLASS = "java/lombok/ClassLoaderWorkaround"; - private static final String TARGET_STATIC_METHOD_NAME = "transformCompilationUnitDeclaration"; - private static final String TARGET_STATIC_METHOD_DESC = "(Ljava/lang/Object;)V"; - - private boolean alreadyCalled = false; - - PatcherMethodVisitor(MethodVisitor mv) { - super(mv); - } - - @Override public void visitInsn(int opcode) { - if ( opcode == Opcodes.ARETURN ) insertHookCall(); - - super.visitInsn(opcode); - } - - @Override public void visitMethodInsn(int opcode, String owner, String name, - String desc) { - if ( opcode == Opcodes.INVOKESTATIC && - TARGET_STATIC_CLASS.equals(owner) && TARGET_STATIC_METHOD_NAME.equals(name) ) alreadyCalled = true; - super.visitMethodInsn(opcode, owner, name, desc); - } - - /** When this method is called, the stack should hold the reference to the - * just-parsed CompilationUnitDeclaration object that is about to be returned - * to whomever wants it. We will put a call to a method of our choosing in, - * which will transform the CUD. The stack is not modified (that is, that method - * returns a CUD). - */ - private void insertHookCall() { - if ( alreadyCalled ) return; - super.visitInsn(Opcodes.DUP); - super.visitMethodInsn(Opcodes.INVOKESTATIC, TARGET_STATIC_CLASS, - TARGET_STATIC_METHOD_NAME, TARGET_STATIC_METHOD_DESC); - } - } -} diff --git a/src/lombok/agent/eclipse/TransformCompilationUnitDeclaration.java b/src/lombok/agent/eclipse/TransformCompilationUnitDeclaration.java deleted file mode 100644 index 7c29a795..00000000 --- a/src/lombok/agent/eclipse/TransformCompilationUnitDeclaration.java +++ /dev/null @@ -1,22 +0,0 @@ -package lombok.agent.eclipse; - -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; - -public class TransformCompilationUnitDeclaration { - /** This is a 'magic' method signature - it is this one that will be called. Don't rename anything! */ - - public static void transform(CompilationUnitDeclaration ast) { - if ( ast.types != null ) for ( TypeDeclaration type : ast.types ) { - if ( type.fields != null ) for ( FieldDeclaration field : type.fields ) { - if ( field.annotations != null ) for ( Annotation annotation : field.annotations ) { - if ( annotation.type.toString().equals("Getter") ) { - new HandleGetter_ecj().apply(type, field); - } - } - } - } - } -} diff --git a/src/lombok/agent/eclipse/HandleGetter_ecj.java b/src/lombok/eclipse/HandleGetter_ecj.java index d43bbbc4..f71376a3 100644 --- a/src/lombok/agent/eclipse/HandleGetter_ecj.java +++ b/src/lombok/eclipse/HandleGetter_ecj.java @@ -1,10 +1,12 @@ -package lombok.agent.eclipse; +package lombok.eclipse; import java.lang.reflect.Modifier; import lombok.transformations.TransformationsUtil; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; @@ -16,7 +18,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; public class HandleGetter_ecj { - public void apply(TypeDeclaration type, FieldDeclaration field) { + public void apply(Annotation annotation, TypeDeclaration type, FieldDeclaration field) { TypeReference fieldType = field.type; String getterName = TransformationsUtil.toGetterName(new String(field.name), nameEquals(fieldType.getTypeName(), "boolean")); @@ -34,8 +36,11 @@ public class HandleGetter_ecj { method.thrownExceptions = null; method.typeParameters = null; method.scope = new MethodScope(type.scope, method, false); + method.bits |= ASTNode.Bit24; Expression fieldExpression = new SingleNameReference(field.name, (field.declarationSourceStart << 32) | field.declarationSourceEnd); Statement returnStatement = new ReturnStatement(fieldExpression, field.sourceStart, field.sourceEnd); + method.bodyStart = method.declarationSourceStart = method.sourceStart = annotation.sourceStart; + method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = annotation.sourceEnd; method.statements = new Statement[] { returnStatement }; AbstractMethodDeclaration[] newArray = new AbstractMethodDeclaration[type.methods.length + 1]; System.arraycopy(type.methods, 0, newArray, 0, type.methods.length); diff --git a/src/lombok/eclipse/TransformEclipseAST.java b/src/lombok/eclipse/TransformEclipseAST.java new file mode 100644 index 00000000..9212a0d4 --- /dev/null +++ b/src/lombok/eclipse/TransformEclipseAST.java @@ -0,0 +1,60 @@ +package lombok.eclipse; + +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; +import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; +import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.Initializer; +import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.parser.Parser; + +/** + * Entry point for the Eclipse Parser patch that lets lombok modify the Abstract Syntax Tree as generated by + * eclipse's parser implementations. This class is injected into the appropriate OSGi ClassLoader and can thus + * use any classes that belong to org.eclipse.jdt.(apt.)core. + * + * Note that, for any Method body, if Bit24 is set, the eclipse parser has been patched to never attempt to + * (re)parse it. You should set Bit24 on any MethodDeclaration object you inject into the AST: + * + * <code>methodDeclaration.bits |= 0x80000;</code> + * + * @author rzwitserloot + * @author rspilker + */ +public class TransformEclipseAST { + /** + * This method is called immediately after eclipse finishes building a CompilationUnitDeclaration, which is + * the top-level AST node when eclipse parses a source file. The signature is 'magic' - you should not + * change it! + * + * Eclipse's parsers often operate in diet mode, which means many parts of the AST have been left blank. + * Be ready to deal with just about anything being null, such as the Statement[] arrays of the Method AST nodes. + * + * @param parser The eclipse parser object that generated the AST. + * @param ast The AST node belonging to the compilation unit (java speak for a single source file). + */ + public static void transform(Parser parser, CompilationUnitDeclaration ast) { + if ( ast.types != null ) for ( TypeDeclaration type : ast.types ) { + if ( type.fields != null ) for ( FieldDeclaration field : type.fields ) { + if ( field.annotations != null ) for ( Annotation annotation : field.annotations ) { + if ( annotation.type.toString().equals("Getter") ) { + new HandleGetter_ecj().apply(annotation, type, field); + } + } + } + } + } + + public static void transform(Parser parser, MethodDeclaration ast) { + + } + + public static void transform(Parser parser, ConstructorDeclaration ast) { + + } + + public static void transform(Parser parser, Initializer ast) { + + } +} diff --git a/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java b/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java new file mode 100644 index 00000000..0238b592 --- /dev/null +++ b/src_eclipseagent/java/lombok/ClassLoaderWorkaround.java @@ -0,0 +1,104 @@ +package java.lombok; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; + +/** + * Allows you to inject the lombok classes into any classloader, even if that classloader does not + * know how to find the lombok classes. + * + * Example: Injecting lombok's Eclipse Parser patching code into eclipse's OSGi BundleLoader. + * + * @author rzwitserloot + */ +public class ClassLoaderWorkaround { + private static boolean initialized; + private static Method transformCompilationUnitDeclaration; + private static Method transformMethodDeclaration; + private static Method transformConstructorDeclaration; + private static Method transformInitializer; + + public static void transformCompilationUnitDeclaration(Object parser, Object cud) throws Exception { + initialize(cud); + transformCompilationUnitDeclaration.invoke(null, parser, cud); + } + + public static void transformMethodDeclaration(Object parser, Object methodDeclaration) throws Exception { + initialize(methodDeclaration); + transformMethodDeclaration.invoke(null, parser, methodDeclaration); + } + + public static void transformConstructorDeclaration(Object parser, Object constructorDeclaration) throws Exception { + initialize(constructorDeclaration); + transformConstructorDeclaration.invoke(null, parser, constructorDeclaration); + } + + public static void transformInitializer(Object parser, Object initializer) throws Exception { + initialize(initializer); + transformInitializer.invoke(null, parser, initializer); + } + + private static void initialize(Object cud) throws ClassNotFoundException { + if ( initialized ) { + if ( transformInitializer == null ) throw new ClassNotFoundException("lombok.eclipse.TransformEclipseAST"); + return; + } + + final ClassLoader parent = cud.getClass().getClassLoader(); + ClassLoader loader = new ClassLoader() { + @Override public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + if ( name.startsWith("lombok.") ) { + InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/") + ".class"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + byte[] b = new byte[65536]; + try { + while ( true ) { + int r = in.read(b); + if ( r == -1 ) break; + if ( r > 0 ) out.write(b, 0, r); + } + + in.close(); + byte[] data = out.toByteArray(); + Class<?> result = defineClass(name, data, 0, data.length); + if ( resolve ) resolveClass(result); + return result; + } catch ( IOException e ) { + throw new ClassNotFoundException(); + } + } else { + try { + Class<?> result = ClassLoader.getSystemClassLoader().loadClass(name); + if ( resolve ) resolveClass(result); + return result; + } catch ( ClassNotFoundException e ) { + Class<?> result = parent.loadClass(name); + if ( resolve ) resolveClass(result); + return result; + } + } + } + }; + + try { + Class<?> c = loader.loadClass("lombok.eclipse.TransformEclipseAST"); + for ( Method m : c.getMethods() ) { + if ( m.getName().equals("transform") ) { + if ( m.getParameterTypes().length >= 2 ) { + Class<?> astType = m.getParameterTypes()[1]; + String astName = astType.getName(); + astName = astName.substring(astName.lastIndexOf('.') + 1); + if ( astName.equals("CompilationUnitDeclaration") ) transformCompilationUnitDeclaration = m; + else if ( astName.equals("MethodDeclaration") ) transformMethodDeclaration = m; + else if ( astName.equals("ConstructorDeclaration") ) transformConstructorDeclaration = m; + else if ( astName.equals("Initializer") ) transformInitializer = m; + } + } + } + } catch ( ClassNotFoundException ignore ) {} + initialized = true; + } +} diff --git a/src/lombok/agent/eclipse/EclipseParserPatcher.java b/src_eclipseagent/lombok/agent/eclipse/EclipseParserPatcher.java index abe26683..abe26683 100644 --- a/src/lombok/agent/eclipse/EclipseParserPatcher.java +++ b/src_eclipseagent/lombok/agent/eclipse/EclipseParserPatcher.java diff --git a/src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java b/src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java new file mode 100644 index 00000000..803d5d66 --- /dev/null +++ b/src_eclipseagent/lombok/agent/eclipse/EclipseParserTransformer.java @@ -0,0 +1,157 @@ +package lombok.agent.eclipse; + +import java.lang.reflect.Constructor; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.objectweb.asm.ClassAdapter; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodAdapter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +class EclipseParserTransformer { + private static final String COMPILER_PKG = + "Lorg/eclipse/jdt/internal/compiler/ast/"; + private static final String TARGET_STATIC_CLASS = "java/lombok/ClassLoaderWorkaround"; + private static final String TARGET_STATIC_METHOD_DESC = "(Ljava/lang/Object;Ljava/lang/Object;)V"; + + private static final Map<String, Class<? extends MethodVisitor>> rewriters; + + static { + Map<String, Class<? extends MethodVisitor>> map = new HashMap<String, Class<? extends MethodVisitor>>(); + map.put(String.format("endParse(I)%sCompilationUnitDeclaration;", COMPILER_PKG), EndParsePatcher.class); + map.put(String.format("parse(%1$sMethodDeclaration;%1$sCompilationUnitDeclaration;)V", COMPILER_PKG), ParseMethodPatcher.class); + map.put(String.format("parse(%1$sConstructorDeclaration;%1$sCompilationUnitDeclaration;Z)V", COMPILER_PKG), ParseConstructorPatcher.class); + map.put(String.format("parse(%1$sInitializer;%1$sTypeDeclaration;%1$sCompilationUnitDeclaration;)V", COMPILER_PKG), ParseInitializerPatcher.class); + rewriters = Collections.unmodifiableMap(map); + } + + private final byte[] in; + + EclipseParserTransformer(byte[] classfileBuffer) { + in = classfileBuffer; + } + + byte[] transform() { + ClassReader reader = new ClassReader(in); + ClassWriter writer = new ClassWriter(reader, 0); + ClassAdapter adapter = new ParserPatcherAdapter(writer); + reader.accept(adapter, 0); + return writer.toByteArray(); + } + + public static RuntimeException sneakyThrow(Throwable t) { + if ( t == null ) throw new NullPointerException("t"); + EclipseParserTransformer.<RuntimeException>sneakyThrow0(t); + return null; + } + + @SuppressWarnings("unchecked") + private static <T extends Throwable> void sneakyThrow0(Throwable t) throws T { + throw (T)t; + } + + private static class ParserPatcherAdapter extends ClassAdapter { + public ParserPatcherAdapter(ClassVisitor cv) { + super(cv); + } + + @Override public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + MethodVisitor writerVisitor = super.visitMethod(access, name, desc, signature, exceptions); + Class<? extends MethodVisitor> targetVisitorClass = rewriters.get(name+desc); + if ( targetVisitorClass == null ) return writerVisitor; + + try { + Constructor<? extends MethodVisitor> c = targetVisitorClass.getDeclaredConstructor(MethodVisitor.class); + c.setAccessible(true); + return c.newInstance(writerVisitor); + } catch ( Exception e ) { + //NoSuchMethodException: We know they exist. + //InvocationTargetException: No checked exceptions thrown by any compilers. + //IllegalAccessException: We called setAccessible. + //InstantiationException: None of these classes are abstract. + throw sneakyThrow(e); + } + } + } + + private static final int BIT24 = 0x800000; + + static class ParseBlockContainerPatcher extends MethodAdapter { + private final String staticMethodName; + + ParseBlockContainerPatcher(MethodVisitor mv, String staticMethodName) { + super(mv); + this.staticMethodName = staticMethodName; + } + + @Override public void visitCode() { + //injects: if ( constructorDeclaration.bits & BIT24 > 0 ) return; + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitFieldInsn(Opcodes.GETFIELD, "org/eclipse/jdt/internal/compiler/ast/ASTNode", "bits", "I"); + mv.visitLdcInsn(Integer.valueOf(BIT24)); + mv.visitInsn(Opcodes.IAND); + Label l0 = new Label(); + mv.visitJumpInsn(Opcodes.IFLE, l0); + mv.visitInsn(Opcodes.RETURN); + mv.visitLabel(l0); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + super.visitCode(); + } + + @Override public void visitInsn(int opcode) { + if ( opcode == Opcodes.RETURN ) { + //injects: ClassLoaderWorkaround.transformConstructorDeclaration(parser, constructorDeclaration); + super.visitVarInsn(Opcodes.ALOAD, 0); + super.visitVarInsn(Opcodes.ALOAD, 1); + super.visitMethodInsn(Opcodes.INVOKESTATIC, TARGET_STATIC_CLASS, + staticMethodName, TARGET_STATIC_METHOD_DESC); + } + } + } + + static class ParseConstructorPatcher extends ParseBlockContainerPatcher { + public ParseConstructorPatcher(MethodVisitor mv) { + super(mv, "transformConstructorDeclaration"); + } + } + + static class ParseMethodPatcher extends ParseBlockContainerPatcher { + public ParseMethodPatcher(MethodVisitor mv) { + super(mv, "transformMethodDeclaration"); + } + } + + static class ParseInitializerPatcher extends ParseBlockContainerPatcher { + public ParseInitializerPatcher(MethodVisitor mv) { + super(mv, "transformInitializer"); + } + } + + static class EndParsePatcher extends MethodAdapter { + private static final String TARGET_STATIC_METHOD_NAME = "transformCompilationUnitDeclaration"; + + EndParsePatcher(MethodVisitor mv) { + super(mv); + } + + @Override public void visitInsn(int opcode) { + if ( opcode == Opcodes.ARETURN ) { + //injects: ClassLoaderWorkaround.transformCUD(parser, compilationUnitDeclaration); + super.visitInsn(Opcodes.DUP); + super.visitVarInsn(Opcodes.ALOAD, 0); + super.visitInsn(Opcodes.SWAP); + super.visitMethodInsn(Opcodes.INVOKESTATIC, TARGET_STATIC_CLASS, + TARGET_STATIC_METHOD_NAME, TARGET_STATIC_METHOD_DESC); + } + + super.visitInsn(opcode); + } + } +} |