@Override public void addDeclaration(ClassWriter cw) { Type mapperClass = AsmUtils.findClosestPublicTypeExposing(mapper.getClass(), FieldMapper.class); FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, prefix + index, toTargetTypeDeclaration(AsmUtils.toAsmType(mapperClass)), toTargetTypeDeclaration(AsmUtils.toGenericAsmType(mapperClass)), null); fv.visitEnd(); } }
@Override public void addInit(MethodVisitor mv, String mapperClassType) { String fieldMapperType = AsmUtils.toAsmType(mapper.getClass()); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, prefix == CONSTRUCTOR_MAPPER_PREFIX ? 2 : 1); AsmUtils.addIndex(mv, index); mv.visitInsn(AALOAD); mv.visitTypeInsn(CHECKCAST, fieldMapperType); mv.visitFieldInsn(GETFIELD, fieldMapperType, "setter", toTargetTypeDeclaration(AsmUtils.toAsmType(declaredSetterClass))); mv.visitTypeInsn(CHECKCAST, AsmUtils.toAsmType(setterClass)); mv.visitFieldInsn(PUTFIELD, mapperClassType, prefix + index + "Setter", toTargetTypeDeclaration(AsmUtils.toAsmType(setterClass))); }
@Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { if (signature != null) { genericTypeNames = AsmUtils.extractGenericTypeNames(signature); } else { genericTypeNames = Collections.emptyList(); } super.visit(version, access, name, signature, superName, interfaces); }
@Override public void addDeclaration(ClassWriter cw) { { FieldVisitor fvSetter = cw.visitField(ACC_PRIVATE + ACC_FINAL, prefix + index+ "Setter", toTargetTypeDeclaration(AsmUtils.toAsmType(setterClass)), toTargetTypeDeclaration(AsmUtils.toGenericAsmType(setterClass)), null); fvSetter.visitEnd(); } }
public static void invoke(MethodVisitor mv, Method method) { if (Modifier.isStatic(method.getModifiers())) { mv.visitMethodInsn(Opcodes.INVOKESTATIC, toAsmType(method.getDeclaringClass()), method.getName(), toSignature(method), false); } else { invoke(mv, method.getDeclaringClass(), method.getName(), toSignature(method)); } } public static void invoke(MethodVisitor mv, Type target,
private static <S> void invokeGetter(Parameter p, Getter<? super S, ?> getter, String classType, Class<?> sourceClass, MethodVisitor mv, Consumer<MethodVisitor> consumer, boolean ignoreNullValues) throws NoSuchMethodException { GetterCall getterCall = getGetterCall(p.getType(), getter.getClass()); String getterType = AsmUtils.toAsmType(getterCall.getterType); String sourceType = AsmUtils.toAsmType(sourceClass.equals(Void.class) || sourceClass.equals(void.class) ? Object.class : sourceClass); mv.visitFieldInsn(GETFIELD, classType, "getter_" + p.getName(), AsmUtils.toTargetTypeDeclaration(getterType)); mv.visitVarInsn(ALOAD, 1); AsmUtils.invoke(mv, getterCall.getterType, getterCall.methodName, "(" + AsmUtils.toTargetTypeDeclaration(paramType) + ")" + AsmUtils.toAsmType(p.getType())); if (consumer != null) { consumer.accept(mv); Class<?> wrapperClass = AsmUtils.toWrapperClass(p.getType()); Method getterMethod = BiInstantiatorBuilder.getMethod(TypeHelper.toClass(getterCall.getterType), "get", 1); AsmUtils.invoke(mv, getterMethod); if (!wrapperClass.isAssignableFrom(getterMethod.getReturnType())) { mv.visitTypeInsn(CHECKCAST, AsmUtils.toAsmType(wrapperClass));
+ "L" + SETTER_TYPE + "<L" + targetType + ";" + AsmUtils.toTargetTypeDeclaration(propertyType) + ">;" + "L" + ORG_SFM_REFLECT_PRIMITIVE + methodSuffix + "Setter<L" + targetType + ";>;", "java/lang/Object", mv = cw.visitMethod(ACC_PUBLIC, setMethod, "(" + AsmUtils.toTargetTypeDeclaration(targetType) + primitiveType + ")V", null, new String[] { "java/lang/Exception" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(primitiveLoadOp, 2); AsmUtils.invoke(mv, target, method.getName(), "(" + primitiveType + ")" + AsmUtils.toTargetTypeDeclaration(method.getReturnType())); mv = cw.visitMethod(ACC_PUBLIC, "set", "(" + AsmUtils.toTargetTypeDeclaration(targetType) + AsmUtils.toTargetTypeDeclaration(propertyType) + ")V", null, new String[] { "java/lang/Exception" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); AsmUtils.invoke(mv, property, valueMethod, "()" + primitiveType); AsmUtils.invoke(mv, target, method.getName(), "(" + primitiveType + ")" + AsmUtils.toTargetTypeDeclaration(method.getReturnType())); mv.visitInsn(RETURN); mv.visitMaxs(2, 3); return AsmUtils.writeClassToFile(className, cw.toByteArray());
public static <S1, S2> byte[] createInstantiator(final String className, final Class<?> s1, final Class<?> s2, final ExecutableInstantiatorDefinition instantiatorDefinition, final Map<Parameter, BiFunction<? super S1, ? super S2, ?>> injectionsMap) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); Class<?> targetClass= TypeHelper.toClass(getTargetType(instantiatorDefinition)); String targetType = AsmUtils.toAsmType(targetClass); String s1Type = AsmUtils.toWrapperType(s1); String s2Type = AsmUtils.toWrapperType(s2); String classType = AsmUtils.toAsmType(className); String instantiatorType = AsmUtils.toAsmType(BI_INSTANTIATOR_CLASS); List<InjectionPoint> injections = toInjections(injectionsMap); cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "Ljava/lang/Object;L" + instantiatorType + "<L" + targetType + ";>;", "java/lang/Object", new String[] { instantiatorType }); Parameter[] parameters = instantiatorDefinition.getParameters(); appendFunctionsField(injections, cw); appendInit(injections, cw, s1Type, s2Type, classType); appendNewInstance(s1, s2, instantiatorDefinition, injections, cw, targetType, s1Type, s2Type, classType, parameters); appendBridgeMethod(cw, targetType, s1Type, s2Type, classType); appendToString(injections, cw, parameters); cw.visitEnd(); return AsmUtils.writeClassToFile(className, cw.toByteArray()); }
@Override public void addInit(MethodVisitor mv, String mapperClassType) { Type mapperClass = AsmUtils.findClosestPublicTypeExposing(mapper.getClass(), FieldMapper.class); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, prefix == CONSTRUCTOR_MAPPER_PREFIX ? 2 : 1); AsmUtils.addIndex(mv, index); mv.visitInsn(AALOAD); mv.visitTypeInsn(CHECKCAST, AsmUtils.toAsmType(mapperClass)); mv.visitFieldInsn(PUTFIELD, mapperClassType, prefix + index, toTargetTypeDeclaration(AsmUtils.toAsmType(mapperClass))); }
@Override public void addMappingCall(MethodVisitor mv, String mapperClassType) throws NoSuchMethodException { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mapperClassType, prefix + index + "Setter", toTargetTypeDeclaration(AsmUtils.toAsmType(setterClass))); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 3); AsmUtils.addIndex(mv, getterIndex); AsmUtils.invoke(mv, getMethod); AsmUtils.invoke(mv, setMethod); }
ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "Ljava/lang/Object;L" + GETTER_TYPE + "<L" + targetType + ";" + AsmUtils.toTargetTypeDeclaration(propertyType) + ">;", "java/lang/Object", new String[] {GETTER_TYPE}); "(" + AsmUtils.toTargetTypeDeclaration(targetType) + ")" + AsmUtils.toTargetTypeDeclaration(propertyType), null, new String[] { "java/lang/Exception" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(GETFIELD, targetType, field.getName(), AsmUtils.toTargetTypeDeclaration(propertyType)); return AsmUtils.writeClassToFile(className, cw.toByteArray());
public static String toTargetTypeDeclaration(Type targetType) { if (TypeHelper.isPrimitive(targetType)) { return primitivesType.get(TypeHelper.toClass(targetType)); } return toTargetTypeDeclaration(AsmUtils.toAsmType(targetType)); } public static String toTargetTypeDeclaration(String targetType) {
private static void changeToPrimitiveIfNeeded(InjectionPoint injectionPoint, MethodVisitor mv, Class<?> wrapperClass, boolean ignoreNullValues) { if (TypeHelper.isPrimitive(injectionPoint.parameter.getType())) { mv.visitVarInsn(ALOAD, 4); String methodSuffix = getPrimitiveMethodSuffix(injectionPoint.parameter); String valueMethodPrefix = methodSuffix.toLowerCase(); if ("character".equals(valueMethodPrefix)) { valueMethodPrefix = "char"; } String valueMethod = valueMethodPrefix + "Value"; AsmUtils.invoke(mv, wrapperClass, valueMethod, "()" + AsmUtils.toAsmType(injectionPoint.parameter.getType())); mv.visitVarInsn(AsmUtils.getStoreOps(injectionPoint.parameter.getType()), 4); } }
@Override public void addMappingCall(MethodVisitor mv, String mapperClassType) { Type mapperClass = AsmUtils.findClosestPublicTypeExposing(mapper.getClass(), FieldMapper.class); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mapperClassType, prefix + index, "L" + AsmUtils.toAsmType(mapperClass) + ";"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); Method m = getMapToMethod(TypeHelper.toClass(mapperClass)); AsmUtils.invoke(mv, m); }
@Override public void addMappingCall(MethodVisitor mv, String mapperClassType) throws NoSuchMethodException { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mapperClassType, prefix + index + "Setter", toTargetTypeDeclaration(AsmUtils.toAsmType(setterClass))); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mapperClassType, prefix + index + "Getter", toTargetTypeDeclaration(AsmUtils.toAsmType(getterClass))); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 3); AsmUtils.invoke(mv, getMethod); AsmUtils.invoke(mv, setMethod); }
private static <S1, S2> void appendNewInstanceBuilder(Class<?> s1, Class<?> s2, BuilderInstantiatorDefinition instantiatorDefinition, List<InjectionPoint> injectionPoints, ClassWriter cw, String targetType, String s1Type, String s2Type, String classType, Map<Parameter, Method> setters, boolean ignoreNullValues) throws NoSuchMethodException { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "(" + AsmUtils.toTargetTypeDeclaration(s1Type) + AsmUtils.toTargetTypeDeclaration(s2Type)+ ")" + AsmUtils.toTargetTypeDeclaration(targetType), null, new String[] { "java/lang/Exception" }); mv.visitCode(); mv.visitFieldInsn(GETFIELD,classType, "builderInstantiator", AsmUtils.toTargetTypeDeclaration(INSTANTIATOR_CLASS)); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKEINTERFACE, AsmUtils.toAsmType(INSTANTIATOR_CLASS), "newInstance", "(Ljava/lang/Object;)Ljava/lang/Object;", true); final Type builderClass = getTargetType(instantiatorDefinition.getBuilderInstantiator()); final String builderType = AsmUtils.toAsmType(builderClass); mv.visitTypeInsn(CHECKCAST, builderType); if (Modifier.isStatic(buildMethod.getModifiers())) { mv.visitMethodInsn(INVOKESTATIC, AsmUtils.toAsmType(buildMethod.getDeclaringClass()), buildMethod.getName(), AsmUtils.toSignature(buildMethod), false); } else { AsmUtils.invoke(mv, TypeHelper.toClass(builderClass), buildMethod.getName(), AsmUtils.toSignature(buildMethod));
@Override public void accept(MethodVisitor mv) { if (checkIfNull) { mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(AsmUtils.getLoadOps(parameterType), 3); } AsmUtils.invoke(mv, TypeHelper.toClass(builderClass), e.getValue().getName(), AsmUtils.toSignature(e.getValue())); if (!Void.TYPE.equals(e.getValue().getReturnType())) { mv.visitVarInsn(ASTORE, 2); } } }, ignoreNullValues);
@Test public void testToAsmType() { assertEquals("java/lang/String", AsmUtils.toAsmType(String.class)); assertEquals("java/lang/String", AsmUtils.toGenericAsmType(String.class)); assertEquals("java/util/HashMap", AsmUtils.toAsmType(new HashMap<String, Long>() {}.getClass().getGenericSuperclass())); assertEquals("java/util/HashMap<Ljava/lang/String;Ljava/lang/Long;>", AsmUtils.toGenericAsmType(new HashMap<String, Long>() {}.getClass().getGenericSuperclass())); }
public static String toSignature(Method exec) { StringBuilder sb = new StringBuilder(); sb.append("("); for(Class<?> clazz : exec.getParameterTypes()) { sb.append(AsmUtils.toTargetTypeDeclaration(clazz)); } sb.append(")"); sb.append(AsmUtils.toTargetTypeDeclaration(exec.getReturnType())); return sb.toString(); }
private static void appendSet(Method method, ClassWriter cw, Class<?> target, String targetType, String propertyType, String classType) { MethodVisitor mv; { mv = cw.visitMethod(ACC_PUBLIC, "set", "(" + AsmUtils.toTargetTypeDeclaration(targetType) + AsmUtils.toTargetTypeDeclaration(propertyType) + ")V", null, new String[] { "java/lang/Exception" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); AsmUtils.invoke(mv, target, method.getName(), "(" + AsmUtils.toTargetTypeDeclaration(propertyType) + ")" + AsmUtils.toTargetTypeDeclaration(method.getReturnType())); mv.visitInsn(RETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } appendSynthetic(cw, targetType, propertyType, classType); }