]> source.dussan.org Git - aspectj.git/commitdiff
fix for Bugzilla Bug 49295
authorjhugunin <jhugunin>
Wed, 28 Jan 2004 00:36:05 +0000 (00:36 +0000)
committerjhugunin <jhugunin>
Wed, 28 Jan 2004 00:36:05 +0000 (00:36 +0000)
   duplicate warning or second join point for constructor-execution

14 files changed:
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
tests/ajcTests.xml
tests/ajcTestsFailing.xml
tests/bugs/InterfaceInitializerOrder.java [new file with mode: 0644]
tests/bugs/SubtypeConstructorCW.java
tests/new/AfterAdviceOnConstructorsOnTheWrongType.java
tests/new/AfterReturningConstructor.java
tests/new/AfterReturningInterfaceConstructor.java
tests/new/AfterReturningInterfaceConstructorCE.java [new file with mode: 0644]
tests/new/EmptyInterface.java
tests/new/InitializerTest.java
tests/new/NegativeSourceLocation.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java

index 0f189c34c56309ee062cf4b1f9bd053c0e476c36..972d07c2a2429bc98c4924684ff04f46b63e0401 100644 (file)
@@ -194,6 +194,8 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration {
                
                
                if (onTypeBinding.isInterface()) {
+                       classScope.problemReporter().signalError(sourceStart, sourceEnd,
+                                                       "can't define constructors on interfaces");
                        ignoreFurtherInvestigation = true;
                        return null;
                }
index a853bef281b5ff20f94c8b61eec9a63399b4970d..8d17bd6fe35de500feef04ac15be9818ff1add26 100644 (file)
         <compile files="AfterReturningInterfaceConstructor.java"/>
         <run class="AfterReturningInterfaceConstructor"/>
     </ajc-test>
+    
+    <ajc-test dir="new" pr="889"
+      title="after returning advice on interface constructor - error">
+        <compile files="AfterReturningInterfaceConstructorCE.java">
+               <message kind="error" line="26"/>
+        </compile>
+    </ajc-test>
 
     <ajc-test dir="bugs" pr="900"
       title="after advice on static call join point">
         </compile>
   </ajc-test>   
         
+    <ajc-test dir="bugs" 
+               pr="49295"
+               title="declare warning on subtype constructor">
+        <compile files="SubtypeConstructorCW.java" >
+                       <message kind="warning" line="5" text="String as first"/>
+                       <message kind="warning" line="10" text="String as first"/>
+        </compile>
+        <run class="SubtypeConstructorCW"/>
+    </ajc-test>
+        
 </suite>
index dca686139c3c9a12bd265d0476a47eda89f94f44..a64b4fb3ca6b2c2f5c5f75c839c51b38b19701f4 100644 (file)
         <run class="AfterReturningParamMatching"/>
     </ajc-test>
 
-    <ajc-test dir="bugs" 
-               pr="49295"
-               title="declare warning on subtype constructor">
-        <compile files="SubtypeConstructorCW.java" >
-                       <message kind="warning" line="5" text="String as first"/>
-                       <message kind="warning" line="10" text="String as first"/>
-        </compile>
-        <run class="SubtypeConstructorCW"/>
-    </ajc-test>
-
     <ajc-test dir="bugs/interAbstract" 
                pr="49784"
                title="aspect declares interface method (abstract decl, default impl)">
         <run class="Main"/>
     </ajc-test>
 
+    <ajc-test dir="bugs" pr="36787"
+      title="interface initialization order">
+        <compile files="InterfaceInitializerOrder.java"/>
+        <run class="InterfaceInitializerOrder"/>
+    </ajc-test>
+
 </suite>
diff --git a/tests/bugs/InterfaceInitializerOrder.java b/tests/bugs/InterfaceInitializerOrder.java
new file mode 100644 (file)
index 0000000..3036bca
--- /dev/null
@@ -0,0 +1,26 @@
+import org.aspectj.testing.Tester;
+
+public class InterfaceInitializerOrder {
+       public static void main(String[] args) {
+         Base base = new Base();
+         Tester.checkEqual(InitAspect.inits.toString(), "Super1,Super2,SuperInterface,Base,");
+       }
+}
+
+class Super1 {}
+
+class Super2 extends Super1 {}
+
+interface SuperInterface {}
+
+class Base extends Super2 implements SuperInterface { }
+
+aspect InitAspect {
+       public static StringBuffer inits = new StringBuffer();
+       
+  pointcut outerMatch() : initialization(new(..)) && !within(InitAspect);
+  before() : outerMatch() {
+       inits.append(thisJoinPoint.getSignature().getDeclaringType().getName());
+       inits.append(",");
+  }
+}
index d3b6a8765f6cf64df035b46b84a13a855eaf319c..f37ac8b371dff338727e16cba114fbbf0058583d 100644 (file)
@@ -7,8 +7,8 @@ class C implements Runnable { // CW 5
        }
 }
 class F implements Runnable {
-       F(int i) {// CW 10
-       } 
+       F(int i) {}// CW 10
+       
        public void run() {
        }
 }
