List of usage examples for org.objectweb.asm.commons Method getName
public String getName()
From source file:co.cask.cdap.internal.io.DatumWriterGenerator.java
License:Apache License
/** * Generates method body for encoding java class. If the class given is an interface, * getter method will be used to access the field values, otherwise, it will assumes * fields are public.// w ww .j av a 2s.co m * * @param mg * @param schema * @param outputType * @param value * @param encoder * @param schemaLocal * @param seenRefs */ private void encodeRecord(GeneratorAdapter mg, Schema schema, TypeToken<?> outputType, int value, int encoder, int schemaLocal, int seenRefs) { try { Class<?> rawType = outputType.getRawType(); // Record type might be defined by the user, hence need to preserve class loading of it preservedClasses.add(rawType); boolean isInterface = rawType.isInterface(); /* Check for circular reference if (value != null && !seenRefs.add(value)) { throw new IOException(...); } */ Label notSeen = mg.newLabel(); mg.loadArg(value); mg.ifNull(notSeen); mg.loadArg(seenRefs); mg.loadArg(value); mg.invokeInterface(Type.getType(Set.class), getMethod(boolean.class, "add", Object.class)); mg.ifZCmp(GeneratorAdapter.NE, notSeen); mg.throwException(Type.getType(IOException.class), "Circular reference not supported."); mg.mark(notSeen); // Store the list of schema fields. mg.loadArg(schemaLocal); mg.invokeVirtual(Type.getType(Schema.class), getMethod(List.class, "getFields")); int fieldSchemas = mg.newLocal(Type.getType(List.class)); mg.storeLocal(fieldSchemas); // For each field, call the encode method for the field List<Schema.Field> fields = schema.getFields(); for (int i = 0; i < fields.size(); i++) { Schema.Field field = fields.get(i); TypeToken<?> fieldType; // this.encodeFieldMethod(value.fieldName, encoder, fieldSchemas.get(i).getSchema()); if (isInterface) { mg.loadThis(); mg.loadArg(value); Method getter = getGetter(outputType, field.getName()); fieldType = outputType.resolveType(rawType.getMethod(getter.getName()).getGenericReturnType()); mg.invokeInterface(Type.getType(rawType), getter); } else { fieldType = outputType .resolveType(Fields.findField(outputType.getType(), field.getName()).getGenericType()); fieldAccessorRequests.put(outputType, field.getName()); mg.loadThis(); mg.dup(); mg.getField(classType, getFieldAccessorName(outputType, field.getName()), Type.getType(FieldAccessor.class)); mg.loadArg(value); mg.invokeInterface(Type.getType(FieldAccessor.class), getAccessorMethod(fieldType)); if (!fieldType.getRawType().isPrimitive()) { doCast(mg, fieldType, field.getSchema()); } } mg.loadArg(encoder); mg.loadLocal(fieldSchemas); mg.push(i); mg.invokeInterface(Type.getType(List.class), getMethod(Object.class, "get", int.class)); mg.checkCast(Type.getType(Schema.Field.class)); mg.invokeVirtual(Type.getType(Schema.Field.class), getMethod(Schema.class, "getSchema")); mg.loadArg(seenRefs); mg.invokeVirtual(classType, getEncodeMethod(fieldType, field.getSchema())); } } catch (Exception e) { throw Throwables.propagate(e); } }
From source file:co.cask.common.internal.io.DatumWriterGenerator.java
License:Apache License
/** * Generates method body for encoding java class. If the class given is an interface, * getter method will be used to access the field values, otherwise, it will assumes * fields are public.//from ww w . jav a 2 s .c o m * * @param mg * @param schema * @param outputType * @param value * @param encoder * @param schemaLocal * @param seenRefs */ private void encodeRecord(GeneratorAdapter mg, Schema schema, TypeToken<?> outputType, int value, int encoder, int schemaLocal, int seenRefs) { try { Class<?> rawType = outputType.getRawType(); // Record type might be defined by the user, hence need to preserve class loading of it preservedClasses.add(rawType); boolean isInterface = rawType.isInterface(); /* Check for circular reference if (value != null && !seenRefs.add(value)) { throw new IOException(...); } */ Label notSeen = mg.newLabel(); mg.loadArg(value); mg.ifNull(notSeen); mg.loadArg(seenRefs); mg.loadArg(value); mg.invokeInterface(Type.getType(Set.class), getMethod(boolean.class, "add", Object.class)); mg.ifZCmp(GeneratorAdapter.NE, notSeen); mg.throwException(Type.getType(IOException.class), "Circular reference not supported."); mg.mark(notSeen); // Store the list of schema fields. mg.loadArg(schemaLocal); mg.invokeVirtual(Type.getType(Schema.class), getMethod(List.class, "getFields")); int fieldSchemas = mg.newLocal(Type.getType(List.class)); mg.storeLocal(fieldSchemas); // For each field, call the encode method for the field List<Schema.Field> fields = schema.getFields(); for (int i = 0; i < fields.size(); i++) { Schema.Field field = fields.get(i); TypeToken<?> fieldType; // this.encodeFieldMethod(value.fieldName, encoder, fieldSchemas.get(i).getSchema()); if (isInterface) { mg.loadThis(); mg.loadArg(value); Method getter = getGetter(outputType, field.getName()); fieldType = outputType.resolveType(rawType.getMethod(getter.getName()).getGenericReturnType()); mg.invokeInterface(Type.getType(rawType), getter); } else { fieldType = outputType .resolveType(Fields.findField(outputType, field.getName()).getGenericType()); fieldAccessorRequests.put(outputType, field.getName()); mg.loadThis(); mg.dup(); mg.getField(classType, getFieldAccessorName(outputType, field.getName()), Type.getType(FieldAccessor.class)); mg.loadArg(value); mg.invokeInterface(Type.getType(FieldAccessor.class), getAccessorMethod(fieldType)); if (!fieldType.getRawType().isPrimitive()) { doCast(mg, fieldType, field.getSchema()); } } mg.loadArg(encoder); mg.loadLocal(fieldSchemas); mg.push(i); mg.invokeInterface(Type.getType(List.class), getMethod(Object.class, "get", int.class)); mg.checkCast(Type.getType(Schema.Field.class)); mg.invokeVirtual(Type.getType(Schema.Field.class), getMethod(Schema.class, "getSchema")); mg.loadArg(seenRefs); mg.invokeVirtual(classType, getEncodeMethod(fieldType, field.getSchema())); } } catch (Exception e) { throw Throwables.propagate(e); } }
From source file:co.cask.tigon.internal.io.DatumWriterGenerator.java
License:Apache License
/** * Generates method body for encoding java class. If the class given is an interface, * getter method will be used to access the field values, otherwise, it will assumes * fields are public./* w w w . j av a2s . c o m*/ * * @param mg * @param schema * @param outputType * @param value * @param encoder * @param schemaLocal * @param seenRefs */ private void encodeRecord(GeneratorAdapter mg, Schema schema, TypeToken<?> outputType, int value, int encoder, int schemaLocal, int seenRefs) { try { Class<?> rawType = outputType.getRawType(); boolean isInterface = rawType.isInterface(); /* Check for circular reference if (value != null && !seenRefs.add(value)) { throw new IOException(...); } */ Label notSeen = mg.newLabel(); mg.loadArg(value); mg.ifNull(notSeen); mg.loadArg(seenRefs); mg.loadArg(value); mg.invokeInterface(Type.getType(Set.class), getMethod(boolean.class, "add", Object.class)); mg.ifZCmp(GeneratorAdapter.NE, notSeen); mg.throwException(Type.getType(IOException.class), "Circular reference not supported."); mg.mark(notSeen); // Store the list of schema fields. mg.loadArg(schemaLocal); mg.invokeVirtual(Type.getType(Schema.class), getMethod(List.class, "getFields")); int fieldSchemas = mg.newLocal(Type.getType(List.class)); mg.storeLocal(fieldSchemas); // For each field, call the encode method for the field List<Schema.Field> fields = schema.getFields(); for (int i = 0; i < fields.size(); i++) { Schema.Field field = fields.get(i); TypeToken<?> fieldType; // this.encodeFieldMethod(value.fieldName, encoder, fieldSchemas.get(i).getSchema()); if (isInterface) { mg.loadThis(); mg.loadArg(value); Method getter = getGetter(outputType, field.getName()); fieldType = outputType.resolveType(rawType.getMethod(getter.getName()).getGenericReturnType()); mg.invokeInterface(Type.getType(rawType), getter); } else { fieldType = outputType .resolveType(Fields.findField(outputType, field.getName()).getGenericType()); fieldAccessorRequests.put(outputType, field.getName()); mg.loadThis(); mg.dup(); mg.getField(classType, getFieldAccessorName(outputType, field.getName()), Type.getType(FieldAccessor.class)); mg.loadArg(value); mg.invokeInterface(Type.getType(FieldAccessor.class), getAccessorMethod(fieldType)); if (!fieldType.getRawType().isPrimitive()) { doCast(mg, fieldType, field.getSchema()); } } mg.loadArg(encoder); mg.loadLocal(fieldSchemas); mg.push(i); mg.invokeInterface(Type.getType(List.class), getMethod(Object.class, "get", int.class)); mg.checkCast(Type.getType(Schema.Field.class)); mg.invokeVirtual(Type.getType(Schema.Field.class), getMethod(Schema.class, "getSchema")); mg.loadArg(seenRefs); mg.invokeVirtual(classType, getEncodeMethod(fieldType, field.getSchema())); } } catch (Exception e) { throw Throwables.propagate(e); } }
From source file:com.android.build.gradle.internal.incremental.IncrementalChangeVisitor.java
License:Apache License
/** * To each class, add the dispatch method called by the original code that acts as a trampoline to * invoke the changed methods./* w ww .jav a 2 s .c om*/ * <p> * Pseudo code: * <code> * Object access$dispatch(String name, object[] args) { * if (name.equals( * "firstMethod.(L$type;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) { * return firstMethod(($type)arg[0], (String)arg[1], arg[2]); * } * if (name.equals("secondMethod.(L$type;Ljava/lang/String;I;)V")) { * secondMethod(($type)arg[0], (String)arg[1], (int)arg[2]); * return; * } * ... * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " + visitedClassName + * "$dispatch implementation, restart the application"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void addDispatchMethod() { int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_VARARGS; Method m = new Method("access$dispatch", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); if (TRACING_ENABLED) { mv.push("Redirecting "); mv.loadArg(0); trace(mv, 2); } List<MethodNode> allMethods = new ArrayList<>(); // if we are disabled, do not generate any dispatch, the method will throw an exception // if invoked which should never happen. if (!instantRunDisabled) { //noinspection unchecked allMethods.addAll(classNode.methods); allMethods.addAll(addedMethods); } final Map<String, MethodNode> methods = new HashMap<>(); for (MethodNode methodNode : allMethods) { if (methodNode.name.equals("<clinit>") || methodNode.name.equals("<init>")) { continue; } if (!isAccessCompatibleWithInstantRun(methodNode.access)) { continue; } methods.put(methodNode.name + "." + methodNode.desc, methodNode); } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodNode methodNode = methods.get(methodName); String name = methodNode.name; boolean isStatic = (methodNode.access & Opcodes.ACC_STATIC) != 0; String newDesc = computeOverrideMethodDesc(methodNode.desc, isStatic); if (TRACING_ENABLED) { trace(mv, "M: " + name + " P:" + newDesc); } Type[] args = Type.getArgumentTypes(newDesc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } mv.visitMethodInsn(Opcodes.INVOKESTATIC, visitedClassName + "$override", isStatic ? computeOverrideMethodName(name, methodNode.desc) : name, newDesc, false); Type ret = Type.getReturnType(methodNode.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, methods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); super.visitEnd(); }
From source file:com.android.build.gradle.internal.incremental.IncrementalSupportVisitor.java
License:Apache License
/*** * Inserts a trampoline to this class so that the updated methods can make calls to super * class methods./*from w w w.j av a 2s . c o m*/ * <p> * Pseudo code for this trampoline: * <code> * Object access$super($classType instance, String name, object[] args) { * switch(name) { * case "firstMethod.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;": * return super~instance.firstMethod((String)arg[0], arg[1]); * case "secondMethod.(Ljava/lang/String;I)V": * return super~instance.firstMethod((String)arg[0], arg[1]); * * default: * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " $classType $super implementation"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void createAccessSuper() { int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_VARARGS; Method m = new Method("access$super", "(L" + visitedClassName + ";Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); // Gather all methods from itself and its superclasses to generate a giant access$super // implementation. // This will work fine as long as we don't support adding methods to a class. final Map<String, MethodReference> uniqueMethods = new HashMap<>(); if (parentNodes.isEmpty()) { // if we cannot determine the parents for this class, let's blindly add all the // method of the current class as a gateway to a possible parent version. addAllNewMethods(classNode, classNode, uniqueMethods); } else { // otherwise, use the parent list. for (ClassNode parentNode : parentNodes) { addAllNewMethods(classNode, parentNode, uniqueMethods); } } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodReference methodRef = uniqueMethods.get(methodName); mv.visitVarInsn(Opcodes.ALOAD, 0); Type[] args = Type.getArgumentTypes(methodRef.method.desc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } if (TRACING_ENABLED) { trace(mv, "super selected ", methodRef.owner.name, methodRef.method.name, methodRef.method.desc); } String parentName = findParentClassForMethod(methodRef); logger.verbose("Generating access$super for %1$s recev %2$s", methodRef.method.name, parentName); // Call super on the other object, yup this works cos we are on the right place to // call from. mv.visitMethodInsn(Opcodes.INVOKESPECIAL, parentName, methodRef.method.name, methodRef.method.desc, false); Type ret = Type.getReturnType(methodRef.method.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, uniqueMethods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:com.android.build.gradle.internal.incremental.IncrementalSupportVisitor.java
License:Apache License
/*** * Inserts a trampoline to this class so that the updated methods can make calls to * constructors./*from www.j a v a 2 s .c om*/ * * <p> * Pseudo code for this trampoline: * <code> * ClassName(Object[] args, Marker unused) { * String name = (String) args[0]; * if (name.equals( * "java/lang/ClassName.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) { * this((String)arg[1], arg[2]); * return * } * if (name.equals("SuperClassName.(Ljava/lang/String;I)V")) { * super((String)arg[1], (int)arg[2]); * return; * } * ... * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " $classType $super implementation"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void createDispatchingThis() { // Gather all methods from itself and its superclasses to generate a giant constructor // implementation. // This will work fine as long as we don't support adding constructors to classes. final Map<String, MethodNode> uniqueMethods = new HashMap<>(); addAllNewConstructors(uniqueMethods, classNode, true /*keepPrivateConstructors*/); for (ClassNode parentNode : parentNodes) { addAllNewConstructors(uniqueMethods, parentNode, false /*keepPrivateConstructors*/); } int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC; Method m = new Method(ByteCodeUtils.CONSTRUCTOR, ConstructorRedirection.DISPATCHING_THIS_SIGNATURE); MethodVisitor visitor = super.visitMethod(0, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); mv.visitCode(); // Mark this code as redirection code Label label = new Label(); mv.visitLineNumber(0, label); // Get and store the constructor canonical name. mv.visitVarInsn(Opcodes.ALOAD, 1); mv.push(1); mv.visitInsn(Opcodes.AALOAD); mv.unbox(Type.getType("Ljava/lang/String;")); final int constructorCanonicalName = mv.newLocal(Type.getType("Ljava/lang/String;")); mv.storeLocal(constructorCanonicalName); new StringSwitch() { @Override void visitString() { mv.loadLocal(constructorCanonicalName); } @Override void visitCase(String canonicalName) { MethodNode methodNode = uniqueMethods.get(canonicalName); String owner = canonicalName.split("\\.")[0]; // Parse method arguments and mv.visitVarInsn(Opcodes.ALOAD, 0); Type[] args = Type.getArgumentTypes(methodNode.desc); int argc = 1; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 1); mv.push(argc + 1); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, ByteCodeUtils.CONSTRUCTOR, methodNode.desc, false); mv.visitInsn(Opcodes.RETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, uniqueMethods.keySet()); mv.visitMaxs(1, 3); mv.visitEnd(); }
From source file:com.android.build.gradle.internal2.incremental.IncrementalChangeVisitor.java
License:Apache License
/** * To each class, add the dispatch method called by the original code that acts as a trampoline to * invoke the changed methods./*from w ww . j a va2s. com*/ * <p> * Pseudo code: * <code> * Object access$dispatch(String name, object[] args) { * if (name.equals( * "firstMethod.(L$type;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) { * return firstMethod(($type)arg[0], (String)arg[1], arg[2]); * } * if (name.equals("secondMethod.(L$type;Ljava/lang/String;I;)V")) { * secondMethod(($type)arg[0], (String)arg[1], (int)arg[2]); * return; * } * ... * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " + visitedClassName + * "$dispatch implementation, restart the application"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void addDispatchMethod() { int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_VARARGS; Method m = new Method("access$dispatch", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); if (TRACING_ENABLED) { mv.push("Redirecting "); mv.loadArg(0); trace(mv, 2); } List<MethodNode> allMethods = new ArrayList<>(); // if we are disabled, do not generate any dispatch, the method will throw an exception // if invoked which should never happen. if (!instantRunDisabled) { //noinspection unchecked allMethods.addAll(classNode.methods); allMethods.addAll(addedMethods); } final Map<String, MethodNode> methods = new HashMap<>(); for (MethodNode methodNode : allMethods) { if (methodNode.name.equals(ByteCodeUtils.CLASS_INITIALIZER) || methodNode.name.equals(ByteCodeUtils.CONSTRUCTOR)) { continue; } if (!isAccessCompatibleWithInstantRun(methodNode.access)) { continue; } methods.put(methodNode.name + "." + methodNode.desc, methodNode); } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodNode methodNode = methods.get(methodName); String name = methodNode.name; boolean isStatic = (methodNode.access & Opcodes.ACC_STATIC) != 0; String newDesc = computeOverrideMethodDesc(methodNode.desc, isStatic); if (TRACING_ENABLED) { trace(mv, "M: " + name + " P:" + newDesc); } Type[] args = Type.getArgumentTypes(newDesc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } mv.visitMethodInsn(Opcodes.INVOKESTATIC, visitedClassName + "$override", isStatic ? computeOverrideMethodName(name, methodNode.desc) : name, newDesc, false); Type ret = Type.getReturnType(methodNode.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, methods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); super.visitEnd(); }
From source file:com.android.build.gradle.internal2.incremental.IncrementalSupportVisitor.java
License:Apache License
/*** * Inserts a trampoline to this class so that the updated methods can make calls to super * class methods.//from w ww.j av a 2s . c om * <p> * Pseudo code for this trampoline: * <code> * Object access$super($classType instance, String name, object[] args) { * switch(name) { * case "firstMethod.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;": * return super~instance.firstMethod((String)arg[0], arg[1]); * case "secondMethod.(Ljava/lang/String;I)V": * return super~instance.firstMethod((String)arg[0], arg[1]); * * default: * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " $classType $super implementation"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void createAccessSuper() { int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_VARARGS; Method m = new Method("access$super", "(L" + visitedClassName + ";Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); // Gather all methods from itself and its superclasses to generate a giant access$super // implementation. // This will work fine as long as we don't support adding methods to a class. final Map<String, MethodReference> uniqueMethods = new HashMap<>(); if (parentNodes.isEmpty()) { // if we cannot determine the parents for this class, let's blindly add all the // method of the current class as a gateway to a possible parent version. addAllNewMethods(classNode, classNode, uniqueMethods); } else { // otherwise, use the parent list. for (ClassNode parentNode : parentNodes) { addAllNewMethods(classNode, parentNode, uniqueMethods); } } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodReference methodRef = uniqueMethods.get(methodName); mv.visitVarInsn(Opcodes.ALOAD, 0); Type[] args = Type.getArgumentTypes(methodRef.method.desc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } if (TRACING_ENABLED) { trace(mv, "super selected ", methodRef.owner.name, methodRef.method.name, methodRef.method.desc); } String parentName = findParentClassForMethod(methodRef); LOG.verbose("Generating access$super for " + methodRef.method.name + " recv " + parentName); // Call super on the other object, yup this works cos we are on the right place to // call from. mv.visitMethodInsn(Opcodes.INVOKESPECIAL, parentName, methodRef.method.name, methodRef.method.desc, false); Type ret = Type.getReturnType(methodRef.method.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, uniqueMethods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:com.google.code.nanorm.internal.introspect.asm.AccessorBuilder.java
License:Apache License
/** * {@inheritDoc}/*from w ww .j a v a 2s.c o m*/ */ public Class<?> visitProperty(int pos, String property, java.lang.reflect.Method getter, boolean hasNext, Class<?> beanClass) { checkNull(pos); // If expected class is not equal to the type on top of the stack, do // the cast if (declaredClass != beanClass) { accessormg.checkCast(Type.getType(beanClass)); } if (!hasNext && isSetter) { java.lang.reflect.Method setter = IntrospectUtils.findSetter(beanClass, property); Type type = Type.getType(setter.getParameterTypes()[0]); // Cast parameter to required type accessormg.loadArg(1); accessormg.unbox(type); Method method = new Method(setter.getName(), Type.VOID_TYPE, new Type[] { type }); accessormg.invokeVirtual(Type.getType(beanClass), method); } else { Type type = Type.getType(getter.getReturnType()); Method method = new Method(getter.getName(), type, new Type[0]); accessormg.invokeVirtual(Type.getType(beanClass), method); // If this is last property in the path, box the result to match // Getter#getValue return value if (!hasNext) { accessormg.box(type); } // Remember type on top of the stack declaredClass = getter.getReturnType(); } return null; }
From source file:com.google.code.nanorm.internal.introspect.asm.MapperBuilder.java
License:Apache License
/** * Copy the annotation.// ww w. j ava2s. co m * @param visitor annotation visitor * @param annotation annotation */ private static void visitAnnotation(AnnotationVisitor visitor, Annotation annotation) { final java.lang.reflect.Method[] methods = annotation.annotationType().getDeclaredMethods(); for (java.lang.reflect.Method method : methods) { try { Object obj = method.invoke(annotation); final String name = method.getName(); visitAnnotationProperty(name, obj, visitor); } catch (IllegalAccessException e) { throw new IllegalStateException("Failed to copy annotation.", e); } catch (InvocationTargetException e) { throw new IllegalStateException("Failed to copy annotation.", e); } } visitor.visitEnd(); }