/** * Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} * instance (or {@literal null}) each time it is called, i.e., it should not return a previously * returned visitor. * * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if * the method is synthetic and/or deprecated. * @param name the method's name. * @param descriptor the method's descriptor (see {@link Type}). * @param signature the method's signature. May be {@literal null} if the method parameters, * return type and exceptions do not use generic types. * @param exceptions the internal names of the method's exception classes (see {@link * Type#getInternalName()}). May be {@literal null}. * @return an object to visit the byte code of the method, or {@literal null} if this class * visitor is not interested in visiting the code of this method. */ public MethodVisitor visitMethod( final int access, final String name, final String descriptor, final String signature, final String[] exceptions) { if (cv != null) { return cv.visitMethod(access, name, descriptor, signature, exceptions); } return null; }
/** * Creates proxified methods and constructors. * Destination proxy will have all constructors as a target class, using {@link jodd.proxetta.asm.ProxettaCtorBuilder}. * Static initializers are removed, since they will be execute in target anyway. * For each method, {@link ProxettaMethodBuilder} determines if method matches pointcut. If so, method will be proxified. */ @Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { final MethodSignatureVisitor msign = targetClassInfo.lookupMethodSignatureVisitor(access, name, desc, wd.superReference); if (msign == null) { return null; } if (msign.isFinal && !wd.allowFinalMethods) { return null; } // destination constructors [A1] if (name.equals(INIT)) { MethodVisitor mv = wd.dest.visitMethod(access, name, desc, msign.getAsmMethodSignature(), null); return new ProxettaCtorBuilder(mv, msign, wd); } // ignore destination static block if (name.equals(CLINIT)) { return null; } return applyProxy(msign); }
access |= AsmUtil.ACC_PRIVATE | AsmUtil.ACC_FINAL; wd.addAdviceClinitMethod(name); return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) { access = ProxettaAsmUtil.makePrivateFinalAccess(access); wd.addAdviceInitMethod(name); return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) { @Override public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, final Label end, final int index) { return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) {
/** * Creates static initialization block that simply calls all * advice static init methods in correct order. */ protected void makeStaticInitBlock() { if (wd.adviceClinits != null) { MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_STATIC, CLINIT, DESC_VOID, null, null); mv.visitCode(); for (String name : wd.adviceClinits) { mv.visitMethodInsn( INVOKESTATIC, wd.thisReference, name, DESC_VOID, false); } mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } }
/** * Created empty default constructor. */ protected void createEmptyCtor() { final MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_PUBLIC, INIT, "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, AsmUtil.SIGNATURE_JAVA_LANG_OBJECT, INIT, "()V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); }
/** * Starts creation of first chain delegate. */ protected void createFirstChainDelegate_Start() { // check invalid access flags int access = msign.getAccessFlags(); if (!wd.allowFinalMethods) { if ((access & AsmUtil.ACC_FINAL) != 0) { // detect final throw new ProxettaException( "Unable to create proxy for final method: " + msign + ". Remove final modifier or change the pointcut definition."); } } // create proxy methods tmd = new TargetMethodData(msign, aspectList); access &= ~ACC_NATIVE; access &= ~ACC_ABSTRACT; methodVisitor = wd.dest.visitMethod( access, tmd.msign.getMethodName(), tmd.msign.getDescription(), tmd.msign.getAsmMethodSignature(), null); }
/** * Creates init method that simply calls all advice constructor methods in correct order. * This created init method is called from each destination's constructor. */ protected void makeProxyConstructor() { MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_PRIVATE | AsmUtil.ACC_FINAL, ProxettaNames.initMethodName, DESC_VOID, null, null); mv.visitCode(); if (wd.adviceInits != null) { for (String name : wd.adviceInits) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn (INVOKESPECIAL, wd.thisReference, name, DESC_VOID, false); } } mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
access &= ~ACC_NATIVE; MethodVisitor mv = wd.dest.visitMethod( access, msign.getMethodName(), msign.getDescription(), msign.getAsmMethodSignature(), msign.getExceptions()); mv.visitCode();
protected void createEmptyCtorThatCreatesTarget() { final MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, AsmUtil.SIGNATURE_JAVA_LANG_OBJECT, INIT, "()V", false); mv.visitVarInsn(ALOAD, 0); mv.visitTypeInsn(Opcodes.NEW, wd.superReference); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, wd.superReference, INIT, "()V", false); mv.visitFieldInsn(Opcodes.PUTFIELD, wd.thisReference, wd.wrapperRef, wd.wrapperType); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(3, 1); mv.visitEnd(); }
classVisitor.visitMethod( context.currentMethodAccessFlags, context.currentMethodName,
access = ProxettaAsmUtil.makePrivateFinalAccess(access); final MethodVisitor mv = wd.dest.visitMethod(access, td.methodName(), td.msign.getDescription(), null, null); mv.visitCode();
/** * Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} * instance (or {@literal null}) each time it is called, i.e., it should not return a previously * returned visitor. * * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if * the method is synthetic and/or deprecated. * @param name the method's name. * @param descriptor the method's descriptor (see {@link Type}). * @param signature the method's signature. May be {@literal null} if the method parameters, * return type and exceptions do not use generic types. * @param exceptions the internal names of the method's exception classes (see {@link * Type#getInternalName()}). May be {@literal null}. * @return an object to visit the byte code of the method, or {@literal null} if this class * visitor is not interested in visiting the code of this method. */ public MethodVisitor visitMethod( final int access, final String name, final String descriptor, final String signature, final String[] exceptions) { if (cv != null) { return cv.visitMethod(access, name, descriptor, signature, exceptions); } return null; }
/** * Creates proxified methods and constructors. * Destination proxy will have all constructors as a target class, using {@link jodd.proxetta.asm.ProxettaCtorBuilder}. * Static initializers are removed, since they will be execute in target anyway. * For each method, {@link ProxettaMethodBuilder} determines if method matches pointcut. If so, method will be proxified. */ @Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { final MethodSignatureVisitor msign = targetClassInfo.lookupMethodSignatureVisitor(access, name, desc, wd.superReference); if (msign == null) { return null; } if (msign.isFinal && !wd.allowFinalMethods) { return null; } // destination constructors [A1] if (name.equals(INIT)) { MethodVisitor mv = wd.dest.visitMethod(access, name, desc, msign.getAsmMethodSignature(), null); return new ProxettaCtorBuilder(mv, msign, wd); } // ignore destination static block if (name.equals(CLINIT)) { return null; } return applyProxy(msign); }
access |= AsmUtil.ACC_PRIVATE | AsmUtil.ACC_FINAL; wd.addAdviceClinitMethod(name); return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) { access = ProxettaAsmUtil.makePrivateFinalAccess(access); wd.addAdviceInitMethod(name); return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) { @Override public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, final Label end, final int index) { return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) {
/** * Creates static initialization block that simply calls all * advice static init methods in correct order. */ protected void makeStaticInitBlock() { if (wd.adviceClinits != null) { MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_STATIC, CLINIT, DESC_VOID, null, null); mv.visitCode(); for (String name : wd.adviceClinits) { mv.visitMethodInsn( INVOKESTATIC, wd.thisReference, name, DESC_VOID, false); } mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } }
/** * Created empty default constructor. */ protected void createEmptyCtor() { final MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_PUBLIC, INIT, "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, AsmUtil.SIGNATURE_JAVA_LANG_OBJECT, INIT, "()V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); }
/** * Creates init method that simply calls all advice constructor methods in correct order. * This created init method is called from each destination's constructor. */ protected void makeProxyConstructor() { MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_PRIVATE | AsmUtil.ACC_FINAL, ProxettaNames.initMethodName, DESC_VOID, null, null); mv.visitCode(); if (wd.adviceInits != null) { for (String name : wd.adviceInits) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn (INVOKESPECIAL, wd.thisReference, name, DESC_VOID, false); } } mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
/** * Starts creation of first chain delegate. */ protected void createFirstChainDelegate_Start() { // check invalid access flags int access = msign.getAccessFlags(); if (!wd.allowFinalMethods) { if ((access & AsmUtil.ACC_FINAL) != 0) { // detect final throw new ProxettaException( "Unable to create proxy for final method: " + msign + ". Remove final modifier or change the pointcut definition."); } } // create proxy methods tmd = new TargetMethodData(msign, aspectList); access &= ~ACC_NATIVE; access &= ~ACC_ABSTRACT; methodVisitor = wd.dest.visitMethod( access, tmd.msign.getMethodName(), tmd.msign.getDescription(), tmd.msign.getAsmMethodSignature(), null); }
access &= ~ACC_NATIVE; MethodVisitor mv = wd.dest.visitMethod( access, msign.getMethodName(), msign.getDescription(), msign.getAsmMethodSignature(), msign.getExceptions()); mv.visitCode();
protected void createEmptyCtorThatCreatesTarget() { final MethodVisitor mv = wd.dest.visitMethod(AsmUtil.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, AsmUtil.SIGNATURE_JAVA_LANG_OBJECT, INIT, "()V", false); mv.visitVarInsn(ALOAD, 0); mv.visitTypeInsn(Opcodes.NEW, wd.superReference); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, wd.superReference, INIT, "()V", false); mv.visitFieldInsn(Opcodes.PUTFIELD, wd.thisReference, wd.wrapperRef, wd.wrapperType); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(3, 1); mv.visitEnd(); }