diff options
author | avasseur <avasseur> | 2005-05-02 08:17:36 +0000 |
---|---|---|
committer | avasseur <avasseur> | 2005-05-02 08:17:36 +0000 |
commit | cdddd38d261f0ae75bf95f0859e7a440be1bb3d5 (patch) | |
tree | fa61448ab8b0d848cd65930fc5e9a44a71433ea8 /weaver | |
parent | 0b7744f560fb4ff70b70884a4932c8ebeb603fd2 (diff) | |
download | aspectj-cdddd38d261f0ae75bf95f0859e7a440be1bb3d5.tar.gz aspectj-cdddd38d261f0ae75bf95f0859e7a440be1bb3d5.zip |
PTW perClause for @AJ + perClause test
Diffstat (limited to 'weaver')
3 files changed, 244 insertions, 40 deletions
diff --git a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java index d285a1574..428c0b4b8 100644 --- a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java +++ b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java @@ -160,7 +160,15 @@ public class AjcMemberMaker { TypeX.forSignature("Ljava/lang/String;"), NameMangler.PERTYPEWITHIN_WITHINTYPEFIELD, TypeX.NONE); } - + public static ResolvedMember perTypeWithinPerClassMapField(ResolvedTypeX aspectType) { + int modifiers = Modifier.PRIVATE; + if (!TypeX.SERIALIZABLE.isAssignableFrom(aspectType, aspectType.getWorld())) { + modifiers |= Modifier.TRANSIENT; + } + return new ResolvedMember(Member.FIELD, aspectType, modifiers, + TypeX.forSignature("Ljava/util/Map;"), "instances", TypeX.NONE); + } + public static ResolvedMember perObjectBind(TypeX declaringType) { return new ResolvedMember( Member.METHOD, @@ -184,7 +192,22 @@ public class AjcMemberMaker { ); return rm; } - + + // PTWIMPL ResolvedMember for "Set getInstances()" method, declared in aspect + public static ResolvedMember perTypeWithinGetInstancesSet(TypeX declaringType) { +// public Set getInstances() + ResolvedMember rm = new ResolvedMember( + Member.METHOD, + declaringType, + Modifier.PUBLIC, + TypeX.forSignature("Ljava/util/Set;"), + "getInstances", + TypeX.NONE, + TypeX.NONE + ); + return rm; + } + public static ResolvedMember perTypeWithinCreateAspectInstance(TypeX declaringType) { // public static a.X ajc$createAspectInstance(java.lang.String) ResolvedMember rm = new ResolvedMember( diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java index 7f759c721..254f429fe 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java @@ -27,6 +27,13 @@ import org.aspectj.apache.bcel.generic.POP; import org.aspectj.apache.bcel.generic.PUSH; import org.aspectj.apache.bcel.generic.ReferenceType; import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.apache.bcel.generic.MethodGen; +import org.aspectj.apache.bcel.generic.RETURN; +import org.aspectj.apache.bcel.generic.NEW; +import org.aspectj.apache.bcel.generic.INVOKESPECIAL; +import org.aspectj.apache.bcel.generic.ASTORE; +import org.aspectj.apache.bcel.generic.ACONST_NULL; +import org.aspectj.apache.bcel.generic.IRETURN; import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.Member; import org.aspectj.weaver.NameMangler; @@ -35,6 +42,8 @@ import org.aspectj.weaver.ResolvedTypeX; import org.aspectj.weaver.TypeX; import org.aspectj.weaver.patterns.PerClause; +import java.util.Iterator; + /** * Adds aspectOf, hasAspect etc to the annotation defined aspects * @@ -58,8 +67,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { public boolean munge(BcelClassWeaver weaver) { LazyClassGen gen = weaver.getLazyClassGen(); - // agressively generate the inner interface + // agressively generate the inner interface if any + // Note: we do so because of the bug that leads to have this interface implemented by all classes and not + // only those matched by the per clause, which fails under LTW since the very first class + // gets weaved and impl this interface that is still not defined. if (!hasGeneratedInner) { + //FIXME AV - restore test below or ?? + add test to detect such side effect //if (kind == PerClause.PEROBJECT || kind == PerClause.PERCFLOW) { //inner class TypeX interfaceTypeX = AjcMemberMaker.perObjectInterfaceType(aspectType); @@ -99,6 +112,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { generatePerCflowHasAspectMethod(gen); generatePerCflowPushMethod(gen); generatePerCflowAjcClinitMethod(gen); + } else if (kind == PerClause.PERTYPEWITHIN) { + generatePerTWGetInstancesMethod(gen); + generatePerTWAspectOfMethod(gen); + generatePerTWHasAspectMethod(gen); + generatePerTWGetInstanceMethod(gen); + generatePerTWCreateAspectInstanceMethod(gen); } else { throw new RuntimeException("TODO not yet implemented perClause " + kind.getName()); } @@ -135,31 +154,45 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { } else if (kind == PerClause.PEROBJECT) { ResolvedMember perObjectFieldInfo = AjcMemberMaker.perObjectField(aspectType, aspectType); classGen.addField(makeFieldGen(classGen, perObjectFieldInfo).getField(), null); - -// //inner class -// TypeX interfaceTypeX = AjcMemberMaker.perObjectInterfaceType(aspectType); -// LazyClassGen interfaceGen = new LazyClassGen( -// interfaceTypeX.getName(), -// "java.lang.Object", -// null, -// Constants.ACC_PRIVATE + Constants.ACC_ABSTRACT, -// new String[0] -// ); -// interfaceGen.addMethodGen(makeMethodGen(interfaceGen, AjcMemberMaker.perObjectInterfaceGet(aspectType))); -// interfaceGen.addMethodGen(makeMethodGen(interfaceGen, AjcMemberMaker.perObjectInterfaceSet(aspectType))); -// classGen.addGeneratedInner(interfaceGen); + // if lazy generation of the inner interface MayHaveAspect works on LTW (see previous note) + // it should be done here. } else if (kind == PerClause.PERCFLOW) { ResolvedMember perCflowFieldInfo = AjcMemberMaker.perCflowField(aspectType); classGen.addField(makeFieldGen(classGen, perCflowFieldInfo).getField(), null); + } else if (kind == PerClause.PERTYPEWITHIN) { + ResolvedMember perTypeWithinForField = AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType); + classGen.addField(makeFieldGen(classGen, perTypeWithinForField).getField(), null); + ResolvedMember perTypeWithinPerClassMapField = AjcMemberMaker.perTypeWithinPerClassMapField(aspectType); + classGen.addField(makeFieldGen(classGen, perTypeWithinPerClassMapField).getField(), null); + // we need to initialize this map as a WeakHashMap in the aspect constructor(s) + InstructionFactory factory = classGen.getFactory(); + for (Iterator iterator = classGen.getMethodGens().iterator(); iterator.hasNext();) { + LazyMethodGen methodGen = (LazyMethodGen) iterator.next(); + if ("<init>".equals(methodGen.getName())) { + InstructionList il = new InstructionList(); + il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createGet(factory, perTypeWithinPerClassMapField)); + BranchInstruction ifNotNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); + il.append(ifNotNull); + il.append(InstructionConstants.ALOAD_0); + il.append(factory.createNew("java/util/WeakHashMap")); + il.append(new DUP()); + il.append(factory.createInvoke( + "java/util/WeakHashMap", + "<init>", + Type.VOID, + Type.NO_ARGS, + Constants.INVOKESPECIAL + )); + il.append(Utility.createSet(factory, perTypeWithinPerClassMapField)); + InstructionHandle currentEnd = methodGen.getBody().getEnd(); + ifNotNull.setTarget(currentEnd); + methodGen.getBody().insert(currentEnd, il); + } + } } else { - throw new RuntimeException("TODO not implemented yet"); + throw new Error("Should not happen - no such kind " + kind.toString()); } -// } else if (kind == PerClause.PERTYPEWITHIN) { -// //PTWIMPL Add field for storing typename in aspect for which the aspect instance exists -// binding.addField(factory.makeFieldBinding(AjcMemberMaker.perTypeWithinWithinTypeField(typeX,typeX))); -// } else { -// throw new RuntimeException("unimplemented"); -// } } private void generatePerSingletonAspectOfMethod(LazyClassGen classGen) { @@ -217,8 +250,8 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { InstructionHandle tryStart = il.append(factory.createInvoke(aspectType.getName(), NameMangler.AJC_POST_CLINIT_NAME, Type.VOID, Type.NO_ARGS, Constants.INVOKESTATIC)); BranchInstruction tryEnd = InstructionFactory.createBranchInstruction(Constants.GOTO, null); il.append(tryEnd); - InstructionHandle handler = il.append(InstructionFactory.createStore(Type.OBJECT, 0)); - il.append(InstructionFactory.createLoad(Type.OBJECT, 0)); + InstructionHandle handler = il.append(InstructionConstants.ASTORE_0); + il.append(InstructionConstants.ALOAD_0); il.append(Utility.createSet(factory, AjcMemberMaker.initFailureCauseField(aspectType))); il.append(InstructionFactory.createReturn(Type.VOID)); tryEnd.setTarget(il.getEnd()); @@ -239,14 +272,14 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(method); InstructionList il = method.getBody(); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createInstanceOf(interfaceType)); BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(ifEq); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); - il.append(new DUP()); + il.append(InstructionConstants.DUP); BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); il.append(ifNull); il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(aspectType))); @@ -254,7 +287,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { ifNull.setTarget(ifNullElse); InstructionHandle ifEqElse = il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); ifEq.setTarget(ifEqElse); - il.append(new DUP()); + il.append(InstructionConstants.DUP); il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); il.append(new ATHROW()); } @@ -266,20 +299,20 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(method); InstructionList il = method.getBody(); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createInstanceOf(interfaceType)); BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(ifEq); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); il.append(ifNull); - il.append(new ICONST(1));//TODO is ok ? else Push boolean + il.append(InstructionConstants.ICONST_1); il.append(InstructionFactory.createReturn(Type.INT)); - InstructionHandle ifEqElse = il.append(new ICONST(0)); + InstructionHandle ifEqElse = il.append(InstructionConstants.ICONST_0); ifEq.setTarget(ifEqElse); - ifNull.setTarget(ifEqElse);//?? + ifNull.setTarget(ifEqElse);//??//FIXME AV - ok or what ? il.append(InstructionFactory.createReturn(Type.INT)); } @@ -290,16 +323,16 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(method); InstructionList il = method.getBody(); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createInstanceOf(interfaceType)); BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(ifEq); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); il.append(ifNonNull); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(factory.createNew(aspectType.getName())); il.append(InstructionConstants.DUP); @@ -317,7 +350,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(methodGet); InstructionList ilGet = methodGet.getBody(); ilGet = new InstructionList(); - ilGet.append(new ALOAD(0)); + ilGet.append(InstructionConstants.ALOAD_0); ilGet.append(Utility.createGet(factory, AjcMemberMaker.perObjectField(aspectType, aspectType))); ilGet.append(InstructionFactory.createReturn(Type.OBJECT)); @@ -325,8 +358,8 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(methodSet); InstructionList ilSet = methodSet.getBody(); ilSet = new InstructionList(); - ilSet.append(new ALOAD(0)); - ilSet.append(new ALOAD(1)); + ilSet.append(InstructionConstants.ALOAD_0); + ilSet.append(InstructionConstants.ALOAD_1); ilSet.append(Utility.createSet(factory, AjcMemberMaker.perObjectField(aspectType, aspectType))); ilSet.append(InstructionFactory.createReturn(Type.VOID)); } @@ -387,4 +420,144 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { clinit.getBody().insert(il); } + private void generatePerTWGetInstancesMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinGetInstancesSet(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createGet(factory, AjcMemberMaker.perTypeWithinPerClassMapField(aspectType))); + il.append(factory.createInvoke( + "java/util/Map", "keySet", Type.getType("Ljava/util/Set;"), Type.NO_ARGS, Constants.INVOKEINTERFACE + )); + il.append(InstructionFactory.createReturn(Type.OBJECT)); + } + + private void generatePerTWAspectOfMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinAspectOfMethod(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0); + + il.append(Utility.createInvoke( + factory, + Constants.INVOKESTATIC, + AjcMemberMaker.perTypeWithinGetInstance(aspectType) + )); + il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ALOAD_1); + BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); + il.append(ifNonNull); + il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); + il.append(InstructionConstants.DUP); + il.append(new PUSH(classGen.getConstantPoolGen(), aspectType.getName())); + il.append(InstructionConstants.ACONST_NULL); + il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, new Type[] { Type.STRING, new ObjectType("java.lang.Throwable") }, Constants.INVOKESPECIAL)); + il.append(InstructionConstants.ATHROW); + InstructionHandle ifElse = il.append(InstructionConstants.ALOAD_1); + ifNonNull.setTarget(ifElse); + il.append(InstructionFactory.createReturn(Type.OBJECT)); + + InstructionHandle handler = il.append(InstructionConstants.ASTORE_1); + il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); + il.append(InstructionConstants.DUP); + il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + il.append(InstructionConstants.ATHROW); + + method.addExceptionHandler( + tryStart, handler.getPrev(), handler, new ObjectType("java.lang.Exception"), false + ); + } + + private void generatePerTWHasAspectMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinHasAspectMethod(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createInvoke( + factory, + Constants.INVOKESTATIC, + AjcMemberMaker.perTypeWithinGetInstance(aspectType) + )); + BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); + il.append(ifNull); + il.append(InstructionConstants.ICONST_1); + il.append(InstructionConstants.IRETURN); + InstructionHandle ifElse = il.append(InstructionConstants.ICONST_0); + ifNull.setTarget(ifElse); + il.append(InstructionConstants.IRETURN); + + InstructionHandle handler = il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ICONST_0); + il.append(InstructionConstants.IRETURN); + + method.addExceptionHandler( + tryStart, handler.getPrev(), handler, new ObjectType("java.lang.Exception"), false + ); + } + + private void generatePerTWGetInstanceMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinGetInstance(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0); + il.append(new PUSH(factory.getConstantPool(), NameMangler.perTypeWithinLocalAspectOf(aspectType))); + il.append(InstructionConstants.ACONST_NULL);//Class[] for "getDeclaredMethod" + il.append(factory.createInvoke( + "java/lang/Class", + "getDeclaredMethod", + Type.getType("Ljava/lang/reflect/Method;"), + new Type[]{Type.getType("Ljava/lang/String;"), Type.getType("[Ljava/lang/Class;")}, + Constants.INVOKEVIRTUAL + )); + il.append(InstructionConstants.ACONST_NULL);//Object for "invoke", static method + il.append(InstructionConstants.ACONST_NULL);//Object[] for "invoke", no arg + il.append(factory.createInvoke( + "java/lang/reflect/Method", + "invoke", + Type.OBJECT, + new Type[]{Type.getType("Ljava/lang/Object;"), Type.getType("[Ljava/lang/Object;")}, + Constants.INVOKEVIRTUAL + )); + il.append(factory.createCheckCast((ReferenceType) BcelWorld.makeBcelType(aspectType))); + il.append(InstructionConstants.ARETURN); + + InstructionHandle handler = il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ALOAD_1); + il.append(InstructionConstants.ATHROW); + + method.addExceptionHandler( + tryStart, handler.getPrev(), handler, new ObjectType("java.lang.Exception"), false + ); + } + + private void generatePerTWCreateAspectInstanceMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinCreateAspectInstance(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + il.append(factory.createNew(aspectType.getName())); + il.append(InstructionConstants.DUP); + il.append(factory.createInvoke( + aspectType.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL + )); + il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ALOAD_1); + il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createSet( + factory, + AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType) + )); + il.append(InstructionConstants.ALOAD_1); + il.append(InstructionConstants.ARETURN); + } + } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java index 151e3f2d7..df2db0cbb 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java @@ -145,6 +145,14 @@ public class PerTypeWithin extends PerClause { ResolvedTypeMunger munger = new PerTypeWithinTargetTypeMunger(inAspect, ret); inAspect.crosscuttingMembers.addTypeMunger(world.concreteTypeMunger(munger, inAspect)); + + //ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects + if (inAspect.isAnnotationStyleAspect()) { + inAspect.crosscuttingMembers.addTypeMunger( + inAspect.getWorld().makePerClauseAspect(inAspect, getKind()) + ); + } + return ret; } |