private ClassMetaData inspectType(Class<?> type) { boolean isConventionAware = type.getAnnotation(NoConventionMapping.class) == null; boolean extensible = JavaReflectionUtil.getAnnotation(type, NonExtensible.class) == null; ClassMetaData classMetaData = new ClassMetaData(extensible, isConventionAware); inspectType(type, classMetaData); attachSetMethods(classMetaData); findMissingClosureOverloads(classMetaData); classMetaData.complete(); return classMetaData; }
private void addConventionGetter(String getterName, String flagName, MetaBeanProperty property) throws Exception { // GENERATE public <type> <getter>() { return // (<type>)getConventionMapping().getConventionValue(super.<getter>(), '<prop>', <prop>Set); } MetaMethod getter = property.getGetter(); Type returnType = Type.getType(getter.getReturnType()); String methodDescriptor = Type.getMethodDescriptor(returnType, new Type[0]); MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, getterName, methodDescriptor, null, new String[0]); methodVisitor.visitCode(); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn( Opcodes.INVOKEINTERFACE, conventionAwareType.getInternalName(), "getConventionMapping", Type.getMethodDescriptor(conventionMappingType, new Type[0])); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn( Opcodes.INVOKESPECIAL, superclassType.getInternalName(), getterName, methodDescriptor); Type boxedType = null; if (getter.getReturnType().isPrimitive()) { // Box value boxedType = Type.getType(JavaReflectionUtil.getWrapperTypeForPrimitiveType(getter.getReturnType())); String valueOfMethodDescriptor = Type.getMethodDescriptor(boxedType, new Type[] {returnType}); methodVisitor.visitMethodInsn( Opcodes.INVOKESTATIC, boxedType.getInternalName(), "valueOf", valueOfMethodDescriptor); } methodVisitor.visitLdcInsn(property.getName()); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitFieldInsn( Opcodes.GETFIELD, generatedType.getInternalName(), flagName, Type.BOOLEAN_TYPE.getDescriptor()); String getConventionValueDesc = Type.getMethodDescriptor( ConventionMapping.class.getMethod( "getConventionValue", Object.class, String.class, Boolean.TYPE)); methodVisitor.visitMethodInsn( Opcodes.INVOKEINTERFACE, conventionMappingType.getInternalName(), "getConventionValue", getConventionValueDesc); if (getter.getReturnType().isPrimitive()) { // Unbox value methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, boxedType.getInternalName()); String valueMethodDescriptor = Type.getMethodDescriptor(returnType, new Type[0]); methodVisitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, boxedType.getInternalName(), getter.getReturnType().getName() + "Value", valueMethodDescriptor); } else { // Cast to return type methodVisitor.visitTypeInsn( Opcodes.CHECKCAST, getter.getReturnType().isArray() ? "[" + returnType.getElementType().getDescriptor() : returnType.getInternalName()); } methodVisitor.visitInsn(returnType.getOpcode(Opcodes.IRETURN)); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }