public void addGetter(MetaBeanProperty property) throws Exception { MetaMethod getter = property.getGetter(); // GENERATE private boolean <prop>Set; String flagName = String.format("%sSet", property.getName()); visitor.visitField( Opcodes.ACC_PRIVATE, flagName, Type.BOOLEAN_TYPE.getDescriptor(), null, null); addConventionGetter(getter.getName(), flagName, property); String getterName = getter.getName(); Class<?> returnType = getter.getReturnType(); // If it's a boolean property, there can be get or is type variants. // If this class has both, decorate both. if (returnType.equals(Boolean.TYPE)) { boolean getterIsIsMethod = getterName.startsWith("is"); String propertyNameComponent = getterName.substring(getterIsIsMethod ? 2 : 3); String alternativeGetterName = String.format("%s%s", getterIsIsMethod ? "get" : "is", propertyNameComponent); try { type.getMethod(alternativeGetterName); addConventionGetter(alternativeGetterName, flagName, property); } catch (NoSuchMethodException e) { // ignore, no method to override } } }
public void mixInConventionAware() throws Exception { // GENERATE private ConventionMapping mapping = new ConventionAwareHelper(this, // getConvention()) final String mappingFieldSignature = "L" + ConventionMapping.class.getName().replaceAll("\\.", "/") + ";"; final String getConventionDesc = Type.getMethodDescriptor(conventionType, new Type[0]); visitor.visitField(Opcodes.ACC_PRIVATE, "mapping", mappingFieldSignature, null, null); initConventionAwareHelper = new MethodCodeBody() { public void add(MethodVisitor visitor) throws Exception { Type helperType = Type.getType(ConventionAwareHelper.class); // GENERATE mapping = new ConventionAwareHelper(this, getConvention()) visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitTypeInsn(Opcodes.NEW, helperType.getInternalName()); visitor.visitInsn(Opcodes.DUP); visitor.visitVarInsn(Opcodes.ALOAD, 0); // GENERATE getConvention() visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, generatedType.getInternalName(), "getConvention", getConventionDesc); // END String constructorDesc = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {conventionAwareType, conventionType}); visitor.visitMethodInsn( Opcodes.INVOKESPECIAL, helperType.getInternalName(), "<init>", constructorDesc); visitor.visitFieldInsn( Opcodes.PUTFIELD, generatedType.getInternalName(), "mapping", mappingFieldSignature); // END } }; // END // GENERATE public ConventionMapping getConventionMapping() { if (mapping != null) { return // mapping; } else { return new ConventionAwareHelper(this); } } // the null check is for when getConventionMapping() is called by a superclass constructor (eg // when the constructor calls a getter method) addGetter( IConventionAware.class.getDeclaredMethod("getConventionMapping"), new MethodCodeBody() { public void add(MethodVisitor visitor) { // GENERATE if (mapping != null) {... } visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, generatedType.getInternalName(), "mapping", mappingFieldSignature); visitor.visitInsn(Opcodes.DUP); Label nullBranch = new Label(); visitor.visitJumpInsn(Opcodes.IFNULL, nullBranch); visitor.visitInsn(Opcodes.ARETURN); // GENERATE else { return new ConventionAwareHelper(this); } visitor.visitLabel(nullBranch); Type conventionAwareHelperType = Type.getType(ConventionAwareHelper.class); String constructorDesc = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {Type.getType(IConventionAware.class)}); visitor.visitTypeInsn(Opcodes.NEW, conventionAwareHelperType.getInternalName()); visitor.visitInsn(Opcodes.DUP); visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitMethodInsn( Opcodes.INVOKESPECIAL, conventionAwareHelperType.getInternalName(), "<init>", constructorDesc); visitor.visitInsn(Opcodes.ARETURN); } }); }
public void mixInGroovyObject() throws Exception { // GENERATE private MetaClass metaClass = // GroovySystem.getMetaClassRegistry().getMetaClass(getClass()) final String metaClassFieldSignature = "L" + MetaClass.class.getName().replaceAll("\\.", "/") + ";"; visitor.visitField(Opcodes.ACC_PRIVATE, "metaClass", metaClassFieldSignature, null, null); initMetaClass = new MethodCodeBody() { public void add(MethodVisitor visitor) throws Exception { visitor.visitVarInsn(Opcodes.ALOAD, 0); // GroovySystem.getMetaClassRegistry() String getMetaClassRegistryDesc = Type.getMethodDescriptor( GroovySystem.class.getDeclaredMethod("getMetaClassRegistry")); visitor.visitMethodInsn( Opcodes.INVOKESTATIC, Type.getType(GroovySystem.class).getInternalName(), "getMetaClassRegistry", getMetaClassRegistryDesc); // this.getClass() visitor.visitVarInsn(Opcodes.ALOAD, 0); String getClassDesc = Type.getMethodDescriptor(Object.class.getDeclaredMethod("getClass")); visitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, Type.getType(Object.class).getInternalName(), "getClass", getClassDesc); // getMetaClass(..) String getMetaClassDesc = Type.getMethodDescriptor( MetaClassRegistry.class.getDeclaredMethod("getMetaClass", Class.class)); visitor.visitMethodInsn( Opcodes.INVOKEINTERFACE, Type.getType(MetaClassRegistry.class).getInternalName(), "getMetaClass", getMetaClassDesc); visitor.visitFieldInsn( Opcodes.PUTFIELD, generatedType.getInternalName(), "metaClass", metaClassFieldSignature); } }; // GENERATE public MetaClass getMetaClass() { return metaClass } addGetter( GroovyObject.class.getDeclaredMethod("getMetaClass"), new MethodCodeBody() { public void add(MethodVisitor visitor) throws Exception { visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, generatedType.getInternalName(), "metaClass", metaClassFieldSignature); } }); // GENERATE public void setMetaClass(MetaClass class) { this.metaClass = class; } addSetter( GroovyObject.class.getDeclaredMethod("setMetaClass", MetaClass.class), new MethodCodeBody() { public void add(MethodVisitor visitor) throws Exception { visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitVarInsn(Opcodes.ALOAD, 1); visitor.visitFieldInsn( Opcodes.PUTFIELD, generatedType.getInternalName(), "metaClass", metaClassFieldSignature); } }); }
public void mixInDynamicAware() throws Exception { final Type helperType = Type.getType(MixInExtensibleDynamicObject.class); // GENERATE private MixInExtensibleDynamicObject dynamicObjectHelper = new // MixInExtensibleDynamicObject(this, super.getAsDynamicObject()) final String fieldSignature = "L" + MixInExtensibleDynamicObject.class.getName().replaceAll("\\.", "/") + ";"; visitor.visitField(Opcodes.ACC_PRIVATE, "dynamicObjectHelper", fieldSignature, null, null); initDynamicObjectHelper = new MethodCodeBody() { public void add(MethodVisitor visitor) throws Exception { String helperTypeConstructorDesc = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {Type.getType(Object.class), dynamicObjectType}); // GENERATE dynamicObjectHelper = new MixInExtensibleDynamicObject(this, // super.getAsDynamicObject()) visitor.visitVarInsn(Opcodes.ALOAD, 0); // GENERATE new MixInExtensibleDynamicObject(this, super.getAsDynamicObject()) visitor.visitTypeInsn(Opcodes.NEW, helperType.getInternalName()); visitor.visitInsn(Opcodes.DUP); visitor.visitVarInsn(Opcodes.ALOAD, 0); boolean useInheritedDynamicObject = GroovySystem.getMetaClassRegistry() .getMetaClass(type) .pickMethod("getAsDynamicObject", new Class[0]) != null; if (useInheritedDynamicObject) { // GENERATE super.getAsDynamicObject() visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getType(type).getInternalName(), "getAsDynamicObject", Type.getMethodDescriptor(dynamicObjectType, new Type[0])); } else { // GENERATE null visitor.visitInsn(Opcodes.ACONST_NULL); } visitor.visitMethodInsn( Opcodes.INVOKESPECIAL, helperType.getInternalName(), "<init>", helperTypeConstructorDesc); // END visitor.visitFieldInsn( Opcodes.PUTFIELD, generatedType.getInternalName(), "dynamicObjectHelper", fieldSignature); // END } }; // END // GENERATE public Convention getConvention() { return dynamicObjectHelper.getConvention(); } addGetter( HasConvention.class.getDeclaredMethod("getConvention"), new MethodCodeBody() { public void add(MethodVisitor visitor) throws Exception { // GENERATE dynamicObjectHelper.getConvention() visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, generatedType.getInternalName(), "dynamicObjectHelper", fieldSignature); String getterDescriptor = Type.getMethodDescriptor( ExtensibleDynamicObject.class.getDeclaredMethod("getConvention")); visitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, helperType.getInternalName(), "getConvention", getterDescriptor); } }); // END // GENERATE public ExtensionContainer getExtensions() { return getConvention(); } addGetter( ExtensionAware.class.getDeclaredMethod("getExtensions"), new MethodCodeBody() { public void add(MethodVisitor visitor) throws Exception { // GENERATE getConvention() visitor.visitVarInsn(Opcodes.ALOAD, 0); String getterDescriptor = Type.getMethodDescriptor( ExtensibleDynamicObject.class.getDeclaredMethod("getConvention")); visitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, generatedType.getInternalName(), "getConvention", getterDescriptor); } }); // END // GENERATE public DynamicObject.getAsDynamicObject() { return dynamicObjectHelper; } addGetter( DynamicObjectAware.class.getDeclaredMethod("getAsDynamicObject"), new MethodCodeBody() { public void add(MethodVisitor visitor) { // GENERATE dynamicObjectHelper visitor.visitVarInsn(Opcodes.ALOAD, 0); visitor.visitFieldInsn( Opcodes.GETFIELD, generatedType.getInternalName(), "dynamicObjectHelper", fieldSignature); } }); // END }