@@ -25,6 +25,8 @@ public class ModifiersPattern extends PatternNode { | |||
private int requiredModifiers; | |||
private int forbiddenModifiers; | |||
public static final int TRIVIAL = 0x4000; | |||
public static final ModifiersPattern ANY = new ModifiersPattern(0, 0); | |||
public ModifiersPattern(int requiredModifiers, int forbiddenModifiers) { | |||
@@ -54,8 +56,9 @@ public class ModifiersPattern extends PatternNode { | |||
} | |||
public boolean matches(int modifiers) { | |||
return ((modifiers & requiredModifiers) == requiredModifiers) && | |||
((modifiers & forbiddenModifiers) == 0); | |||
// Comparison here is based on 'real' Java modifiers | |||
return (((modifiers & requiredModifiers)&0xfff) == (requiredModifiers&0xfff)) && | |||
(((modifiers & forbiddenModifiers)&0xfff) == 0); | |||
} | |||
@@ -77,8 +80,12 @@ public class ModifiersPattern extends PatternNode { | |||
private static Map modifierFlags = null; | |||
public static int getModifierFlag(String name) { | |||
return getModifierFlag(name,false); | |||
} | |||
public static int getModifierFlag(String name,boolean allowTrivial) { | |||
if (modifierFlags == null) { | |||
modifierFlags = new HashMap(); | |||
int flag = 1; | |||
@@ -87,13 +94,29 @@ public class ModifiersPattern extends PatternNode { | |||
modifierFlags.put(flagName, new Integer(flag)); | |||
flag = flag << 1; | |||
} | |||
modifierFlags.put("trivial",new Integer(TRIVIAL)); | |||
} | |||
Integer flag = (Integer)modifierFlags.get(name); | |||
if (flag == null) return -1; | |||
if (flag.intValue()==TRIVIAL && !allowTrivial) return -2; | |||
return flag.intValue(); | |||
} | |||
public boolean concernedWithTriviality() { | |||
return ((requiredModifiers|forbiddenModifiers)&TRIVIAL)!=0; | |||
} | |||
public boolean matchesTriviality(boolean isTrivial) { | |||
int matchMods = (isTrivial?TRIVIAL:0x0000); | |||
return ((matchMods & requiredModifiers) == requiredModifiers) && | |||
((matchMods & forbiddenModifiers) == 0); | |||
} | |||
public boolean requires(int flag) { | |||
return ((requiredModifiers&flag)!=0); | |||
} | |||
public Object accept(PatternNodeVisitor visitor, Object data) { | |||
return visitor.visit(this, data); | |||
} | |||
} | |||
} |
@@ -596,7 +596,7 @@ public class PatternParser { | |||
Shadow.Kind shadowKind = null; | |||
if (kind.equals("execution")) { | |||
sig = parseMethodOrConstructorSignaturePattern(); | |||
sig = parseMethodOrConstructorSignaturePattern(true); | |||
if (sig.getKind() == Member.METHOD) { | |||
shadowKind = Shadow.MethodExecution; | |||
} else if (sig.getKind() == Member.CONSTRUCTOR) { | |||
@@ -1074,8 +1074,11 @@ public class PatternParser { | |||
return first.getEnd() == second.getStart()-1; | |||
} | |||
public ModifiersPattern parseModifiersPattern() { | |||
return parseModifiersPattern(false); | |||
} | |||
public ModifiersPattern parseModifiersPattern(boolean allowTrivial) { | |||
int requiredFlags = 0; | |||
int forbiddenFlags = 0; | |||
int start; | |||
@@ -1084,7 +1087,11 @@ public class PatternParser { | |||
boolean isForbidden = false; | |||
isForbidden = maybeEat("!"); | |||
IToken t = tokenSource.next(); | |||
int flag = ModifiersPattern.getModifierFlag(t.getString()); | |||
int flag = ModifiersPattern.getModifierFlag(t.getString(),allowTrivial); | |||
// working out the flag... | |||
if (flag==-2) { | |||
throw new ParserException("any modifier except 'trivial'",t);//tokenSource.peek(-1)); | |||
} | |||
if (flag == -1) break; | |||
if (isForbidden) forbiddenFlags |= flag; | |||
else requiredFlags |= flag; | |||
@@ -1157,11 +1164,14 @@ public class PatternParser { | |||
return ThrowsPattern.ANY; | |||
} | |||
public SignaturePattern parseMethodOrConstructorSignaturePattern() { | |||
return parseMethodOrConstructorSignaturePattern(false); | |||
} | |||
public SignaturePattern parseMethodOrConstructorSignaturePattern(boolean allowTrivial) { | |||
int startPos = tokenSource.peek().getStart(); | |||
AnnotationTypePattern annotationPattern = maybeParseAnnotationPattern(); | |||
ModifiersPattern modifiers = parseModifiersPattern(); | |||
ModifiersPattern modifiers = parseModifiersPattern(allowTrivial); | |||
TypePattern returnType = parseTypePattern(false); | |||
TypePattern declaringType; |
@@ -25,6 +25,7 @@ import java.util.Map; | |||
import java.util.Set; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.lang.Signature; | |||
import org.aspectj.lang.reflect.FieldSignature; | |||
import org.aspectj.lang.reflect.MethodSignature; | |||
@@ -328,6 +329,19 @@ public class SignaturePattern extends PatternNode { | |||
} | |||
if (matchesIgnoringAnnotations.alwaysFalse()) return FuzzyBoolean.NO; | |||
// last thing to try | |||
if (subjectMatch && modifiers.concernedWithTriviality()) { | |||
if (!inAWorld.isJoinpointTrivialEnabled()) { | |||
inAWorld.getMessageHandler().handleMessage(MessageUtil.warn("pointcuts can not use trivial modifier unless -Xjoinpoints:trivial specified")); | |||
} else { | |||
ResolvedMember rm = aMember.resolve(inAWorld); | |||
boolean isTrivial = rm.isTrivial(); | |||
if (!modifiers.matchesTriviality(isTrivial)) return FuzzyBoolean.NO; | |||
} | |||
} | |||
// annotations match on the *subject* | |||
if (subjectMatch && !matchesAnnotations(aMember,inAWorld).alwaysTrue()) { | |||
return FuzzyBoolean.NO; |