@@ -0,0 +1,62 @@ | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
import org.aspectj.lang.JoinPoint; | |||
public aspect pr119749 { | |||
// not inherited | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.METHOD) | |||
@interface Me{} | |||
static class C { | |||
@Me() | |||
void m() throws Exception {} | |||
} | |||
static class D extends C{ | |||
void m() {} | |||
} | |||
static class E { | |||
D d(){return null;} | |||
C c(){return null;} | |||
static aspect A { | |||
declare warning: execution(C E.*()) : "C E.*()"; //L26 | |||
declare warning: execution(D E.*()) : "D E.*()"; // L25 | |||
} | |||
} | |||
public static void main(String[] args) { | |||
C c = new C(); | |||
D d = new D(); | |||
C cd = d; | |||
try {c.m();} catch (Exception e) {} | |||
try {cd.m();} catch (Exception e) {} | |||
d.m(); | |||
} | |||
static aspect A { | |||
static void log(JoinPoint jp, Object o) { | |||
System.out.println("" + jp + ": " + o); | |||
} | |||
pointcut scope() : within(pr119749); | |||
pointcut execMe() :execution(@Me void m()) && scope(); // L17 | |||
pointcut execEx() :execution(void m() throws Exception) && scope(); // L17 | |||
pointcut execAnyEx() :execution(* *(..) throws Exception) && scope(); // L17 | |||
pointcut callEx() :call(void m() throws Exception) && scope(); // L37,38 | |||
declare warning : execMe() : "aa @Me void m()"; | |||
declare warning : execEx() : "aa void m() throws Exception"; | |||
declare warning : execAnyEx() : "aa * *(..) throws Exception"; | |||
declare warning : callEx() : "aa call void m() throws Exception"; | |||
before(Me me) : @annotation(me) && execMe() { | |||
log(thisJoinPoint, "execMe[" + me + "]"); | |||
} | |||
before() : execEx() { | |||
log(thisJoinPoint, "execEx"); | |||
} | |||
} | |||
} |
@@ -23,7 +23,7 @@ | |||
pointcut annotatedC2MethodCall() : | |||
call(@SomeAnnotation * C2.aMethod()); // matches nothing | |||
pointcut annotatedMethodCall() : // CW L16, L17 | |||
pointcut annotatedMethodCall() : // CW L16 | |||
call(@SomeAnnotation * aMethod()); | |||
declare warning : annotatedC2MethodCall() : "annotatedC2MethodCall()"; |
@@ -847,6 +847,10 @@ public class Ajc150Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
runTest("reflection on @DeclareParents"); | |||
} | |||
public void testModifierOverrides() { | |||
runTest("modifier overrides"); | |||
} | |||
// helper methods..... | |||
public SyntheticRepository createRepos(File cpentry) { |
@@ -6,6 +6,25 @@ | |||
<compile files="pr118698.aj"/> | |||
<run class="pr118698"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs150" title="modifier overrides"> | |||
<compile files="pr119749.aj" options="-1.5"> | |||
<message kind="warning" line="26" text="C E.*()"/> | |||
<message kind="warning" line="25" text="D E.*()"/> | |||
<message kind="warning" line="17" text="aa @Me void m()"/> | |||
<message kind="warning" line="17" text="aa void m() throws Exception"/> | |||
<message kind="warning" line="17" text="aa * *(..) throws Exception"/> | |||
<message kind="warning" line="37" text="aa call void m() throws Exception"/> | |||
<message kind="warning" line="38" text="aa call void m() throws Exception"/> | |||
</compile> | |||
<run class="pr119749"> | |||
<stdout> | |||
<line text="execution(void pr119749.C.m()): execMe[@pr119749$Me()]"/> | |||
<line text="execution(void pr119749.C.m()): execEx"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="bugs150/pr112476/case1" title="binary weaving decp broken"> | |||
<compile files="lib/A.java,lib/B.java,lib/C.java" outjar="library.jar" options="-1.5"/> | |||
@@ -2683,7 +2702,7 @@ | |||
<ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: @inherited"> | |||
<compile files="AnnotationInheritance.aj" options="-1.5"> | |||
<message kind="warning" line="16" text="annotatedMethodCall()"/> | |||
<message kind="warning" line="17" text="annotatedMethodCall()"/> | |||
<!-- <message kind="warning" line="17" text="annotatedMethodCall()"/> --> | |||
</compile> | |||
</ajc-test> | |||
@@ -305,24 +305,30 @@ public class SignaturePattern extends PatternNode { | |||
return FuzzyBoolean.MAYBE; | |||
} | |||
// modifiers match on the *subject* | |||
if (!modifiers.matches(aMember.getModifiers())) { | |||
if (aMember.isPrivate()) return FuzzyBoolean.NO; | |||
else return FuzzyBoolean.MAYBE; | |||
return FuzzyBoolean.NO; | |||
// if (aMember.isPrivate()) return FuzzyBoolean.NO; | |||
// else return FuzzyBoolean.MAYBE; | |||
} | |||
// annotations match on the *subject* | |||
if (!matchesAnnotations(aMember,inAWorld).alwaysTrue()) { | |||
return FuzzyBoolean.NO; | |||
} | |||
FuzzyBoolean matchesIgnoringAnnotations = FuzzyBoolean.YES; | |||
if (kind == Member.STATIC_INITIALIZATION) { | |||
matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld); | |||
return matchesExactlyStaticInitialization(aMember, inAWorld); | |||
} else if (kind == Member.FIELD) { | |||
matchesIgnoringAnnotations = matchesExactlyField(aMember,inAWorld); | |||
return matchesExactlyField(aMember,inAWorld); | |||
} else if (kind == Member.METHOD) { | |||
matchesIgnoringAnnotations = matchesExactlyMethod(aMember,inAWorld); | |||
return matchesExactlyMethod(aMember,inAWorld); | |||
} else if (kind == Member.CONSTRUCTOR) { | |||
matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld); | |||
return matchesExactlyConstructor(aMember, inAWorld); | |||
} else { | |||
return FuzzyBoolean.YES; | |||
} | |||
if (!matchesIgnoringAnnotations.alwaysTrue()) return matchesIgnoringAnnotations; | |||
return matchesAnnotations(aMember, inAWorld); | |||
} | |||
/** | |||
@@ -357,6 +363,9 @@ public class SignaturePattern extends PatternNode { | |||
*/ | |||
private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world) { | |||
if (!name.matches(aMethod.getName())) return FuzzyBoolean.NO; | |||
// Check the throws pattern | |||
if (!throwsPattern.matches(aMethod.getExceptions(), world)) return FuzzyBoolean.NO; | |||
if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) return FuzzyBoolean.MAYBE; | |||
if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) { | |||
// looking bad, but there might be parameterization to consider... | |||
@@ -379,9 +388,6 @@ public class SignaturePattern extends PatternNode { | |||
// check that varargs specifications match | |||
if (!matchesVarArgs(aMethod,world)) return FuzzyBoolean.MAYBE; | |||
// Check the throws pattern | |||
if (!throwsPattern.matches(aMethod.getExceptions(), world)) return FuzzyBoolean.MAYBE; | |||
// passed all the guards.. | |||
return FuzzyBoolean.YES; | |||
} | |||
@@ -477,7 +483,7 @@ public class SignaturePattern extends PatternNode { | |||
if (annotationPattern.matches(member).alwaysTrue()) { | |||
return FuzzyBoolean.YES; | |||
} else { | |||
return FuzzyBoolean.MAYBE; // need to look at ancestor members too... | |||
return FuzzyBoolean.NO; // do NOT look at ancestor members... | |||
} | |||
} | |||
@@ -38,8 +38,8 @@ public class SignaturePatternTestCase extends TestCase { | |||
Member mOnDerived = MemberImpl.methodFromString("void fluffy.Derived.m()"); | |||
checkMatch(makeMethodPat("* fluffy.Base.*(..) throws java.lang.CloneNotSupportedException"), | |||
new Member[] { mOnBase, mOnDerived }, | |||
new Member[] { }); | |||
new Member[] { mOnBase }, | |||
new Member[] { mOnDerived }); | |||
checkMatch(makeMethodPat("* fluffy.Derived.*(..) throws java.lang.CloneNotSupportedException"), | |||
new Member[] { }, | |||
@@ -53,7 +53,7 @@ public class SignaturePatternTestCase extends TestCase { | |||
checkMatch(makeMethodPat("* *(..)"), M, NONE); | |||
checkMatch(makeMethodPat("* *(..) throws !*"), NO_EXCEPTIONS, M); | |||
checkMatch(makeMethodPat("* *(..) throws *"), BOTH, NONE); | |||
checkMatch(makeMethodPat("* *(..) throws *"), M, NO_EXCEPTIONS); | |||
checkMatch(makeMethodPat("* *(..) throws *, !*"), NONE, BOTH); | |||
checkMatch(makeMethodPat("* *(..) throws (!*)"), NONE, BOTH); |