index e29ee974a2445f5eaa719f5667c2212793e13c44..21ab6cb6bbda2f62de2ba055d6a572c2605817c6 100644 (file)
@@ -10,8 +10,8 @@ public class AfterAdviceOnConstructorsOnTheWrongType {
     }
     static {
         Tester.clearEvents();
-        // new(..) for both class and interface
-        Tester.expectEventsInString("after-c,after-c,c,after-d,after-d,d");
+        // new(..) for just class
+        Tester.expectEventsInString("after-c,c,after-d,d");
     }
 }
 
index e0fad5e0e6a7be439a2c30d7e3aa3f2888b2095c..3d87758e5075d7c71be594c2c7255b658ebd4898 100644 (file)
@@ -32,8 +32,8 @@ class U {
     static final String afterThrowing = "after() throwing(): ";
     static final String c = "C()";
     static final String i = "I()";
-    static final String cjp = "execution(" + c + ")";
-    static final String ijp = "execution(" + i + ")";
+    static final String cjp = "initialization(" + c + ")";
+    static final String ijp = "initialization(" + i + ")";
 
     static void e(String event) {
         //System.err.println("act event: " + event); // XXX
@@ -46,8 +46,8 @@ class U {
 }
 
 aspect A {
-    /** must pick out both interface and implementor constructor execution */
-    pointcut pc(): execution(new(..)) && !within(A);
+    /** must pick out both interface and implementor initializers */
+    pointcut pc(): initialization(new(..)) && !within(A);
 
     before(): pc() {
         U.e(U.before + thisJoinPoint);
index 71e851867dfd262a87c2cfddb18c7a697a3ddfc4..f16f563bf05cd5572000db10ec49fd47504a130b 100644 (file)
@@ -6,7 +6,10 @@ public class AfterReturningInterfaceConstructor {
     public static void main (String[] args) {
         Tester.expectEvent("constructor");
         Tester.expectEvent("advice");
-        new C();
+        I i = new C();
+        
+        Tester.checkEqual(i.i, 2, "i.i");
+        
         Tester.checkAllEvents();
     }     
 }
@@ -21,10 +24,10 @@ class C implements I {
 
 aspect A {
     int I.i;
-    I.new() {
-        i = 2;
+       after(I i) returning: this(i) && initialization(I.new(..)) {
+        i.i = 2;
     }
-    after() returning: execution(I.new()) {
+    after() returning: initialization(I.new(..)) {
         Tester.event("advice");
     }
 }
diff --git a/tests/new/AfterReturningInterfaceConstructorCE.java b/tests/new/AfterReturningInterfaceConstructorCE.java
new file mode 100644 (file)
index 0000000..aec297d
--- /dev/null
@@ -0,0 +1,33 @@
+
+import org.aspectj.testing.Tester;
+
+/** @testcase PR#889 after returning advice on interface constructor */
+public class AfterReturningInterfaceConstructorCE {
+    public static void main (String[] args) {
+        Tester.expectEvent("constructor");
+        Tester.expectEvent("advice");
+        I i = new C();
+        System.out.println("i.i: " + i.i);
+        
+        Tester.checkAllEvents();
+    }     
+}
+
+interface I {}
+
+class C implements I {
+    C() {
+        Tester.event("constructor");
+    }
+}
+
+aspect A {
+    int I.i;
+    I.new() {
+        i = 2;
+        System.out.println("running I.new()");
+    }
+    after() returning: execution(I.new()) {    // ERR: can't define constructor on interface
+        Tester.event("advice");
+    }
+}
index aca01b6a88eb2b6bbe594a38b95e5ed6e9798fb0..396f7994caa2a8e7901a03817d6b9095c1869f6b 100644 (file)
@@ -20,7 +20,7 @@ aspect Log {
     interface LoggedType {
     }
     declare parents: C implements LoggedType;
-    after() : within(LoggedType+) 
+    after(): within(LoggedType+) 
         //&& !initialization(new(..))
         //&& !preinitialization(new(..)) // 1.1 only  
         {
index 52f2d93af51a3ee28c66605ffd8c6f25888e29eb..31b5ca6983eaa1e3647d7ad1246a8dd109816cae 100644 (file)
@@ -81,10 +81,10 @@ aspect A issingleton () {
     before(I i): initialization(I.new()) && this(i) {
         Tester.checkEqual(((C)i).state, "C-constructed", thisJoinPoint.toString());
     }
-    before(I i): execution(I.new()) && this(i) {
-        Tester.checkEqual(((C)i).state, "C-constructed", thisJoinPoint.toString());
-        Tester.note("constructed I");
-    }
+//    before(I i): execution(I.new()) && this(i) {
+//        Tester.checkEqual(((C)i).state, "C-constructed", thisJoinPoint.toString());
+//        Tester.note("constructed I");
+//    }
     after(I i): initialization(I.new()) && this(i) {
         Tester.checkEqual(((C)i).state, "C-constructed", thisJoinPoint.toString());
         Tester.note("initialized I");
@@ -100,7 +100,7 @@ public class InitializerTest {
         Tester.check("constructed SubC");
 
         Tester.check("initialized I");
-        Tester.check("constructed I");
+        //Tester.check("constructed I");
 
         Tester.check("static initialized C");
         Tester.check("static initialized SubC");
index f76ef229a37c00effcdbde710b1085dc42d2ade3..f27bf3925d36b7d5ac7a055ae59a782a6762cd96 100644 (file)
@@ -287,7 +287,7 @@ class Const {
         , "before AllTargetJoinPoints set(String TargetClass.staticString)"
         , "before AllTargetJoinPoints preinitialization(TargetClass())"
         , "before AllTargetJoinPoints initialization(java.lang.Runnable())"
-        , "before AllTargetJoinPoints execution(java.lang.Runnable())"
+        //, "before AllTargetJoinPoints execution(java.lang.Runnable())"
         , "before AllTargetJoinPoints initialization(TargetClass())"
         //, "before AllTargetJoinPoints execution(TargetClass.<init>)"
         , "before AllTargetJoinPoints set(String TargetClass.string)"
@@ -305,7 +305,7 @@ class Const {
         , "before AllTargetJoinPoints preinitialization(TargetClass())"        
         , "before AllTargetJoinPoints initialization(TargetClass())"
         , "before AllTargetJoinPoints initialization(java.lang.Runnable())"
-        , "before AllTargetJoinPoints execution(java.lang.Runnable())"
+        //, "before AllTargetJoinPoints execution(java.lang.Runnable())"
         //, "before AllTargetJoinPoints execution(TargetClass.<init>)"
         , "before AllTargetJoinPoints set(String TargetClass.string)"
         , "before AllTargetJoinPoints execution(TargetClass())"
index 052cef1fac90d87178d6fc9c58cdbb19a7206378..d67d4eb87b8c16c9a9ad6142c2c80803eaf4f774 100644 (file)
@@ -391,7 +391,7 @@ class BcelClassWeaver implements IClassWeaver {
                                Range.genStart(body, body.getStart().getNext()),
                                Range.genEnd(body, call.getPrev()));
                } else {
-                       // assert s.getKind() == Shadow.Initialization  
+                       // assert s.getKind() == Shadow.Initialization
                        r.associateWithTargets(
                                Range.genStart(body, call.getNext()),
                                Range.genEnd(body));
@@ -748,50 +748,40 @@ class BcelClassWeaver implements IClassWeaver {
                        
                        // walk the body
                        boolean beforeSuperOrThisCall = true;
-                       if (shouldWeaveBody(mg)) { //!mg.isAjSynthetic()) {
-                               for (InstructionHandle h = mg.getBody().getStart();
-                                       h != null;
-                                       h = h.getNext()) {
-                                       if (h == superOrThisCall) {
-                                               beforeSuperOrThisCall = false;
-                                               continue;
+                       if (shouldWeaveBody(mg)) {
+                               if (canMatchBodyShadows) {
+                                       for (InstructionHandle h = mg.getBody().getStart();
+                                               h != null;
+                                               h = h.getNext()) {
+                                               if (h == superOrThisCall) {
+                                                       beforeSuperOrThisCall = false;
+                                                       continue;
+                                               }
+                                               match(mg, h, beforeSuperOrThisCall ? null : enclosingShadow, shadowAccumulator);
                                        }
-                                       match(mg, h, beforeSuperOrThisCall ? null : enclosingShadow, shadowAccumulator);
                                }
                                match(enclosingShadow, shadowAccumulator);
                        }
                        
                        // XXX we don't do pre-inits of interfaces
                        
-                       // now add interface inits and cexecs
+                       // now add interface inits
                        if (superOrThisCall != null && ! isThisCall(superOrThisCall)) {
                                InstructionHandle curr = enclosingShadow.getRange().getStart();
                                for (Iterator i = addedSuperInitializersAsList.iterator(); i.hasNext(); ) {
                                        IfaceInitList l = (IfaceInitList) i.next();
-                                       // generate the cexec jp
+
                                        Member ifaceInitSig = AjcMemberMaker.interfaceConstructor(l.onType);
-                                       BcelShadow cexecShadow =
-                                               BcelShadow.makeIfaceConstructorExecution(
-                                                       world,
-                                                       mg,
-                                                       curr,
-                                                       ifaceInitSig);
-                                       if (match(cexecShadow, shadowAccumulator)) {
-                                               cexecShadow.getRange().getBody().append(
-                                                       cexecShadow.getRange().getStart(),
-                                                       InstructionConstants.NOP);
-                                       }
-                                       // generate the init jp around it
+                                       
                                        BcelShadow initShadow =
-                                               BcelShadow.makeIfaceInitialization(
-                                                       world,
-                                                       mg,
-                                                       cexecShadow,
-                                                       ifaceInitSig);
-                                       match(initShadow, shadowAccumulator);
+                                               BcelShadow.makeIfaceInitialization(world, mg, ifaceInitSig);
+                                       
                                        // insert code in place
                                        InstructionList inits = genInitInstructions(l.list, false);
-                                       initShadow.getRange().insert(inits, Range.InsideAfter);
+                                       if (match(initShadow, shadowAccumulator) || !inits.isEmpty()) {
+                                               initShadow.initIfaceInitializer(curr);
+                                               initShadow.getRange().insert(inits, Range.OutsideBefore);
+                                       }
                                }
                                
                                // now we add our initialization code
index 41a84491a476998de3cbe810a91a9ef4f0833910..fd72970cd745c9cf4009725c15a78a62cbcec43b 100644 (file)
@@ -430,7 +430,6 @@ public class BcelShadow extends Shadow {
        public static BcelShadow makeIfaceInitialization(
                BcelWorld world,
                LazyMethodGen constructor,
-               BcelShadow ifaceCExecShadow,
                Member interfaceConstructorSignature) 
        {
                InstructionList body = constructor.getBody();
@@ -443,44 +442,55 @@ public class BcelShadow extends Shadow {
                 constructor,
                 null);
         s.fallsThrough = true;
-        ShadowRange r = new ShadowRange(body);
-        r.associateWithShadow(s);
-        InstructionHandle start = Range.genStart(body, ifaceCExecShadow.getRange().getStart());
-        InstructionHandle end = Range.genEnd(body, ifaceCExecShadow.getRange().getEnd());
-        
-        r.associateWithTargets(start, end);
+//        ShadowRange r = new ShadowRange(body);
+//        r.associateWithShadow(s);
+//        InstructionHandle start = Range.genStart(body, handle);
+//        InstructionHandle end = Range.genEnd(body, handle);
+//        
+//        r.associateWithTargets(start, end);
         return s;                      
        }
-
-       public static BcelShadow makeIfaceConstructorExecution(
-               BcelWorld world,
-               LazyMethodGen constructor,
-               InstructionHandle next,
-               Member interfaceConstructorSignature) 
-       {
-               // final InstructionFactory fact = constructor.getEnclosingClass().getFactory();
-               InstructionList body = constructor.getBody();
-               // TypeX inType = constructor.getEnclosingClass().getType();
-        BcelShadow s =
-            new BcelShadow(
-                world,
-                ConstructorExecution,
-                interfaceConstructorSignature,
-                constructor,
-                null);
-        s.fallsThrough = true;
-        ShadowRange r = new ShadowRange(body);
-        r.associateWithShadow(s);
-               // ??? this may or may not work
-        InstructionHandle start = Range.genStart(body, next);
-        //InstructionHandle end = Range.genEnd(body, body.append(start, fact.NOP));
-        InstructionHandle end = Range.genStart(body, next);
-        //body.append(start, fact.NOP);
-        
-        r.associateWithTargets(start, end);
-        return s;                      
+       
+       public void initIfaceInitializer(InstructionHandle end) {
+               final InstructionList body = enclosingMethod.getBody();
+               ShadowRange r = new ShadowRange(body);
+               r.associateWithShadow(this);
+               InstructionHandle nop = body.insert(end, InstructionConstants.NOP);
+               
+               r.associateWithTargets(
+                       Range.genStart(body, nop),
+                       Range.genEnd(body, nop));
        }
 
+//     public static BcelShadow makeIfaceConstructorExecution(
+//             BcelWorld world,
+//             LazyMethodGen constructor,
+//             InstructionHandle next,
+//             Member interfaceConstructorSignature) 
+//     {
+//             // final InstructionFactory fact = constructor.getEnclosingClass().getFactory();
+//             InstructionList body = constructor.getBody();
+//             // TypeX inType = constructor.getEnclosingClass().getType();
+//        BcelShadow s =
+//            new BcelShadow(
+//                world,
+//                ConstructorExecution,
+//                interfaceConstructorSignature,
+//                constructor,
+//                null);
+//        s.fallsThrough = true;
+//        ShadowRange r = new ShadowRange(body);
+//        r.associateWithShadow(s);
+//             // ??? this may or may not work
+//        InstructionHandle start = Range.genStart(body, next);
+//        //InstructionHandle end = Range.genEnd(body, body.append(start, fact.NOP));
+//        InstructionHandle end = Range.genStart(body, next);
+//        //body.append(start, fact.NOP);
+//        
+//        r.associateWithTargets(start, end);
+//        return s;                    
+//     }
+
     
        /** Create an initialization join point associated with a constructor, but not
                 * with any body of code yet.  If this is actually matched, it's range will be set