ASM4 实现:
/** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xbean.recipe; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import java.util.Arrays; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; import org.objectweb.asm.commons.EmptyVisitor; /** * Implementation of ParameterNameLoader that uses ASM to read the parameter names from the local variable table in the * class byte code. * * This wonderful piece of code was taken from org.springframework.core.LocalVariableTableParameterNameDiscover */ public class AsmParameterNameLoader implements ParameterNameLoader { /** * Weak map from Constructor to List<String>. */ private final WeakHashMap<Constructor,List<String>> constructorCache = new WeakHashMap<Constructor,List<String>>(); /** * Weak map from Method to List<String>. */ private final WeakHashMap<Method,List<String>> methodCache = new WeakHashMap<Method,List<String>>(); /** * Gets the parameter names of the specified method or null if the class was compiled without debug symbols on. * @param method the method for which the parameter names should be retrieved * @return the parameter names or null if the class was compilesd without debug symbols on */ public List<String> get(Method method) { // check the cache if (methodCache.containsKey(method)) { return methodCache.get(method); } Map<Method,List<String>> allMethodParameters = getAllMethodParameters(method.getDeclaringClass(), method.getName()); return allMethodParameters.get(method); } /** * Gets the parameter names of the specified constructor or null if the class was compiled without debug symbols on. * @param constructor the constructor for which the parameters should be retrieved * @return the parameter names or null if the class was compiled without debug symbols on */ public List<String> get(Constructor constructor) { // check the cache if (constructorCache.containsKey(constructor)) { return constructorCache.get(constructor); } Map<Constructor,List<String>> allConstructorParameters = getAllConstructorParameters(constructor.getDeclaringClass()); return allConstructorParameters.get(constructor); } /** * Gets the parameter names of all constructor or null if the class was compiled without debug symbols on. * @param clazz the class for which the constructor parameter names should be retrieved * @return a map from Constructor object to the parameter names or null if the class was compiled without debug symbols on */ public Map<Constructor,List<String>> getAllConstructorParameters(Class clazz) { // Determine the constructors? List<Constructor> constructors = new ArrayList<Constructor>(Arrays.asList(clazz.getConstructors())); constructors.addAll(Arrays.asList(clazz.getDeclaredConstructors())); if (constructors.isEmpty()) { return Collections.emptyMap(); } // Check the cache if (constructorCache.containsKey(constructors.get(0))) { Map<Constructor,List<String>> constructorParameters = new HashMap<Constructor,List<String>>(); for (Constructor constructor : constructors) { constructorParameters.put(constructor, constructorCache.get(constructor)); } return constructorParameters; } // Load the parameter names using ASM Map<Constructor,List<String>> constructorParameters = new HashMap<Constructor,List<String>> (); try { ClassReader reader = AsmParameterNameLoader.createClassReader(clazz); AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor visitor = new AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor(clazz); reader.accept(visitor, 0); Map exceptions = visitor.getExceptions(); if (exceptions.size() == 1) { throw new RuntimeException((Exception)exceptions.values().iterator().next()); } if (!exceptions.isEmpty()) { throw new RuntimeException(exceptions.toString()); } constructorParameters = visitor.getConstructorParameters(); } catch (IOException ex) { } // Cache the names for (Constructor constructor : constructors) { constructorCache.put(constructor, constructorParameters.get(constructor)); } return constructorParameters; } /** * Gets the parameter names of all methods with the specified name or null if the class was compiled without debug symbols on. * @param clazz the class for which the method parameter names should be retrieved * @param methodName the of the method for which the parameters should be retrieved * @return a map from Method object to the parameter names or null if the class was compiled without debug symbols on */ public Map<Method,List<String>> getAllMethodParameters(Class clazz, String methodName) { // Determine the constructors? Method[] methods = getMethods(clazz, methodName); if (methods.length == 0) { return Collections.emptyMap(); } // Check the cache if (methodCache.containsKey(methods[0])) { Map<Method,List<String>> methodParameters = new HashMap<Method,List<String>>(); for (Method method : methods) { methodParameters.put(method, methodCache.get(method)); } return methodParameters; } // Load the parameter names using ASM Map<Method,List<String>> methodParameters = new HashMap<Method,List<String>>(); try { ClassReader reader = AsmParameterNameLoader.createClassReader(clazz); AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor visitor = new AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor(clazz, methodName); reader.accept(visitor, 0); Map exceptions = visitor.getExceptions(); if (exceptions.size() == 1) { throw new RuntimeException((Exception)exceptions.values().iterator().next()); } if (!exceptions.isEmpty()) { throw new RuntimeException(exceptions.toString()); } methodParameters = visitor.getMethodParameters(); } catch (IOException ex) { } // Cache the names for (Method method : methods) { methodCache.put(method, methodParameters.get(method)); } return methodParameters; } private Method[] getMethods(Class clazz, String methodName) { List<Method> methods = new ArrayList<Method>(Arrays.asList(clazz.getMethods())); methods.addAll(Arrays.asList(clazz.getDeclaredMethods())); List<Method> matchingMethod = new ArrayList<Method>(methods.size()); for (Method method : methods) { if (method.getName().equals(methodName)) { matchingMethod.add(method); } } return matchingMethod.toArray(new Method[matchingMethod.size()]); } private static ClassReader createClassReader(Class declaringClass) throws IOException { InputStream in = null; try { ClassLoader classLoader = declaringClass.getClassLoader(); in = classLoader.getResourceAsStream(declaringClass.getName().replace('.', '/') + ".class"); ClassReader reader = new ClassReader(in); return reader; } finally { if (in != null) { try { in.close(); } catch (IOException ignored) { } } } } private static class AllParameterNamesDiscoveringVisitor extends EmptyVisitor { private final Map<Constructor,List<String>> constructorParameters = new HashMap<Constructor,List<String>>(); private final Map<Method,List<String>> methodParameters = new HashMap<Method,List<String>>(); private final Map<String,Exception> exceptions = new HashMap<String,Exception>(); private final String methodName; private final Map<String,Method> methodMap = new HashMap<String,Method>(); private final Map<String,Constructor> constructorMap = new HashMap<String,Constructor>(); public AllParameterNamesDiscoveringVisitor(Class type, String methodName) { this.methodName = methodName; List<Method> methods = new ArrayList<Method>(Arrays.asList(type.getMethods())); methods.addAll(Arrays.asList(type.getDeclaredMethods())); for (Method method : methods) { if (method.getName().equals(methodName)) { methodMap.put(Type.getMethodDescriptor(method), method); } } } public AllParameterNamesDiscoveringVisitor(Class type) { this.methodName = "<init>"; List<Constructor> constructors = new ArrayList<Constructor>(Arrays.asList(type.getConstructors())); constructors.addAll(Arrays.asList(type.getDeclaredConstructors())); for (Constructor constructor : constructors) { Type[] types = new Type[constructor.getParameterTypes().length]; for (int j = 0; j < types.length; j++) { types[j] = Type.getType(constructor.getParameterTypes()[j]); } constructorMap.put(Type.getMethodDescriptor(Type.VOID_TYPE, types), constructor); } } public Map<Constructor, List<String>> getConstructorParameters() { return constructorParameters; } public Map<Method, List<String>> getMethodParameters() { return methodParameters; } public Map<String,Exception> getExceptions() { return exceptions; } public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (!name.equals(this.methodName)) { return null; } try { final List<String> parameterNames; final boolean isStaticMethod; if (methodName.equals("<init>")) { Constructor constructor = constructorMap.get(desc); if (constructor == null) { return null; } parameterNames = new ArrayList<String>(constructor.getParameterTypes().length); parameterNames.addAll(Collections.<String>nCopies(constructor.getParameterTypes().length, null)); constructorParameters.put(constructor, parameterNames); isStaticMethod = false; } else { Method method = methodMap.get(desc); if (method == null) { return null; } parameterNames = new ArrayList<String>(method.getParameterTypes().length); parameterNames.addAll(Collections.<String>nCopies(method.getParameterTypes().length, null)); methodParameters.put(method, parameterNames); isStaticMethod = Modifier.isStatic(method.getModifiers()); } return new EmptyVisitor() { // assume static method until we get a first parameter name public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) { if (isStaticMethod) { parameterNames.set(index, name); } else if (index > 0) { // for non-static the 0th arg is "this" so we need to offset by -1 parameterNames.set(index - 1, name); } } }; } catch (Exception e) { this.exceptions.put(signature, e); } return null; } } }
ASM5实现:
/** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xbean.recipe; import org.apache.xbean.asm5.original.commons.EmptyVisitor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.WeakHashMap; /** * Implementation of ParameterNameLoader that uses ASM to read the parameter names from the local variable table in the * class byte code. * * This wonderful piece of code was taken from org.springframework.core.LocalVariableTableParameterNameDiscover */ public class AsmParameterNameLoader implements ParameterNameLoader { /** * Weak map from Constructor to List<String>. */ private final WeakHashMap<Constructor,List<String>> constructorCache = new WeakHashMap<Constructor,List<String>>(); /** * Weak map from Method to List<String>. */ private final WeakHashMap<Method,List<String>> methodCache = new WeakHashMap<Method,List<String>>(); /** * Gets the parameter names of the specified method or null if the class was compiled without debug symbols on. * @param method the method for which the parameter names should be retrieved * @return the parameter names or null if the class was compilesd without debug symbols on */ public List<String> get(Method method) { // check the cache if (methodCache.containsKey(method)) { return methodCache.get(method); } Map<Method,List<String>> allMethodParameters = getAllMethodParameters(method.getDeclaringClass(), method.getName()); return allMethodParameters.get(method); } /** * Gets the parameter names of the specified constructor or null if the class was compiled without debug symbols on. * @param constructor the constructor for which the parameters should be retrieved * @return the parameter names or null if the class was compiled without debug symbols on */ public List<String> get(Constructor constructor) { // check the cache if (constructorCache.containsKey(constructor)) { return constructorCache.get(constructor); } Map<Constructor,List<String>> allConstructorParameters = getAllConstructorParameters(constructor.getDeclaringClass()); return allConstructorParameters.get(constructor); } /** * Gets the parameter names of all constructor or null if the class was compiled without debug symbols on. * @param clazz the class for which the constructor parameter names should be retrieved * @return a map from Constructor object to the parameter names or null if the class was compiled without debug symbols on */ public Map<Constructor,List<String>> getAllConstructorParameters(Class clazz) { // Determine the constructors? List<Constructor> constructors = new ArrayList<Constructor>(Arrays.asList(clazz.getConstructors())); constructors.addAll(Arrays.asList(clazz.getDeclaredConstructors())); if (constructors.isEmpty()) { return Collections.emptyMap(); } // Check the cache if (constructorCache.containsKey(constructors.get(0))) { Map<Constructor,List<String>> constructorParameters = new HashMap<Constructor,List<String>>(); for (Constructor constructor : constructors) { constructorParameters.put(constructor, constructorCache.get(constructor)); } return constructorParameters; } // Load the parameter names using ASM Map<Constructor,List<String>> constructorParameters = new HashMap<Constructor,List<String>> (); try { ClassReader reader = AsmParameterNameLoader.createClassReader(clazz); AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor visitor = new AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor(clazz); reader.accept(visitor, 0); Map exceptions = visitor.getExceptions(); if (exceptions.size() == 1) { throw new RuntimeException((Exception)exceptions.values().iterator().next()); } if (!exceptions.isEmpty()) { throw new RuntimeException(exceptions.toString()); } constructorParameters = visitor.getConstructorParameters(); } catch (IOException ex) { } // Cache the names for (Constructor constructor : constructors) { constructorCache.put(constructor, constructorParameters.get(constructor)); } return constructorParameters; } /** * Gets the parameter names of all methods with the specified name or null if the class was compiled without debug symbols on. * @param clazz the class for which the method parameter names should be retrieved * @param methodName the of the method for which the parameters should be retrieved * @return a map from Method object to the parameter names or null if the class was compiled without debug symbols on */ public Map<Method,List<String>> getAllMethodParameters(Class clazz, String methodName) { // Determine the constructors? Method[] methods = getMethods(clazz, methodName); if (methods.length == 0) { return Collections.emptyMap(); } // Check the cache if (methodCache.containsKey(methods[0])) { Map<Method,List<String>> methodParameters = new HashMap<Method,List<String>>(); for (Method method : methods) { methodParameters.put(method, methodCache.get(method)); } return methodParameters; } // Load the parameter names using ASM Map<Method,List<String>> methodParameters = new HashMap<Method,List<String>>(); try { ClassReader reader = AsmParameterNameLoader.createClassReader(clazz); AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor visitor = new AsmParameterNameLoader.AllParameterNamesDiscoveringVisitor(clazz, methodName); reader.accept(visitor, 0); Map exceptions = visitor.getExceptions(); if (exceptions.size() == 1) { throw new RuntimeException((Exception)exceptions.values().iterator().next()); } if (!exceptions.isEmpty()) { throw new RuntimeException(exceptions.toString()); } methodParameters = visitor.getMethodParameters(); } catch (IOException ex) { } // Cache the names for (Method method : methods) { methodCache.put(method, methodParameters.get(method)); } return methodParameters; } private Method[] getMethods(Class clazz, String methodName) { List<Method> methods = new ArrayList<Method>(Arrays.asList(clazz.getMethods())); methods.addAll(Arrays.asList(clazz.getDeclaredMethods())); List<Method> matchingMethod = new ArrayList<Method>(methods.size()); for (Method method : methods) { if (method.getName().equals(methodName)) { matchingMethod.add(method); } } return matchingMethod.toArray(new Method[matchingMethod.size()]); } private static ClassReader createClassReader(Class declaringClass) throws IOException { InputStream in = null; try { ClassLoader classLoader = declaringClass.getClassLoader(); in = classLoader.getResourceAsStream(declaringClass.getName().replace('.', '/') + ".class"); ClassReader reader = new ClassReader(in); return reader; } finally { if (in != null) { try { in.close(); } catch (IOException ignored) { } } } } private static class AllParameterNamesDiscoveringVisitor extends EmptyVisitor { private final Map<Constructor,List<String>> constructorParameters = new HashMap<Constructor,List<String>>(); private final Map<Method,List<String>> methodParameters = new HashMap<Method,List<String>>(); private final Map<String,Exception> exceptions = new HashMap<String,Exception>(); private final String methodName; private final Map<String,Method> methodMap = new HashMap<String,Method>(); private final Map<String,Constructor> constructorMap = new HashMap<String,Constructor>(); public AllParameterNamesDiscoveringVisitor(Class type, String methodName) { this.methodName = methodName; List<Method> methods = new ArrayList<Method>(Arrays.asList(type.getMethods())); methods.addAll(Arrays.asList(type.getDeclaredMethods())); for (Method method : methods) { if (method.getName().equals(methodName)) { methodMap.put(Type.getMethodDescriptor(method), method); } } } public AllParameterNamesDiscoveringVisitor(Class type) { this.methodName = "<init>"; List<Constructor> constructors = new ArrayList<Constructor>(Arrays.asList(type.getConstructors())); constructors.addAll(Arrays.asList(type.getDeclaredConstructors())); for (Constructor constructor : constructors) { Type[] types = new Type[constructor.getParameterTypes().length]; for (int j = 0; j < types.length; j++) { types[j] = Type.getType(constructor.getParameterTypes()[j]); } constructorMap.put(Type.getMethodDescriptor(Type.VOID_TYPE, types), constructor); } } public Map<Constructor, List<String>> getConstructorParameters() { return constructorParameters; } public Map<Method, List<String>> getMethodParameters() { return methodParameters; } public Map<String,Exception> getExceptions() { return exceptions; } public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (!name.equals(this.methodName)) { return null; } try { final List<String> parameterNames; final boolean isStaticMethod; if (methodName.equals("<init>")) { Constructor constructor = constructorMap.get(desc); if (constructor == null) { return null; } parameterNames = new ArrayList<String>(constructor.getParameterTypes().length); parameterNames.addAll(Collections.<String>nCopies(constructor.getParameterTypes().length, null)); constructorParameters.put(constructor, parameterNames); isStaticMethod = false; } else { Method method = methodMap.get(desc); if (method == null) { return null; } parameterNames = new ArrayList<String>(method.getParameterTypes().length); parameterNames.addAll(Collections.<String>nCopies(method.getParameterTypes().length, null)); methodParameters.put(method, parameterNames); isStaticMethod = Modifier.isStatic(method.getModifiers()); } return new MethodVisitor(Opcodes.ASM5) { // assume static method until we get a first parameter name public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) { if (isStaticMethod) { parameterNames.set(index, name); } else if (index > 0) { // for non-static the 0th arg is "this" so we need to offset by -1 parameterNames.set(index - 1, name); } } }; } catch (Exception e) { this.exceptions.put(signature, e); } return null; } } }
org.apache.xbean.asm5.original.commons.EmptyVisitor:
/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.xbean.asm5.original.commons; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Attribute; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Handle; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.TypePath; public class EmptyVisitor extends ClassVisitor { protected final AnnotationVisitor av = new AnnotationVisitor(Opcodes.ASM5) { @Override public void visit(String name, Object value) { EmptyVisitor.this.visit(name, value); } @Override public void visitEnum(String name, String desc, String value) { EmptyVisitor.this.visitEnum(name, desc, value); } @Override public AnnotationVisitor visitAnnotation(String name, String desc) { return EmptyVisitor.this.visitAnnotation(name, desc); } @Override public AnnotationVisitor visitArray(String name) { return EmptyVisitor.this.visitArray(name); } @Override public void visitEnd() { EmptyVisitor.this.visitEnd(); } }; protected final FieldVisitor fv = new FieldVisitor(Opcodes.ASM5) { @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return EmptyVisitor.this.visitAnnotation(desc, visible); } @Override public void visitAttribute(Attribute attribute) { EmptyVisitor.this.visitAttribute(attribute); } @Override public void visitEnd() { EmptyVisitor.this.visitEnd(); } }; protected final MethodVisitor mv = new MethodVisitor(Opcodes.ASM4) { @Override public AnnotationVisitor visitAnnotationDefault() { return EmptyVisitor.this.visitAnnotationDefault(); } @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return EmptyVisitor.this.visitAnnotation(desc, visible); } @Override public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { return EmptyVisitor.this.visitMethodParameterAnnotation(parameter, desc, visible); } @Override public void visitAttribute(Attribute attribute) { EmptyVisitor.this.visitAttribute(attribute); } @Override public void visitCode() { EmptyVisitor.this.visitCode(); } @Override public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { EmptyVisitor.this.visitFrame(type, nLocal, local, nStack, stack); } @Override public void visitInsn(int opcode) { EmptyVisitor.this.visitInsn(opcode); } @Override public void visitJumpInsn(int i, Label label) { EmptyVisitor.this.visitJumpInsn(i, label); } @Override public void visitLabel(Label label) { EmptyVisitor.this.visitLabel(label); } @Override public void visitLdcInsn(Object cst) { EmptyVisitor.this.visitLdcInsn(cst); } @Override public void visitIincInsn(int var, int increment) { EmptyVisitor.this.visitIincInsn(var, increment); } @Override public void visitTableSwitchInsn(int i, int i2, Label label, Label... labels) { EmptyVisitor.this.visitTableSwitchInsn(i, i2, label, labels); } @Override public void visitLookupSwitchInsn(Label label, int[] ints, Label[] labels) { EmptyVisitor.this.visitLookupSwitchInsn(label, ints, labels); } @Override public void visitMultiANewArrayInsn(String desc, int dims) { EmptyVisitor.this.visitMultiANewArrayInsn(desc, dims); } @Override public void visitTryCatchBlock(Label label, Label label2, Label label3, String s) { EmptyVisitor.this.visitTryCatchBlock(label, label2, label3, s); } @Override public void visitLocalVariable(String s, String s2, String s3, Label label, Label label2, int i) { EmptyVisitor.this.visitLocalVariable(s, s2, s3, label, label2, i); } @Override public void visitLineNumber(int i, Label label) { EmptyVisitor.this.visitLineNumber(i, label); } @Override public void visitMaxs(int maxStack, int maxLocals) { EmptyVisitor.this.visitMaxs(maxStack, maxLocals); } @Override public void visitEnd() { EmptyVisitor.this.visitEnd(); } @Override public void visitIntInsn(int opcode, int operand) { EmptyVisitor.this.visitIntInsn(opcode, operand); } @Override public void visitVarInsn(int opcode, int var) { EmptyVisitor.this.visitVarInsn(opcode, var); } @Override public void visitTypeInsn(int opcode, String type) { EmptyVisitor.this.visitTypeInsn(opcode, type); } @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { EmptyVisitor.this.visitFieldInsn(opcode, owner, name, desc); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { EmptyVisitor.this.visitMethodInsn(opcode, owner, name, desc); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { EmptyVisitor.this.visitMethodInsn(opcode, owner, name, desc); } @Override public void visitInvokeDynamicInsn(String s, String s2, Handle handle, Object... objects) { EmptyVisitor.this.visitInvokeDynamicInsn(s, s2, handle, objects); } }; public EmptyVisitor() { super(Opcodes.ASM5); } protected AnnotationVisitor visitAnnotationDefault() { return av; } protected AnnotationVisitor visitArray(String name) { return av; } protected AnnotationVisitor visitAnnotation(String name, String desc) { return av; } protected void visitEnum(String name, String desc, String value) { // no-op } protected void visit(String name, Object value) { // no-op } protected void visitVarInsn(int opcode, int var) { // no-op } protected void visitTypeInsn(int opcode, String type) { // no-op } protected void visitFieldInsn(int opcode, String owner, String name, String desc) { // no-op } protected void visitMethodInsn(int opcode, String owner, String name, String desc) { // no-op } protected void visitInvokeDynamicInsn(String s, String s2, Handle handle, Object[] objects) { // no-op } protected void visitIntInsn(int opcode, int operand) { // no-op } protected void visitJumpInsn(int i, Label label) { // no-op } protected void visitLabel(Label label) { // no-op } protected void visitLdcInsn(Object cst) { // no-op } protected void visitIincInsn(int var, int increment) { // no-op } protected void visitTableSwitchInsn(int i, int i2, Label label, Label[] labels) { // no-op } protected void visitLookupSwitchInsn(Label label, int[] ints, Label[] labels) { // no-op } protected void visitMultiANewArrayInsn(String desc, int dims) { // no-op } protected void visitTryCatchBlock(Label label, Label label2, Label label3, String s) { // no-op } protected void visitLocalVariable(String s, String s2, String s3, Label label, Label label2, int i) { // no-op } protected void visitLineNumber(int i, Label label) { // no-op } protected void visitMaxs(int maxStack, int maxLocals) { // no-op } protected void visitInsn(int opcode) { // no-op } protected void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { // no-op } protected void visitCode() { // no-op } protected AnnotationVisitor visitMethodParameterAnnotation(int parameter, String desc, boolean visible) { return av; } protected AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { return av; } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { if (cv != null) { cv.visit(version, access, name, signature, superName, interfaces); } } @Override public void visitSource(String source, String debug) { if (cv != null) { cv.visitSource(source, debug); } } @Override public void visitOuterClass(String owner, String name, String desc) { if (cv != null) { cv.visitOuterClass(owner, name, desc); } } @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return av; } @Override public void visitAttribute(Attribute attr) { if (cv != null) { cv.visitAttribute(attr); } } @Override public void visitInnerClass(String name, String outerName, String innerName, int access) { if (cv != null) { cv.visitInnerClass(name, outerName, innerName, access); } } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { return fv; } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { return mv; } @Override public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { return av; } @Override public void visitEnd() { if (cv != null) { cv.visitEnd(); } } public AnnotationVisitor annotationVisitor() { return av; } public FieldVisitor fieldVisitor() { return fv; } public MethodVisitor methodVisitor() { return mv; } }