diff options
-rw-r--r-- | docs/adk15ProgGuideDB/pertypewithin.xml | 15 | ||||
-rw-r--r-- | org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java | 29 | ||||
-rw-r--r-- | tests/features152/synthetic/TheWholeShow.aj | 2 | ||||
-rw-r--r-- | tests/features153/ptw/CaseFive.java | 27 | ||||
-rw-r--r-- | tests/features153/ptw/CaseFour.java | 28 | ||||
-rw-r--r-- | tests/features153/ptw/CaseOne.java | 22 | ||||
-rw-r--r-- | tests/features153/ptw/CaseThree.java | 26 | ||||
-rw-r--r-- | tests/features153/ptw/CaseTwo.java | 26 | ||||
-rw-r--r-- | tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java | 5 | ||||
-rw-r--r-- | tests/src/org/aspectj/systemtest/ajc153/ajc153.xml | 53 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/AjcMemberMaker.java | 14 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/NameMangler.java | 1 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java | 18 |
13 files changed, 259 insertions, 7 deletions
diff --git a/docs/adk15ProgGuideDB/pertypewithin.xml b/docs/adk15ProgGuideDB/pertypewithin.xml index 8bab12b5d..4a5e9bbab 100644 --- a/docs/adk15ProgGuideDB/pertypewithin.xml +++ b/docs/adk15ProgGuideDB/pertypewithin.xml @@ -44,6 +44,21 @@ </para> <para> + In addition, <literal>pertypewithin</literal> aspects have a + <literal>getWithinTypeName</literal> method that can be called + to return the package qualified name of the type for which the + aspect instance has been created. + </para> + + <programlisting><![CDATA[ + /** + * return the package qualified name (eg. com.foo.MyClass) of the type + * for which the aspect instance has been instantiated. + */ + public String getWithinTypeName() + ]]></programlisting> + + <para> In common with the other per-clause instantiation models, the execution of any advice declared within a <literal>pertypewithin</literal> aspect is conditional upon an implicit pointcut condition. In this case, that diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java index 5d3595273..f49ffeb07 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java @@ -75,7 +75,7 @@ public class AspectDeclaration extends TypeDeclaration { private AjAttribute.Aspect aspectAttribute; public PerClause perClause; public ResolvedMember aspectOfMethod; - //public ResolvedMember ptwGetWithinTypeMethod; + public ResolvedMember ptwGetWithinTypeNameMethod; public ResolvedMember hasAspectMethod; @@ -368,8 +368,7 @@ public class AspectDeclaration extends TypeDeclaration { generatePerTypeWithinGetInstanceMethod(classFile); // private static <aspecttype> ajc$getInstance(Class c) throws Exception generatePerTypeWithinHasAspectMethod(classFile); generatePerTypeWithinCreateAspectInstanceMethod(classFile); // generate public static X ajc$createAspectInstance(Class forClass) { - // PTWIMPL getWithinType() would need this... - //generatePerTypeWithinGetWithinTypeMethod(classFile); // generate public Class getWithinType() { + generatePerTypeWithinGetWithinTypeNameMethod(classFile); } else { throw new RuntimeException("unimplemented"); } @@ -728,6 +727,26 @@ public class AspectDeclaration extends TypeDeclaration { }}); } + private void generatePerTypeWithinGetWithinTypeNameMethod(ClassFile classFile) { + final EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(this.scope); + // Code: + /* + Code: + Stack=1, Locals=1, Args_size=1 + 0: aload_0 + 1: getfield #14; //Field ajc$withinType:Ljava/lang/String; + 4: areturn + */ + generateMethod(classFile, AjcMemberMaker.perTypeWithinGetWithinTypeNameMethod(world.fromBinding(binding),world.getWorld().isInJava5Mode()), + new BodyGenerator() { + public void generate(CodeStream codeStream) { + ExceptionLabel exc = new ExceptionLabel(codeStream,world.makeTypeBinding(UnresolvedType.JAVA_LANG_EXCEPTION)); + exc.placeStart(); + codeStream.aload_0(); + codeStream.getfield(world.makeFieldBinding(AjcMemberMaker.perTypeWithinWithinTypeField(typeX,typeX))); + codeStream.areturn(); + }}); + } // PTWIMPL Generate getInstance method private void generatePerTypeWithinGetInstanceMethod(ClassFile classFile) { final EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(this.scope); @@ -1044,8 +1063,8 @@ public class AspectDeclaration extends TypeDeclaration { // PTWIMPL Use these variants of aspectOf()/hasAspect() aspectOfMethod = AjcMemberMaker.perTypeWithinAspectOfMethod(typeX,world.getWorld().isInJava5Mode()); hasAspectMethod = AjcMemberMaker.perTypeWithinHasAspectMethod(typeX,world.getWorld().isInJava5Mode()); - //ptwGetWithinTypeMethod = AjcMemberMaker.perTypeWithinGetWithinTypeMethod(typeX,world.getWorld().isInJava5Mode()); - //binding.addMethod(world.makeMethodBinding(ptwGetWithinTypeMethod)); + ptwGetWithinTypeNameMethod = AjcMemberMaker.perTypeWithinGetWithinTypeNameMethod(typeX,world.getWorld().isInJava5Mode()); + binding.addMethod(world.makeMethodBinding(ptwGetWithinTypeNameMethod)); } else { throw new RuntimeException("bad per clause: " + perClause); } diff --git a/tests/features152/synthetic/TheWholeShow.aj b/tests/features152/synthetic/TheWholeShow.aj index 7045c8192..0fa1c6642 100644 --- a/tests/features152/synthetic/TheWholeShow.aj +++ b/tests/features152/synthetic/TheWholeShow.aj @@ -58,7 +58,7 @@ public class TheWholeShow { for (Method m : ms) { if (!m.isSynthetic()) { String name = m.getName(); - if (name.equals("aspectOf") || name.equals("hasAspect")) continue; + if (name.equals("aspectOf") || name.equals("hasAspect") || name.equals("getWithinTypeName")) continue; if ( ! (name.startsWith("ajc$before") || name.startsWith("ajc$after") || name.startsWith("ajc$around") || name.startsWith("ajc$interMethod$"))) { System.err.println("Found non-synthetic method: " + m.getName() + " in " + c.getName()); diff --git a/tests/features153/ptw/CaseFive.java b/tests/features153/ptw/CaseFive.java new file mode 100644 index 000000000..e95edddd8 --- /dev/null +++ b/tests/features153/ptw/CaseFive.java @@ -0,0 +1,27 @@ +import java.lang.reflect.Method; + +import org.aspectj.lang.annotation.*; +import org.aspectj.lang.*; + +class AClass {} +class BClass {} +class CClass {} + +@Aspect("pertypewithin(*Class)") +public class CaseFive { + public static void main(String []argv) throws Exception { + new Runner().run(); + } +} + +class Runner { + public void run() throws Exception { + if (Aspects14.hasAspect(CaseFive.class,AClass.class)) { + System.out.println("AClass has an aspect instance"); + CaseFive instance = (CaseFive)Aspects14.aspectOf(CaseFive.class,AClass.class); + Method m = CaseFive.class.getDeclaredMethod("getWithinTypeName",null); + String s = (String)m.invoke(instance,null); + System.out.println("The aspect instance thinks it is for type name "+s); + } + } +} diff --git a/tests/features153/ptw/CaseFour.java b/tests/features153/ptw/CaseFour.java new file mode 100644 index 000000000..735bbd4e0 --- /dev/null +++ b/tests/features153/ptw/CaseFour.java @@ -0,0 +1,28 @@ +// Types in packages + +package a.b; + +class AClass {} +class BClass {} +class CClass {} + +public aspect CaseFour pertypewithin(*Class) { + public static void main(String []argv) { + new Runner().run(); + } +} + +class Runner { + public void run() { + CaseFour aInstance = (CaseFour.hasAspect(AClass.class)?CaseFour.aspectOf(AClass.class):null); + CaseFour bInstance = (CaseFour.hasAspect(BClass.class)?CaseFour.aspectOf(BClass.class):null); + CaseFour cInstance = (CaseFour.hasAspect(CClass.class)?CaseFour.aspectOf(CClass.class):null); + + System.out.println("BClass aspect instance gives a within type name of "+ + (bInstance==null?"<null>":bInstance.getWithinTypeName())); + System.out.println("CClass aspect instance gives a within type name of "+ + (cInstance==null?"<null>":cInstance.getWithinTypeName())); + System.out.println("AClass aspect instance gives a within type name of "+ + (aInstance==null?"<null>":aInstance.getWithinTypeName())); + } +} diff --git a/tests/features153/ptw/CaseOne.java b/tests/features153/ptw/CaseOne.java new file mode 100644 index 000000000..ea310ae70 --- /dev/null +++ b/tests/features153/ptw/CaseOne.java @@ -0,0 +1,22 @@ +// Types not in packages + +class AClass {} +class BClass {} +class CClass {} + +public aspect CaseOne pertypewithin(*Class) { + public static void main(String []argv) { + new Runner().run(); + } +} + +class Runner { + public void run() { + if (CaseOne.hasAspect(AClass.class)) { + System.out.println("AClass has an aspect instance"); + CaseOne instance = CaseOne.aspectOf(AClass.class); + String name = instance.getWithinTypeName(); + System.out.println("The aspect instance thinks it is for type name "+name); + } + } +} diff --git a/tests/features153/ptw/CaseThree.java b/tests/features153/ptw/CaseThree.java new file mode 100644 index 000000000..1a808f662 --- /dev/null +++ b/tests/features153/ptw/CaseThree.java @@ -0,0 +1,26 @@ +// Types not in packages - BClass won't get an aspect + +class AClass {} +class BClass {} +class CClass {} + +public aspect CaseThree pertypewithin(*Class && !BClass) { + public static void main(String []argv) { + new Runner().run(); + } +} + +class Runner { + public void run() { + CaseThree aInstance = (CaseThree.hasAspect(AClass.class)?CaseThree.aspectOf(AClass.class):null); + CaseThree bInstance = (CaseThree.hasAspect(BClass.class)?CaseThree.aspectOf(BClass.class):null); + CaseThree cInstance = (CaseThree.hasAspect(CClass.class)?CaseThree.aspectOf(CClass.class):null); + + System.out.println("BClass aspect instance gives a within type name of "+ + (bInstance==null?"<null>":bInstance.getWithinTypeName())); + System.out.println("CClass aspect instance gives a within type name of "+ + (cInstance==null?"<null>":cInstance.getWithinTypeName())); + System.out.println("AClass aspect instance gives a within type name of "+ + (aInstance==null?"<null>":aInstance.getWithinTypeName())); + } +} diff --git a/tests/features153/ptw/CaseTwo.java b/tests/features153/ptw/CaseTwo.java new file mode 100644 index 000000000..08bd0ed46 --- /dev/null +++ b/tests/features153/ptw/CaseTwo.java @@ -0,0 +1,26 @@ +// Types not in packages, and multiple mixed up instances + +class AClass {} +class BClass {} +class CClass {} + +public aspect CaseTwo pertypewithin(*Class) { + public static void main(String []argv) { + new Runner().run(); + } +} + +class Runner { + public void run() { + CaseTwo aInstance = (CaseTwo.hasAspect(AClass.class)?CaseTwo.aspectOf(AClass.class):null); + CaseTwo bInstance = (CaseTwo.hasAspect(BClass.class)?CaseTwo.aspectOf(BClass.class):null); + CaseTwo cInstance = (CaseTwo.hasAspect(CClass.class)?CaseTwo.aspectOf(CClass.class):null); + + System.out.println("BClass aspect instance gives a within type name of "+ + (bInstance==null?"<null>":bInstance.getWithinTypeName())); + System.out.println("CClass aspect instance gives a within type name of "+ + (cInstance==null?"<null>":cInstance.getWithinTypeName())); + System.out.println("AClass aspect instance gives a within type name of "+ + (aInstance==null?"<null>":aInstance.getWithinTypeName())); + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java b/tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java index 88435cf39..0f1f79025 100644 --- a/tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java @@ -28,6 +28,11 @@ public class Ajc153Tests extends org.aspectj.testing.XMLBasedAjcTestCase { // public void testCFlowXMLAspectLTW_pr149096() { runTest("cflow xml concrete aspect"); } // public void testAmbiguousBinding_pr121805() { runTest("ambiguous binding");} // public void testNegatedAnnotationMatchingProblem_pr153464() { runTest("negated annotation matching problem");} + public void testPTWgetWithinTypeName_pr123423_1() { runTest("basic usage of getWithinTypeName");} + public void testPTWgetWithinTypeName_pr123423_2() { runTest("basic usage of getWithinTypeName - multiple types");} + public void testPTWgetWithinTypeName_pr123423_3() { runTest("basic usage of getWithinTypeName - non matching types");} + public void testPTWgetWithinTypeName_pr123423_4() { runTest("basic usage of getWithinTypeName - types in packages");} + public void testPTWgetWithinTypeName_pr123423_5() { runTest("basic usage of getWithinTypeName - annotation style");} public void testTurningOffBcelCaching_pr160674() { runTest("turning off bcel caching");} public void testNoIllegalStateExceptionWithGenericInnerAspect_pr156058() { runTest("no IllegalStateException with generic inner aspect"); } public void testNoIllegalStateExceptionWithGenericInnerAspect_pr156058_2() { runTest("no IllegalStateException with generic inner aspect - 2"); } diff --git a/tests/src/org/aspectj/systemtest/ajc153/ajc153.xml b/tests/src/org/aspectj/systemtest/ajc153/ajc153.xml index b428413d6..d7e0cd677 100644 --- a/tests/src/org/aspectj/systemtest/ajc153/ajc153.xml +++ b/tests/src/org/aspectj/systemtest/ajc153/ajc153.xml @@ -51,6 +51,59 @@ </compile> </ajc-test> + <ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName"> + <compile files="CaseOne.java"/> + <run class="CaseOne"> + <stdout> + <line text="AClass has an aspect instance"/> + <line text="The aspect instance thinks it is for type name AClass"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - annotation style"> + <compile files="CaseFive.java" options="-1.5"/> + <run class="CaseFive"> + <stdout> + <line text="AClass has an aspect instance"/> + <line text="The aspect instance thinks it is for type name AClass"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - multiple types"> + <compile files="CaseTwo.java"/> + <run class="CaseTwo"> + <stdout> + <line text="BClass aspect instance gives a within type name of BClass"/> + <line text="CClass aspect instance gives a within type name of CClass"/> + <line text="AClass aspect instance gives a within type name of AClass"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - non matching types"> + <compile files="CaseThree.java"/> + <run class="CaseThree"> + <stdout> + <line text="BClass aspect instance gives a within type name of <null>"/> + <line text="CClass aspect instance gives a within type name of CClass"/> + <line text="AClass aspect instance gives a within type name of AClass"/> + </stdout> + </run> + </ajc-test> + + <ajc-test dir="features153/ptw" title="basic usage of getWithinTypeName - types in packages"> + <compile files="CaseFour.java"/> + <run class="a.b.CaseFour"> + <stdout> + <line text="BClass aspect instance gives a within type name of a.b.BClass"/> + <line text="CClass aspect instance gives a within type name of a.b.CClass"/> + <line text="AClass aspect instance gives a within type name of a.b.AClass"/> + </stdout> + </run> + </ajc-test> + <ajc-test dir="bugs153/pr158126" title="annotations, call and constructors problem"> <compile files="A.java,B.java,MyAnnotation.java,MyAspect.java" options="-1.5 -showWeaveInfo"> <message kind="weave" text="Join point 'constructor-call(void B.<init>())' in Type 'A' (A.java:5) advised by before advice from 'MyAspect' (MyAspect.java:3)"/> diff --git a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java index 382780014..8ca2c511b 100644 --- a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java +++ b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java @@ -189,6 +189,20 @@ public class AjcMemberMaker { ); return rm; } + + // PTWIMPL ResolvedMember for getWithinTypeName() method + public static ResolvedMember perTypeWithinGetWithinTypeNameMethod(UnresolvedType declaringType, boolean inJava5Mode) { + // public String getWithinTypeName() + ResolvedMemberImpl rm = new ResolvedMemberImpl( + Member.METHOD, + declaringType, + Modifier.PUBLIC, + UnresolvedType.JAVA_LANG_STRING, // return value + NameMangler.PERTYPEWITHIN_GETWITHINTYPENAME_METHOD, + UnresolvedType.NONE + ); + return rm; + } public static ResolvedMember perTypeWithinCreateAspectInstance(UnresolvedType declaringType) { // public static a.X ajc$createAspectInstance(java.lang.String) diff --git a/weaver/src/org/aspectj/weaver/NameMangler.java b/weaver/src/org/aspectj/weaver/NameMangler.java index faf06df83..47531910a 100644 --- a/weaver/src/org/aspectj/weaver/NameMangler.java +++ b/weaver/src/org/aspectj/weaver/NameMangler.java @@ -47,6 +47,7 @@ public class NameMangler { public static final String PERTYPEWITHIN_GETINSTANCE_METHOD = PREFIX + "getInstance"; public static final String PERTYPEWITHIN_CREATEASPECTINSTANCE_METHOD = PREFIX + "createAspectInstance"; public static final String PERTYPEWITHIN_WITHINTYPEFIELD = PREFIX + "withinType"; + public static final String PERTYPEWITHIN_GETWITHINTYPENAME_METHOD = "getWithinTypeName"; public static final String AJC_PRE_CLINIT_NAME = PREFIX + "preClinit"; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java index 38d385691..a3aa3926d 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java @@ -124,6 +124,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { generatePerTWHasAspectMethod(gen); generatePerTWGetInstanceMethod(gen); generatePerTWCreateAspectInstanceMethod(gen); + generatePerTWGetWithinTypeNameMethod(gen); } else { throw new Error("should not happen - not such kind " + kind.getName()); } @@ -177,7 +178,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { // pr144602 - don't need to do this, PerObjectInterface munger will do it // } else if (kind == PerClause.PEROBJECT) { // ResolvedMember perObjectFieldInfo = AjcMemberMaker.perObjectField(aspectType, aspectType); -// classGen.addField(makeFieldGen(classGen, perObjectFieldInfo).getField(), null); +// classGen.addField(makeFieldGen(classGen, perObjectFieldInfo).(), null); // // if lazy generation of the inner interface MayHaveAspect works on LTW (see previous note) // // it should be done here. } else if (kind == PerClause.PERCFLOW) { @@ -471,6 +472,21 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { ); } + // Create 'public String getWithinTypeName() { return ajc$withinType;}' + private void generatePerTWGetWithinTypeNameMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinGetWithinTypeNameMethod(aspectType,classGen.getWorld().isInJava5Mode())); + flagAsSynthetic(method, false); + classGen.addMethodGen(method); + // 0: aload_0 + // 1: getfield #14; //Field ajc$withinType:Ljava/lang/String; + // 4: areturn + InstructionList il = method.getBody(); + il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createGet(factory, AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType))); + il.append(InstructionConstants.ARETURN); + } + private void generatePerTWHasAspectMethod(LazyClassGen classGen) { InstructionFactory factory = classGen.getFactory(); LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinHasAspectMethod(aspectType,classGen.getWorld().isInJava5Mode())); |