]> source.dussan.org Git - aspectj.git/commitdiff
fix for 142466
authoraclement <aclement>
Tue, 23 May 2006 07:55:53 +0000 (07:55 +0000)
committeraclement <aclement>
Tue, 23 May 2006 07:55:53 +0000 (07:55 +0000)
13 files changed:
loadtime/src/org/aspectj/weaver/loadtime/ConcreteAspectCodeGen.java
tests/bugs152/pr142466/AbstractMethods.aj [new file with mode: 0644]
tests/bugs152/pr142466/AtAspectTestConcreteMethods.java [new file with mode: 0644]
tests/bugs152/pr142466/ConcreteMethods.aj [new file with mode: 0644]
tests/bugs152/pr142466/HelloWorld.java [new file with mode: 0644]
tests/bugs152/pr142466/aop-tracing.xml [new file with mode: 0644]
tests/bugs152/pr142466/case2/AbstractMethods.aj [new file with mode: 0644]
tests/bugs152/pr142466/case2/AtAspectTestConcreteMethods.java [new file with mode: 0644]
tests/bugs152/pr142466/case2/ConcreteMethods.aj [new file with mode: 0644]
tests/bugs152/pr142466/case2/HelloWorld.java [new file with mode: 0644]
tests/bugs152/pr142466/case2/aop-tracing.xml [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java
tests/src/org/aspectj/systemtest/ajc152/ajc152.xml

index 73ac9f3da5cf2a58976a9531cadf41e26053b66d..facebc4899cfb2ca48d4c3f6e5c7cbb27714b209 100644 (file)
@@ -38,9 +38,12 @@ import org.aspectj.weaver.patterns.PerSingleton;
 
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Generates bytecode for concrete-aspect
@@ -159,27 +162,35 @@ public class ConcreteAspectCodeGen {
 
         // must have all abstractions defined
         List elligibleAbstractions = new ArrayList();
-        Iterator methods = m_parent.getMethods();
-        while (methods.hasNext()) {
-            ResolvedMember method = (ResolvedMember) methods.next();
-            if (method.isAbstract()) {
-                if ("()V".equals(method.getSignature())) {
-                       String n = method.getName();
-                       if (n.startsWith("ajc$pointcut")) { // Allow for the abstract pointcut being from a code style aspect compiled with -1.5 (see test for 128744)
-                               n = n.substring(14);
-                               n = n.substring(0,n.indexOf("$"));
-                               elligibleAbstractions.add(n);
-                       } else {
-                               // Only interested in abstract methods that take no parameters and are marked @Pointcut
-                               if (hasPointcutAnnotation(method))
-                                       elligibleAbstractions.add(method.getName());
-                       }
-                } else {
-                    reportError("Abstract method '" + method.getName() + "' cannot be concretized as a pointcut (illegal signature, must have no arguments, must return void): " + stringify());
-                    return false;
-                }
+        
+        Collection abstractMethods = getOutstandingAbstractMethods(m_parent);
+        for (Iterator iter = abstractMethods.iterator(); iter.hasNext();) {
+                       ResolvedMember method = (ResolvedMember) iter.next();
+                       if ("()V".equals(method.getSignature())) {
+                        String n = method.getName();
+                if (n.startsWith("ajc$pointcut")) { // Allow for the abstract pointcut being from a code style aspect compiled with -1.5 (see test for 128744)
+                       n = n.substring(14);
+                       n = n.substring(0,n.indexOf("$"));
+                       elligibleAbstractions.add(n);         
+                } else if (hasPointcutAnnotation(method)) {
+                               elligibleAbstractions.add(method.getName());
+                } else {
+                // error, an outstanding abstract method that can't be concretized in XML
+                        reportError("Abstract method '" + method.toString() + "' cannot be concretized in XML: " + stringify());
+                  return false;
+                }
+            } else {
+                 if (method.getName().startsWith("ajc$pointcut") || hasPointcutAnnotation(method)) {
+                       // it may be a pointcut but it doesn't meet the requirements for XML concretization
+                       reportError("Abstract method '" + method.toString() + "' cannot be concretized as a pointcut (illegal signature, must have no arguments, must return void): " + stringify());
+                 return false;
+                 } else {
+                       // error, an outstanding abstract method that can't be concretized in XML
+                 reportError("Abstract method '" + method.toString() + "' cannot be concretized in XML: " + stringify());
+                 return false;
+                 }
             }
-        }
+               }
         List pointcutNames = new ArrayList();
         for (Iterator it = m_concreteAspect.pointcuts.iterator(); it.hasNext();) {
             Definition.Pointcut abstractPc = (Definition.Pointcut) it.next();
@@ -198,7 +209,38 @@ public class ConcreteAspectCodeGen {
         return m_isValid;
     }
 
-    /**
+    private Collection getOutstandingAbstractMethods(ResolvedType type) {
+               Map collector = new HashMap();
+               // let's get to the top of the hierarchy and then walk down ... recording abstract methods then removing
+               // them if they get defined further down the hierarchy
+               getOutstandingAbstractMethodsHelper(type,collector);
+               return collector.values();
+       }
+    
+    // We are trying to determine abstract methods left over at the bottom of a hierarchy that have not been
+    // concretized.
+    private void getOutstandingAbstractMethodsHelper(ResolvedType type,Map collector) {
+         if (type==null) return;
+         // Get to the top
+         if (type!=null && !type.equals(ResolvedType.OBJECT)) {
+                 if (type.getSuperclass()!=null)
+                   getOutstandingAbstractMethodsHelper(type.getSuperclass(),collector);
+         }
+         ResolvedMember[] rms = type.getDeclaredMethods();
+         if (rms!=null) {
+                 for (int i = 0; i < rms.length; i++) {
+                               ResolvedMember member = rms[i];
+                               String key = member.getName()+member.getSignature();
+                               if (member.isAbstract()) {
+                                       collector.put(key,member);
+                               } else {
+                                       collector.remove(key);
+                               }
+                 }
+         }
+    }
+
+       /**
      * Rebuild the XML snip that defines this concrete aspect, for log error purpose
      *
      * @return string repr.
diff --git a/tests/bugs152/pr142466/AbstractMethods.aj b/tests/bugs152/pr142466/AbstractMethods.aj
new file mode 100644 (file)
index 0000000..f252d88
--- /dev/null
@@ -0,0 +1,31 @@
+import org.aspectj.lang.annotation.*;
+
+
+@Aspect
+public abstract class AbstractMethods {
+
+  @Pointcut
+  protected abstract void tracingScope();
+
+  @Before("tracingScope()")
+  public void doit() {
+    test();
+    System.out.println("advice running");
+  }
+  protected abstract void test();
+}
+
+/*
+public abstract aspect AbstractMethods {
+
+       protected abstract pointcut tracingScope ();
+       
+       before () : tracingScope () {
+               test();
+                System.out.println("advice running");
+       }
+       
+       protected abstract void test ();
+//     protected void test () {}
+}
+*/
diff --git a/tests/bugs152/pr142466/AtAspectTestConcreteMethods.java b/tests/bugs152/pr142466/AtAspectTestConcreteMethods.java
new file mode 100644 (file)
index 0000000..90e4cc3
--- /dev/null
@@ -0,0 +1,6 @@
+import org.aspectj.lang.annotation.Aspect;
+
+@Aspect
+public class AtAspectTestConcreteMethods extends ConcreteMethods {
+
+}
diff --git a/tests/bugs152/pr142466/ConcreteMethods.aj b/tests/bugs152/pr142466/ConcreteMethods.aj
new file mode 100644 (file)
index 0000000..cd2dd1e
--- /dev/null
@@ -0,0 +1,8 @@
+
+
+public abstract aspect ConcreteMethods extends AbstractMethods {
+
+       protected void test () {}
+  public abstract void foo(int i) ;
+
+}
diff --git a/tests/bugs152/pr142466/HelloWorld.java b/tests/bugs152/pr142466/HelloWorld.java
new file mode 100644 (file)
index 0000000..f741a2c
--- /dev/null
@@ -0,0 +1,11 @@
+public class HelloWorld {
+
+       public static void main(String[] args) {
+               new HelloWorld().println();
+       }
+
+       public void println() {
+               System.out.print("Hello World!");
+       }
+
+}
diff --git a/tests/bugs152/pr142466/aop-tracing.xml b/tests/bugs152/pr142466/aop-tracing.xml
new file mode 100644 (file)
index 0000000..2c80513
--- /dev/null
@@ -0,0 +1,10 @@
+<aspectj>
+       <aspects>
+        <concrete-aspect name="TraceHelloWorld" extends="ConcreteMethods">
+               <pointcut name="tracingScope" expression="within(HelloWorld) AND call(* println(..))"/>
+        </concrete-aspect>
+       </aspects>
+    
+    <weaver options=""/>
+</aspectj>
+
diff --git a/tests/bugs152/pr142466/case2/AbstractMethods.aj b/tests/bugs152/pr142466/case2/AbstractMethods.aj
new file mode 100644 (file)
index 0000000..f252d88
--- /dev/null
@@ -0,0 +1,31 @@
+import org.aspectj.lang.annotation.*;
+
+
+@Aspect
+public abstract class AbstractMethods {
+
+  @Pointcut
+  protected abstract void tracingScope();
+
+  @Before("tracingScope()")
+  public void doit() {
+    test();
+    System.out.println("advice running");
+  }
+  protected abstract void test();
+}
+
+/*
+public abstract aspect AbstractMethods {
+
+       protected abstract pointcut tracingScope ();
+       
+       before () : tracingScope () {
+               test();
+                System.out.println("advice running");
+       }
+       
+       protected abstract void test ();
+//     protected void test () {}
+}
+*/
diff --git a/tests/bugs152/pr142466/case2/AtAspectTestConcreteMethods.java b/tests/bugs152/pr142466/case2/AtAspectTestConcreteMethods.java
new file mode 100644 (file)
index 0000000..90e4cc3
--- /dev/null
@@ -0,0 +1,6 @@
+import org.aspectj.lang.annotation.Aspect;
+
+@Aspect
+public class AtAspectTestConcreteMethods extends ConcreteMethods {
+
+}
diff --git a/tests/bugs152/pr142466/case2/ConcreteMethods.aj b/tests/bugs152/pr142466/case2/ConcreteMethods.aj
new file mode 100644 (file)
index 0000000..cdce053
--- /dev/null
@@ -0,0 +1,7 @@
+
+
+public abstract aspect ConcreteMethods extends AbstractMethods {
+
+//     protected void test () {}
+
+}
diff --git a/tests/bugs152/pr142466/case2/HelloWorld.java b/tests/bugs152/pr142466/case2/HelloWorld.java
new file mode 100644 (file)
index 0000000..f741a2c
--- /dev/null
@@ -0,0 +1,11 @@
+public class HelloWorld {
+
+       public static void main(String[] args) {
+               new HelloWorld().println();
+       }
+
+       public void println() {
+               System.out.print("Hello World!");
+       }
+
+}
diff --git a/tests/bugs152/pr142466/case2/aop-tracing.xml b/tests/bugs152/pr142466/case2/aop-tracing.xml
new file mode 100644 (file)
index 0000000..2c80513
--- /dev/null
@@ -0,0 +1,10 @@
+<aspectj>
+       <aspects>
+        <concrete-aspect name="TraceHelloWorld" extends="ConcreteMethods">
+               <pointcut name="tracingScope" expression="within(HelloWorld) AND call(* println(..))"/>
+        </concrete-aspect>
+       </aspects>
+    
+    <weaver options=""/>
+</aspectj>
+
index 126c8e8870a4fa05b9e48f065c237ccfd486ca39..1105d823555142d217648c790b8545f23a7d1b66 100644 (file)
@@ -17,6 +17,8 @@ import org.aspectj.testing.XMLBasedAjcTestCase;
 
 public class Ajc152Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
 
+  public void testConcretizingAbstractMethods_pr142466() { runTest("aop.xml aspect inheriting but not concretizing abstract method");}
+  public void testConcretizingAbstractMethods_pr142466_2() { runTest("aop.xml aspect inheriting but not concretizing abstract method - 2");}
   public void testComplexGenericDecl_pr137568() { runTest("complicated generics declaration");}
   public void testItdOnInnerTypeOfGenericType_pr132349() { runTest("ITD on inner type of generic type");}
   public void testItdOnInnerTypeOfGenericType_pr132349_2() { runTest("ITD on inner type of generic type - 2");}
index aaa4a7c07c21a8219aa8a7fbb97b410ddbb271ea..64857100deab3804eaefcc29b04a22459cf71e1f 100644 (file)
         </run>
     </ajc-test>
     
+    <ajc-test dir="bugs152/pr142466" title="aop.xml aspect inheriting but not concretizing abstract method">
+        <compile files="HelloWorld.java"/>
+        <compile files="AbstractMethods.aj, ConcreteMethods.aj" options="-1.5"/>
+        <run class="HelloWorld" ltw="aop-tracing.xml">
+          <stderr>
+            <line text="error Abstract method 'void ConcreteMethods.foo(int)' cannot be concretized in XML:"/>
+            <line text="warning register definition failed"/>
+          </stderr>
+          <stdout>
+            <line text="Hello World!"/>
+          </stdout>
+        </run>
+    </ajc-test>
+     
+    <ajc-test dir="bugs152/pr142466/case2" title="aop.xml aspect inheriting but not concretizing abstract method - 2">
+        <compile files="HelloWorld.java"/>
+        <compile files="AbstractMethods.aj, ConcreteMethods.aj" options="-1.5"/>
+        <run class="HelloWorld" ltw="aop-tracing.xml">
+          <stderr>
+            <line text="error Abstract method 'void AbstractMethods.test()' cannot be concretized in XML"/>
+            <line text="warning register definition failed"/>
+          </stderr>
+          <stdout>
+            <line text="Hello World!"/>
+          </stdout>
+        </run>
+    </ajc-test>   
 
     <ajc-test dir="bugs152/pr138223" pr="138223" title="Double at annotation matching (no binding)">
       <compile files="DoubleAnnotationMatching.aj" options="-1.5">