diff options
5 files changed, 147 insertions, 10 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java index 2c45f3d1a..cbfbc0c04 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeFieldDeclaration.java @@ -99,12 +99,23 @@ public class InterTypeFieldDeclaration extends InterTypeDeclaration { new ReturnStatement(null, 0, 0), }; } else if (!onTypeBinding.isInterface()) { - FieldBinding interField = world.makeFieldBinding( - AjcMemberMaker.interFieldClassField(sig, aspectType)); - Reference ref = new KnownFieldReference(interField, 0); - this.statements = new Statement[] { - new Assignment(ref, initialization, initialization.sourceEnd), - }; + MethodBinding writeMethod = world.makeMethodBinding( + AjcMemberMaker.interFieldSetDispatcher(sig,aspectType)); + // For the body of an intertype field initalizer, generate a call to the inter field set dispatcher + // method as that casts the shadow of a field set join point. + if (Modifier.isStatic(declaredModifiers)) { + this.statements = new Statement[] { + new KnownMessageSend(writeMethod, + AstUtil.makeNameReference(writeMethod.declaringClass), + new Expression[] {initialization}), + }; + } else { + this.statements = new Statement[] { + new KnownMessageSend(writeMethod, + AstUtil.makeNameReference(writeMethod.declaringClass), + new Expression[] {AstUtil.makeLocalVariableReference(arguments[0].binding),initialization}), + }; + } } else { //XXX something is broken about this logic. Can we write to static interface fields? MethodBinding writeMethod = world.makeMethodBinding( diff --git a/tests/bugs/PR68991/Oxford.java b/tests/bugs/PR68991/Oxford.java new file mode 100644 index 000000000..c22cceac6 --- /dev/null +++ b/tests/bugs/PR68991/Oxford.java @@ -0,0 +1,45 @@ +/* initialisers of intertype fields should match field set pointcuts. + +In the example below, the output should be + +set field set(int C.n) +set field set(int C.m) +get field get(int C.n) +set field set(int C.n) + +but the first field set (of C.n) is not picked up. +*/ + + + +aspect Aspect { + + + private int C.n = 13; + + before() : get(* C.*) { + System.err.print(":get field "+thisJoinPointStaticPart); + } + + before() : set(* C.*) { + System.err.print(":set field "+thisJoinPointStaticPart); + } + + public void C.foo() { + n++; + } + +} + +class C { + int m = 20; +} + +public class Oxford { + + public static void main(String[] args) { + C c = new C(); + c.foo(); + } + +}
\ No newline at end of file diff --git a/tests/bugs/PR68991/Simple.java b/tests/bugs/PR68991/Simple.java new file mode 100644 index 000000000..f6afa8e10 --- /dev/null +++ b/tests/bugs/PR68991/Simple.java @@ -0,0 +1,58 @@ +import java.util.*; + +aspect Aspect { + + public static List tjps = new ArrayList(); + public static List values = new ArrayList(); + public static List ejps = new ArrayList(); + + public int C.m = 13; + private int C.n = 13; + + before() : get(* C.*) { + tjps.add(thisJoinPointStaticPart.toString()); + ejps.add(thisEnclosingJoinPointStaticPart.toString()); + //System.out.println("get field "+thisJoinPointStaticPart); + } + + before(int x) : set(* C.*) && args(x) { + tjps.add(thisJoinPointStaticPart.toString()); + ejps.add(thisEnclosingJoinPointStaticPart.toString()); + values.add(new String(thisJoinPointStaticPart+"="+new Integer(x))); + //System.err.println("set field "+thisJoinPointStaticPart); + } + + public void C.foo() { + m++; + n++; + } + +} + +class C { + // int m = 20; +} + +public class Simple { + + public static void main(String[] args) { + C c = new C(); + c.foo(); + System.err.println("\nSummaryJPs:"+Aspect.tjps); + System.err.println("\nSummaryEJPs:"+Aspect.ejps); + System.err.println("\nSummaryVals:"+Aspect.values); + // Ought to have a nicer signature for the ejpsp in the case of an initializer ... + chkNext(Aspect.tjps,"set(int C.m)");chkNext(Aspect.values,"set(int C.m)=13");chkNext(Aspect.ejps,"execution(void Aspect.ajc$interFieldInit$Aspect$C$m(C))"); + chkNext(Aspect.tjps,"set(int C.n)");chkNext(Aspect.values,"set(int C.n)=13");chkNext(Aspect.ejps,"execution(void Aspect.ajc$interFieldInit$Aspect$C$n(C))"); + chkNext(Aspect.tjps,"get(int C.m)"); chkNext(Aspect.ejps,"execution(void C.foo())"); + chkNext(Aspect.tjps,"set(int C.m)");chkNext(Aspect.values,"set(int C.m)=14");chkNext(Aspect.ejps,"execution(void C.foo())"); + chkNext(Aspect.tjps,"get(int C.n)"); chkNext(Aspect.ejps,"execution(void C.foo())"); + chkNext(Aspect.tjps,"set(int C.n)");chkNext(Aspect.values,"set(int C.n)=14");chkNext(Aspect.ejps,"execution(void C.foo())"); + } + + public static void chkNext(List l,String expected) { + String s = (String)l.remove(0); + if (!s.equals(expected)) throw new RuntimeException("Expected next thing on list to be '"+expected+"' but it was '"+s+"'"); + } + +}
\ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java b/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java index 64d7937cf..039dffa0e 100644 --- a/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java @@ -10,9 +10,7 @@ package org.aspectj.systemtest.ajc121; import java.io.File; - import junit.framework.Test; - import org.aspectj.testing.XMLBasedAjcTestCase; public class Ajc121Tests extends org.aspectj.testing.XMLBasedAjcTestCase { @@ -141,8 +139,7 @@ public class Ajc121Tests extends org.aspectj.testing.XMLBasedAjcTestCase { public void test025_proceedInAround3() { runTest("proceed used as method name in around advice (3)"); } - - public void test026_bindingThisAndTargetToTheSameFormal() { + public void test026_bindingThisAndTargetToTheSameFormal() { runTest("ajc crashes when compiling the following program (binding this() and target())"); } @@ -157,5 +154,18 @@ public class Ajc121Tests extends org.aspectj.testing.XMLBasedAjcTestCase { public void test029_falseInvalidAbsoluteTypeName() { runTest("Valid but inaccessible type names should not be flagged by XLint:invalidAbsoluteTypeName"); } + + public void test030_privateITDinitialisersBeingMatched() { + runTest("intertype initialisers should match field set pointcuts"); + } + + public void test031_privateITDinitialisersBeingMatched_OxfordTest() { + runTest("intertype initialisers should match field set pointcuts (oxford testcase)"); + //System.err.println(">"+getLastRunResult().getStdErr()); + String exp = ":set field set(int C.n):set field set(int C.m):get field get(int C.n):set field set(int C.n)"; + assertTrue("Expected output '"+exp+"' but got "+getLastRunResult().getStdErr(), + getLastRunResult().getStdErr().equals(exp)); + } + } diff --git a/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml b/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml index 38261858e..dc59c31c1 100644 --- a/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml +++ b/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml @@ -203,6 +203,7 @@ <run class="Proceeding3"/> </ajc-test> + <ajc-test dir="bugs" pr="61572" title="ITDs on inner classes should be static context"> <compile files="PR61572.aj"> @@ -242,3 +243,15 @@ </compile> <run class="False_InvalidAbsoluteTypeName"/> </ajc-test> + + <ajc-test dir="bugs/PR68991" pr="68991" + title="intertype initialisers should match field set pointcuts"> + <compile files="Simple.java"/> + <run class="Simple"/> + </ajc-test> + + <ajc-test dir="bugs/PR68991" pr="68991" + title="intertype initialisers should match field set pointcuts (oxford testcase)"> + <compile files="Oxford.java"/> + <run class="Oxford"/> + </ajc-test>
\ No newline at end of file |