]> source.dussan.org Git - aspectj.git/commitdiff
test and fix for 123423: getWithinTypeName() for ptw aspects
authoraclement <aclement>
Wed, 18 Oct 2006 14:46:29 +0000 (14:46 +0000)
committeraclement <aclement>
Wed, 18 Oct 2006 14:46:29 +0000 (14:46 +0000)
13 files changed:
docs/adk15ProgGuideDB/pertypewithin.xml
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AspectDeclaration.java
tests/features152/synthetic/TheWholeShow.aj
tests/features153/ptw/CaseFive.java [new file with mode: 0644]
tests/features153/ptw/CaseFour.java [new file with mode: 0644]
tests/features153/ptw/CaseOne.java [new file with mode: 0644]
tests/features153/ptw/CaseThree.java [new file with mode: 0644]
tests/features153/ptw/CaseTwo.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java
tests/src/org/aspectj/systemtest/ajc153/ajc153.xml
weaver/src/org/aspectj/weaver/AjcMemberMaker.java
weaver/src/org/aspectj/weaver/NameMangler.java
weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java

index 8bab12b5de3461d1d57441524bd0a47e8019a8bc..4a5e9bbab46b92e71bfdf34d669db2ebbf94e492 100644 (file)
        aspect.
    </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
index 5d3595273cbc043c4740182803cd5400154e67c5..f49ffeb07487b5ba7a6dd20d41266d91d020f614 100644 (file)
@@ -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);     
                        }
index 7045c819268a4172accbdc59a6a1c1ac3404b769..0fa1c664260538ad6e9a1bc31418b8282369084f 100644 (file)
@@ -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 (file)
index 0000000..e95eddd
--- /dev/null
@@ -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 (file)
index 0000000..735bbd4
--- /dev/null
@@ -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 (file)
index 0000000..ea310ae
--- /dev/null
@@ -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 (file)
index 0000000..1a808f6
--- /dev/null
@@ -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 (file)
index 0000000..08bd0ed
--- /dev/null
@@ -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()));
+  }
+}
index 88435cf39a6a2aaa084f086701522c91c09177a1..0f1f79025497f646023cf7cc9ee7e85b2aab805e 100644 (file)
@@ -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"); }
index b428413d692cb0833aa4ea38f72d4977ac968821..d7e0cd677b640126114259764fb7114217c56347 100644 (file)
       </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 &lt;null&gt;"/>
+          <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.&lt;init&gt;())' in Type 'A' (A.java:5) advised by before advice from 'MyAspect' (MyAspect.java:3)"/>
index 382780014180a4442927f848cc762089798d163a..8ca2c511b7939f9509b6ad1acbb7b6a677ad5ac5 100644 (file)
@@ -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)
index faf06df83914a679a0c3e6dede462652c55635f8..47531910abc18d3ddafabf948642247a615f6b53 100644 (file)
@@ -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";
 
index 38d385691352cb627664ee3f01f202cb8360792b..a3aa3926d6d007a8afc34174f1d6e7bd80594e5f 100644 (file)
@@ -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()));