@@ -0,0 +1,5 @@ | |||
package moody; | |||
public class AnnotationMoodImplementor { | |||
} |
@@ -0,0 +1,22 @@ | |||
package moody; | |||
import org.aspectj.lang.annotation.Aspect; | |||
import org.aspectj.lang.annotation.DeclareParents; | |||
@Aspect | |||
public class AnnotationMoodIndicator { | |||
public interface Moody { | |||
Mood getMood(); | |||
void setMood(Mood mood); | |||
} | |||
public static class MoodyImpl implements Moody { | |||
private Mood mood = Mood.HAPPY; | |||
public Mood getMood() { return mood; } | |||
public void setMood(Mood mood) { this.mood = mood; } | |||
} | |||
@DeclareParents(value="moody.AnnotationMoodImplementor",defaultImpl=MoodyImpl.class) | |||
private Moody implementedInterface; | |||
} |
@@ -0,0 +1,17 @@ | |||
package moody; | |||
public class MainClass { | |||
public static void main(String[] args) { | |||
AnnotationMoodImplementor ami0 = new AnnotationMoodImplementor(); | |||
AnnotationMoodImplementor ami1 = new AnnotationMoodImplementor(); | |||
System.out.println("ami0's mood is " + ((AnnotationMoodIndicator.Moody) ami0).getMood()); | |||
((AnnotationMoodIndicator.Moody) ami1).setMood(Mood.JOLLY); | |||
System.out.println("ami1's mood is now " + ((AnnotationMoodIndicator.Moody) ami1).getMood()); | |||
System.out.println("ami0's mood is still " + ((AnnotationMoodIndicator.Moody) ami0).getMood()); | |||
} | |||
} |
@@ -0,0 +1,5 @@ | |||
package moody; | |||
public enum Mood { | |||
HAPPY, JOLLY | |||
} |
@@ -164,6 +164,10 @@ public class Ajc151Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
runTest("@AJ without JoinPoint import"); | |||
} | |||
public void testAtAspectDeclareParentsRetainsFieldState_pr122370() { | |||
runTest("@AJ declare parents retains field state"); | |||
} | |||
/* | |||
* Load-time weaving bugs and enhancements | |||
*/ |
@@ -182,6 +182,17 @@ | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs151/pr122370" title="@AJ declare parents retains field state"> | |||
<compile files="moody/AnnotationMoodImplementor.java, moody/AnnotationMoodIndicator.java, moody/Mood.java, moody/MainClass.java" options="-1.5"/> | |||
<run class="moody.MainClass"> | |||
<stdout> | |||
<line text="ami0's mood is HAPPY"/> | |||
<line text="ami1's mood is now JOLLY"/> | |||
<line text="ami0's mood is still HAPPY"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<!-- New features down here... when they arent big enough to have their own test file --> | |||
<ajc-test dir="features151/ptw" title="exposing withintype"> |
@@ -1110,15 +1110,19 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
// getfield | |||
body.append(InstructionConstants.ALOAD_0); | |||
body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); | |||
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); | |||
BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); | |||
body.append(ifNonNull); | |||
InstructionHandle ifNonNullElse = body.append(InstructionConstants.ALOAD_0); | |||
// Create and store a new instance | |||
body.append(InstructionConstants.ALOAD_0); | |||
body.append(fact.createNew(munger.getImplClassName())); | |||
body.append(InstructionConstants.DUP); | |||
body.append(fact.createInvoke(munger.getImplClassName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); | |||
body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); | |||
// if not null use the instance we've got | |||
InstructionHandle ifNonNullElse = body.append(InstructionConstants.ALOAD_0); | |||
ifNonNull.setTarget(ifNonNullElse); | |||
body.append(InstructionConstants.ALOAD_0); | |||
body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); | |||
//args |