@@ -0,0 +1,80 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2010 Contributors | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Andy Clement - SpringSource | |||
* ******************************************************************/ | |||
package org.aspectj.weaver.patterns; | |||
import java.io.IOException; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.CompressingDataOutputStream; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
/** | |||
* Implements common functions to be used across ISignaturePatterns. | |||
* | |||
* @author Andy Clement | |||
* @since 1.6.9 | |||
*/ | |||
public abstract class AbstractSignaturePattern implements ISignaturePattern { | |||
protected void writePlaceholderLocation(CompressingDataOutputStream s) throws IOException { | |||
s.writeInt(0); | |||
s.writeInt(0); | |||
} | |||
public static ISignaturePattern readCompoundSignaturePattern(VersionedDataInputStream s, ISourceContext context) | |||
throws IOException { | |||
byte key = s.readByte(); | |||
switch (key) { | |||
case PATTERN: | |||
return SignaturePattern.read(s, context); | |||
case AND: | |||
return AndSignaturePattern.readAndSignaturePattern(s, context); | |||
case OR: | |||
return OrSignaturePattern.readOrSignaturePattern(s, context); | |||
case NOT: | |||
return NotSignaturePattern.readNotSignaturePattern(s, context); | |||
default: | |||
throw new BCException("unknown SignatureTypePattern kind: " + key); | |||
} | |||
} | |||
public static void writeCompoundSignaturePattern(CompressingDataOutputStream s, ISignaturePattern sigPattern) | |||
throws IOException { | |||
System.out.println(sigPattern); | |||
if (sigPattern instanceof SignaturePattern) { | |||
s.writeByte(PATTERN); | |||
((SignaturePattern) sigPattern).write(s); | |||
} else if (sigPattern instanceof AndSignaturePattern) { | |||
AndSignaturePattern andSignaturePattern = (AndSignaturePattern) sigPattern; | |||
s.writeByte(AND); | |||
writeCompoundSignaturePattern(s, andSignaturePattern.getLeft()); | |||
writeCompoundSignaturePattern(s, andSignaturePattern.getRight()); | |||
s.writeInt(0); | |||
s.writeInt(0); // TODO positions not yet set properly | |||
} else if (sigPattern instanceof OrSignaturePattern) { | |||
OrSignaturePattern orSignaturePattern = (OrSignaturePattern) sigPattern; | |||
s.writeByte(OR); | |||
writeCompoundSignaturePattern(s, orSignaturePattern.getLeft()); | |||
writeCompoundSignaturePattern(s, orSignaturePattern.getRight()); | |||
s.writeInt(0); | |||
s.writeInt(0); // TODO positions not yet set properly | |||
} else { | |||
// negated | |||
NotSignaturePattern notSignaturePattern = (NotSignaturePattern) sigPattern; | |||
s.writeByte(NOT); | |||
writeCompoundSignaturePattern(s, notSignaturePattern.getNegated()); | |||
s.writeInt(0); | |||
s.writeInt(0); // TODO positions not yet set properly | |||
} | |||
} | |||
} |
@@ -0,0 +1,104 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2010 Contributors | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Andy Clement - SpringSource | |||
* ******************************************************************/ | |||
package org.aspectj.weaver.patterns; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
import org.aspectj.weaver.World; | |||
/** | |||
* Represents the AND of two other signature patterns. | |||
* | |||
* @author Andy Clement | |||
* @since 1.6.9 | |||
*/ | |||
public class AndSignaturePattern extends AbstractSignaturePattern { | |||
private ISignaturePattern leftSp; | |||
private ISignaturePattern rightSp; | |||
private List<ExactTypePattern> exactDeclaringTypes; | |||
public AndSignaturePattern(ISignaturePattern leftSp, ISignaturePattern rightSp) { | |||
this.leftSp = leftSp; | |||
this.rightSp = rightSp; | |||
} | |||
public boolean couldEverMatch(ResolvedType type) { | |||
return leftSp.couldEverMatch(type) || rightSp.couldEverMatch(type); | |||
} | |||
public List<ExactTypePattern> getExactDeclaringTypes() { | |||
if (exactDeclaringTypes == null) { | |||
exactDeclaringTypes = new ArrayList<ExactTypePattern>(); | |||
exactDeclaringTypes.addAll(leftSp.getExactDeclaringTypes()); | |||
exactDeclaringTypes.addAll(rightSp.getExactDeclaringTypes()); | |||
} | |||
return exactDeclaringTypes; | |||
} | |||
public boolean isMatchOnAnyName() { | |||
return leftSp.isMatchOnAnyName() || rightSp.isMatchOnAnyName(); | |||
} | |||
public boolean isStarAnnotation() { | |||
return leftSp.isStarAnnotation() || rightSp.isStarAnnotation(); | |||
} | |||
public boolean matches(Member member, World world, boolean b) { | |||
return (leftSp.matches(member, world, b)) && (rightSp.matches(member, world, b)); | |||
} | |||
public ISignaturePattern parameterizeWith(Map<String, UnresolvedType> typeVariableBindingMap, World world) { | |||
return new AndSignaturePattern(leftSp.parameterizeWith(typeVariableBindingMap, world), rightSp.parameterizeWith( | |||
typeVariableBindingMap, world)); | |||
} | |||
public ISignaturePattern resolveBindings(IScope scope, Bindings bindings) { | |||
// Whilst the real SignaturePattern returns 'this' we are safe to return 'this' here rather than build a new | |||
// AndSignaturePattern | |||
leftSp.resolveBindings(scope, bindings); | |||
rightSp.resolveBindings(scope, bindings); | |||
return this; | |||
} | |||
public static ISignaturePattern readAndSignaturePattern(VersionedDataInputStream s, ISourceContext context) throws IOException { | |||
AndSignaturePattern ret = new AndSignaturePattern(readCompoundSignaturePattern(s, context), readCompoundSignaturePattern(s, | |||
context)); | |||
s.readInt(); | |||
s.readInt(); | |||
// ret.readLocation(context, s); // TODO output position currently useless so dont need to do this | |||
return ret; | |||
} | |||
public ISignaturePattern getLeft() { | |||
return leftSp; | |||
} | |||
public ISignaturePattern getRight() { | |||
return rightSp; | |||
} | |||
public String toString() { | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(leftSp.toString()).append(" && ").append(rightSp.toString()); | |||
return sb.toString(); | |||
} | |||
} |
@@ -17,6 +17,7 @@ import java.util.Map; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
import org.aspectj.weaver.World; | |||
@@ -63,7 +64,7 @@ public abstract class Declare extends PatternNode { | |||
* Returns a version of this declare element in which all references to type variables are replaced with their bindings given in | |||
* the map. | |||
*/ | |||
public abstract Declare parameterizeWith(Map typeVariableBindingMap, World w); | |||
public abstract Declare parameterizeWith(Map<String, UnresolvedType> typeVariableBindingMap, World w); | |||
/** | |||
* Indicates if this declare should be treated like advice. If true, the declare will have no effect in an abstract aspect. It |
@@ -13,7 +13,9 @@ | |||
package org.aspectj.weaver.patterns; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.aspectj.bridge.MessageUtil; | |||
@@ -26,7 +28,13 @@ import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
import org.aspectj.weaver.WeaverMessages; | |||
import org.aspectj.weaver.World; | |||
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; | |||
/** | |||
* Represents a declare annotation statement, one of atField, atMethod, atConstructor or atType. | |||
* | |||
* @author Andy Clement | |||
*/ | |||
public class DeclareAnnotation extends Declare { | |||
public static final Kind AT_TYPE = new Kind(1, "type"); | |||
@@ -35,62 +43,46 @@ public class DeclareAnnotation extends Declare { | |||
public static final Kind AT_CONSTRUCTOR = new Kind(4, "constructor"); | |||
private Kind kind; | |||
private TypePattern typePattern; // for declare @type | |||
private SignaturePattern sigPattern; // for declare | |||
// @field,@method,@constructor | |||
private String annotationMethod = "unknown"; | |||
private String annotationString = "@<annotation>"; | |||
// for declare @type | |||
private TypePattern typePattern; | |||
// for declare @field,@method,@constructor | |||
private ISignaturePattern signaturePattern; | |||
private ResolvedType containingAspect; | |||
private AnnotationAJ annotation; | |||
private ResolvedType annotationType; | |||
private List<String> annotationMethods; | |||
private List<String> annotationStrings; | |||
private AnnotationAJ annotation; // discovered when required | |||
private ResolvedType annotationType; // discovered when required | |||
/** | |||
* Captures type of declare annotation (method/type/field/constructor) | |||
* Constructor for declare atType. | |||
*/ | |||
public static class Kind { | |||
private final int id; | |||
private String s; | |||
private Kind(int n, String name) { | |||
id = n; | |||
s = name; | |||
} | |||
@Override | |||
public int hashCode() { | |||
return (19 + 37 * id); | |||
} | |||
@Override | |||
public boolean equals(Object obj) { | |||
if (!(obj instanceof Kind)) { | |||
return false; | |||
} | |||
Kind other = (Kind) obj; | |||
return other.id == id; | |||
} | |||
@Override | |||
public String toString() { | |||
return "at_" + s; | |||
} | |||
} | |||
public DeclareAnnotation(Kind kind, TypePattern typePattern) { | |||
this.typePattern = typePattern; | |||
this.kind = kind; | |||
init(); | |||
} | |||
/** | |||
* Returns the string, useful before the real annotation has been resolved | |||
* Constructor for declare atMethod/atField/atConstructor. | |||
*/ | |||
public String getAnnotationString() { | |||
return annotationString; | |||
public DeclareAnnotation(Kind kind, ISignaturePattern sigPattern) { | |||
this.signaturePattern = sigPattern; | |||
this.kind = kind; | |||
init(); | |||
} | |||
public DeclareAnnotation(Kind kind, SignaturePattern sigPattern) { | |||
this.sigPattern = sigPattern; | |||
this.kind = kind; | |||
private void init() { | |||
this.annotationMethods = new ArrayList<String>(); | |||
annotationMethods.add("unknown"); | |||
this.annotationStrings = new ArrayList<String>(); | |||
annotationStrings.add("@<annotation>"); | |||
} | |||
/** | |||
* Returns the string, useful before the real annotation has been resolved | |||
*/ | |||
public String getAnnotationString() { | |||
return annotationStrings.get(0); | |||
} | |||
public boolean isExactPattern() { | |||
@@ -98,18 +90,18 @@ public class DeclareAnnotation extends Declare { | |||
} | |||
public String getAnnotationMethod() { | |||
return annotationMethod; | |||
return annotationMethods.get(0); | |||
} | |||
@Override | |||
public String toString() { | |||
StringBuffer ret = new StringBuffer(); | |||
StringBuilder ret = new StringBuilder(); | |||
ret.append("declare @"); | |||
ret.append(kind); | |||
ret.append(" : "); | |||
ret.append(typePattern != null ? typePattern.toString() : sigPattern.toString()); | |||
ret.append(typePattern != null ? typePattern.toString() : signaturePattern.toString()); | |||
ret.append(" : "); | |||
ret.append(annotationString); | |||
ret.append(annotationStrings.get(0)); | |||
return ret.toString(); | |||
} | |||
@@ -137,24 +129,24 @@ public class DeclareAnnotation extends Declare { | |||
if (typePattern != null) { | |||
typePattern = typePattern.resolveBindings(scope, Bindings.NONE, false, false); | |||
} | |||
if (sigPattern != null) { | |||
sigPattern = sigPattern.resolveBindings(scope, Bindings.NONE); | |||
if (signaturePattern != null) { | |||
signaturePattern = signaturePattern.resolveBindings(scope, Bindings.NONE); | |||
} | |||
this.containingAspect = scope.getEnclosingType(); | |||
} | |||
@Override | |||
public Declare parameterizeWith(Map typeVariableBindingMap, World w) { | |||
public Declare parameterizeWith(Map<String, UnresolvedType> typeVariableBindingMap, World w) { | |||
DeclareAnnotation ret; | |||
if (this.kind == AT_TYPE) { | |||
ret = new DeclareAnnotation(kind, this.typePattern.parameterizeWith(typeVariableBindingMap, w)); | |||
} else { | |||
ret = new DeclareAnnotation(kind, this.sigPattern.parameterizeWith(typeVariableBindingMap, w)); | |||
ret = new DeclareAnnotation(kind, this.signaturePattern.parameterizeWith(typeVariableBindingMap, w)); | |||
} | |||
ret.annotationMethod = this.annotationMethod; | |||
ret.annotationString = this.annotationString; | |||
ret.containingAspect = this.containingAspect; | |||
ret.annotationMethods = this.annotationMethods; | |||
ret.annotationStrings = this.annotationStrings; | |||
ret.annotation = this.annotation; | |||
ret.containingAspect = this.containingAspect; | |||
ret.copyLocationFrom(this); | |||
return ret; | |||
} | |||
@@ -164,12 +156,12 @@ public class DeclareAnnotation extends Declare { | |||
return false; | |||
} | |||
public void setAnnotationString(String as) { | |||
this.annotationString = as; | |||
public void setAnnotationString(String annotationString) { | |||
this.annotationStrings.set(0, annotationString); | |||
} | |||
public void setAnnotationMethod(String methName) { | |||
this.annotationMethod = methName; | |||
public void setAnnotationMethod(String methodName) { | |||
this.annotationMethods.set(0, methodName); | |||
} | |||
@Override | |||
@@ -181,10 +173,10 @@ public class DeclareAnnotation extends Declare { | |||
if (!this.kind.equals(other.kind)) { | |||
return false; | |||
} | |||
if (!this.annotationString.equals(other.annotationString)) { | |||
if (!this.annotationStrings.get(0).equals(other.annotationStrings.get(0))) { | |||
return false; | |||
} | |||
if (!this.annotationMethod.equals(other.annotationMethod)) { | |||
if (!this.annotationMethods.get(0).equals(other.annotationMethods.get(0))) { | |||
return false; | |||
} | |||
if (this.typePattern != null) { | |||
@@ -192,8 +184,8 @@ public class DeclareAnnotation extends Declare { | |||
return false; | |||
} | |||
} | |||
if (this.sigPattern != null) { | |||
if (!sigPattern.equals(other.sigPattern)) { | |||
if (this.signaturePattern != null) { | |||
if (!signaturePattern.equals(other.signaturePattern)) { | |||
return false; | |||
} | |||
} | |||
@@ -204,33 +196,35 @@ public class DeclareAnnotation extends Declare { | |||
public int hashCode() { | |||
int result = 19; | |||
result = 37 * result + kind.hashCode(); | |||
result = 37 * result + annotationString.hashCode(); | |||
result = 37 * result + annotationMethod.hashCode(); | |||
result = 37 * result + annotationStrings.get(0).hashCode(); | |||
result = 37 * result + annotationMethods.get(0).hashCode(); | |||
if (typePattern != null) { | |||
result = 37 * result + typePattern.hashCode(); | |||
} | |||
if (sigPattern != null) { | |||
result = 37 * result + sigPattern.hashCode(); | |||
if (signaturePattern != null) { | |||
result = 37 * result + signaturePattern.hashCode(); | |||
} | |||
return result; | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream) | |||
*/ | |||
@Override | |||
public void write(CompressingDataOutputStream s) throws IOException { | |||
s.writeByte(Declare.ANNOTATION); | |||
s.writeInt(kind.id); | |||
s.writeUTF(annotationString); | |||
s.writeUTF(annotationMethod); | |||
int max = 0; | |||
s.writeByte(max = annotationStrings.size()); | |||
for (int i = 0; i < max; i++) { | |||
s.writeUTF(annotationStrings.get(i)); | |||
} | |||
s.writeByte(max = annotationMethods.size()); | |||
for (int i = 0; i < max; i++) { | |||
s.writeUTF(annotationMethods.get(i)); | |||
} | |||
if (typePattern != null) { | |||
typePattern.write(s); | |||
} | |||
if (sigPattern != null) { | |||
sigPattern.write(s); | |||
if (signaturePattern != null) { | |||
AbstractSignaturePattern.writeCompoundSignaturePattern(s, signaturePattern); | |||
} | |||
writeLocation(s); | |||
} | |||
@@ -238,7 +232,16 @@ public class DeclareAnnotation extends Declare { | |||
public static Declare read(VersionedDataInputStream s, ISourceContext context) throws IOException { | |||
DeclareAnnotation ret = null; | |||
int kind = s.readInt(); | |||
// old format was just a single string and method | |||
if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_AJ169) { | |||
// int numAnnotationStrings = | |||
s.readByte(); | |||
} | |||
String annotationString = s.readUTF(); | |||
if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_AJ169) { | |||
// int numAnnotationMethods = | |||
s.readByte(); | |||
} | |||
String annotationMethod = s.readUTF(); | |||
TypePattern tp = null; | |||
SignaturePattern sp = null; | |||
@@ -248,52 +251,61 @@ public class DeclareAnnotation extends Declare { | |||
ret = new DeclareAnnotation(AT_TYPE, tp); | |||
break; | |||
case 2: | |||
sp = SignaturePattern.read(s, context); | |||
ret = new DeclareAnnotation(AT_FIELD, sp); | |||
if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_AJ169) { | |||
ret = new DeclareAnnotation(AT_FIELD, AbstractSignaturePattern.readCompoundSignaturePattern(s, context)); | |||
} else { | |||
sp = SignaturePattern.read(s, context); | |||
ret = new DeclareAnnotation(AT_FIELD, sp); | |||
} | |||
break; | |||
case 3: | |||
sp = SignaturePattern.read(s, context); | |||
ret = new DeclareAnnotation(AT_METHOD, sp); | |||
if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_AJ169) { | |||
ret = new DeclareAnnotation(AT_METHOD, AbstractSignaturePattern.readCompoundSignaturePattern(s, context)); | |||
} else { | |||
sp = SignaturePattern.read(s, context); | |||
ret = new DeclareAnnotation(AT_METHOD, sp); | |||
} | |||
break; | |||
case 4: | |||
sp = SignaturePattern.read(s, context); | |||
ret = new DeclareAnnotation(AT_CONSTRUCTOR, sp); | |||
if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_AJ169) { | |||
ret = new DeclareAnnotation(AT_CONSTRUCTOR, AbstractSignaturePattern.readCompoundSignaturePattern(s, context)); | |||
} else { | |||
sp = SignaturePattern.read(s, context); | |||
ret = new DeclareAnnotation(AT_CONSTRUCTOR, sp); | |||
} | |||
break; | |||
} | |||
// if (kind==AT_TYPE.id) { | |||
// tp = TypePattern.read(s,context); | |||
// ret = new DeclareAnnotation(AT_TYPE,tp); | |||
// } else { | |||
// sp = SignaturePattern.read(s,context); | |||
// ret = new DeclareAnnotation(kind,sp); | |||
// } | |||
ret.setAnnotationString(annotationString); | |||
ret.setAnnotationMethod(annotationMethod); | |||
ret.readLocation(context, s); | |||
return ret; | |||
} | |||
// public boolean getAnnotationIfMatches(ResolvedType onType) { | |||
// return (match(onType)); | |||
// } | |||
/** | |||
* For @constructor, @method, @field | |||
* For declare atConstructor, atMethod, atField | |||
*/ | |||
public boolean matches(ResolvedMember rm, World world) { | |||
return sigPattern.matches(rm, world, false); | |||
public boolean matches(ResolvedMember resolvedmember, World world) { | |||
if (kind == AT_METHOD || kind == AT_CONSTRUCTOR) { | |||
if (resolvedmember != null && resolvedmember.getName().charAt(0) == '<') { | |||
// <clinit> or <init> | |||
if (kind == AT_METHOD) { | |||
return false; | |||
} | |||
} | |||
} | |||
return signaturePattern.matches(resolvedmember, world, false); | |||
} | |||
/** | |||
* For @type | |||
* For declare atType. | |||
*/ | |||
public boolean matches(ResolvedType typeX) { | |||
if (!typePattern.matchesStatically(typeX)) { | |||
public boolean matches(ResolvedType type) { | |||
if (!typePattern.matchesStatically(type)) { | |||
return false; | |||
} | |||
if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() && !typeX.isExposedToWeaver()) { | |||
typeX.getWorld().getLint().typeNotExposedToWeaver.signal(typeX.getName(), getSourceLocation()); | |||
if (type.getWorld().getLint().typeNotExposedToWeaver.isEnabled() && !type.isExposedToWeaver()) { | |||
type.getWorld().getLint().typeNotExposedToWeaver.signal(type.getName(), getSourceLocation()); | |||
} | |||
return true; | |||
} | |||
@@ -326,8 +338,9 @@ public class DeclareAnnotation extends Declare { | |||
if (annotation != null) { | |||
return; | |||
} | |||
for (Iterator iter = containingAspect.getMethods(true, true); iter.hasNext();) { | |||
ResolvedMember member = (ResolvedMember) iter.next(); | |||
String annotationMethod = annotationMethods.get(0); | |||
for (Iterator<ResolvedMember> iter = containingAspect.getMethods(true, true); iter.hasNext();) { | |||
ResolvedMember member = iter.next(); | |||
if (member.getName().equals(annotationMethod)) { | |||
AnnotationAJ[] annos = member.getAnnotations(); | |||
if (annos == null) { | |||
@@ -349,18 +362,16 @@ public class DeclareAnnotation extends Declare { | |||
return typePattern; | |||
} | |||
public SignaturePattern getSignaturePattern() { | |||
return sigPattern; | |||
public ISignaturePattern getSignaturePattern() { | |||
return signaturePattern; | |||
} | |||
public boolean isStarredAnnotationPattern() { | |||
if (typePattern != null) { | |||
return typePattern.isStarAnnotation(); | |||
} else { | |||
return signaturePattern.isStarAnnotation(); | |||
} | |||
if (sigPattern != null) { | |||
return sigPattern.isStarAnnotation(); | |||
} | |||
throw new RuntimeException("Impossible! what kind of deca is this: " + this); | |||
} | |||
public Kind getKind() { | |||
@@ -388,8 +399,9 @@ public class DeclareAnnotation extends Declare { | |||
*/ | |||
public ResolvedType getAnnotationType() { | |||
if (annotationType == null) { | |||
for (Iterator iter = containingAspect.getMethods(true, true); iter.hasNext();) { | |||
ResolvedMember member = (ResolvedMember) iter.next(); | |||
String annotationMethod = annotationMethods.get(0); | |||
for (Iterator<ResolvedMember> iter = containingAspect.getMethods(true, true); iter.hasNext();) { | |||
ResolvedMember member = iter.next(); | |||
if (member.getName().equals(annotationMethod)) { | |||
ResolvedType[] annoTypes = member.getAnnotationTypes(); | |||
if (annoTypes == null) { | |||
@@ -417,8 +429,8 @@ public class DeclareAnnotation extends Declare { | |||
} | |||
public String getPatternAsString() { | |||
if (sigPattern != null) { | |||
return sigPattern.toString(); | |||
if (signaturePattern != null) { | |||
return signaturePattern.toString(); | |||
} | |||
if (typePattern != null) { | |||
return typePattern.toString(); | |||
@@ -437,8 +449,8 @@ public class DeclareAnnotation extends Declare { | |||
// do something here so we don't iterate over all fields and all methods | |||
// in all types exposed to the weaver! So look out for bugs here and | |||
// we can update the test as appropriate. | |||
if (sigPattern != null) { | |||
return sigPattern.getDeclaringType().matches(type, TypePattern.STATIC).maybeTrue(); | |||
if (signaturePattern != null) { | |||
return signaturePattern.couldEverMatch(type); | |||
} | |||
return true; | |||
} | |||
@@ -450,4 +462,36 @@ public class DeclareAnnotation extends Declare { | |||
public String getNameSuffix() { | |||
return getKind().toString(); | |||
} | |||
/** | |||
* Captures type of declare annotation (method/type/field/constructor) | |||
*/ | |||
public static class Kind { | |||
private final int id; | |||
private String s; | |||
private Kind(int n, String name) { | |||
id = n; | |||
s = name; | |||
} | |||
@Override | |||
public int hashCode() { | |||
return (19 + 37 * id); | |||
} | |||
@Override | |||
public boolean equals(Object obj) { | |||
if (!(obj instanceof Kind)) { | |||
return false; | |||
} | |||
Kind other = (Kind) obj; | |||
return other.id == id; | |||
} | |||
@Override | |||
public String toString() { | |||
return "at_" + s; | |||
} | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
package org.aspectj.weaver.patterns; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.World; | |||
public interface ISignaturePattern { | |||
byte PATTERN = 1; | |||
byte NOT = 2; | |||
byte OR = 3; | |||
byte AND = 4; | |||
boolean matches(Member member, World world, boolean b); | |||
ISignaturePattern parameterizeWith(Map<String, UnresolvedType> typeVariableBindingMap, World world); | |||
ISignaturePattern resolveBindings(IScope scope, Bindings none); | |||
List<ExactTypePattern> getExactDeclaringTypes(); | |||
boolean isMatchOnAnyName(); | |||
boolean couldEverMatch(ResolvedType type); | |||
boolean isStarAnnotation(); | |||
} |
@@ -0,0 +1,91 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2010 Contributors | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Andy Clement - SpringSource | |||
* ******************************************************************/ | |||
package org.aspectj.weaver.patterns; | |||
import java.io.IOException; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
import org.aspectj.weaver.World; | |||
/** | |||
* Represents the NOT of a signature pattern | |||
* | |||
* @author Andy Clement | |||
* @since 1.6.9 | |||
*/ | |||
public class NotSignaturePattern extends AbstractSignaturePattern { | |||
private ISignaturePattern negatedSp; | |||
public NotSignaturePattern(ISignaturePattern negatedSp) { | |||
this.negatedSp = negatedSp; | |||
} | |||
public boolean couldEverMatch(ResolvedType type) { | |||
if (negatedSp.getExactDeclaringTypes().size() == 0) { | |||
return true; | |||
} | |||
return !negatedSp.couldEverMatch(type); | |||
} | |||
public List<ExactTypePattern> getExactDeclaringTypes() { | |||
return negatedSp.getExactDeclaringTypes(); | |||
} | |||
public boolean isMatchOnAnyName() { | |||
return negatedSp.isMatchOnAnyName(); | |||
} | |||
public boolean isStarAnnotation() { | |||
return negatedSp.isStarAnnotation(); | |||
} | |||
public boolean matches(Member member, World world, boolean b) { | |||
return !negatedSp.matches(member, world, b); | |||
} | |||
public ISignaturePattern parameterizeWith(Map<String, UnresolvedType> typeVariableBindingMap, World world) { | |||
return new NotSignaturePattern(negatedSp.parameterizeWith(typeVariableBindingMap, world)); | |||
} | |||
public ISignaturePattern resolveBindings(IScope scope, Bindings bindings) { | |||
// Whilst the real SignaturePattern returns 'this' we are safe to return 'this' here rather than build a new | |||
// AndSignaturePattern | |||
negatedSp.resolveBindings(scope, bindings); | |||
return this; | |||
} | |||
public static ISignaturePattern readNotSignaturePattern(VersionedDataInputStream s, ISourceContext context) throws IOException { | |||
NotSignaturePattern ret = new NotSignaturePattern(readCompoundSignaturePattern(s, context)); | |||
// ret.readLocation(context, s); // TODO output position currently useless so dont need to do this | |||
s.readInt(); | |||
s.readInt(); | |||
return ret; | |||
} | |||
public ISignaturePattern getNegated() { | |||
return negatedSp; | |||
} | |||
public String toString() { | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append("!").append(negatedSp.toString()); | |||
return sb.toString(); | |||
} | |||
} |
@@ -0,0 +1,104 @@ | |||
/* ******************************************************************* | |||
* Copyright (c) 2010 Contributors | |||
* All rights reserved. | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Public License v1.0 | |||
* which accompanies this distribution and is available at | |||
* http://www.eclipse.org/legal/epl-v10.html | |||
* | |||
* Contributors: | |||
* Andy Clement - SpringSource | |||
* ******************************************************************/ | |||
package org.aspectj.weaver.patterns; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.aspectj.weaver.ISourceContext; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.ResolvedType; | |||
import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
import org.aspectj.weaver.World; | |||
/** | |||
* Represents the OR of two other signature patterns. | |||
* | |||
* @author Andy Clement | |||
* @since 1.6.9 | |||
*/ | |||
public class OrSignaturePattern extends AbstractSignaturePattern { | |||
private ISignaturePattern leftSp; | |||
private ISignaturePattern rightSp; | |||
private List<ExactTypePattern> exactDeclaringTypes; | |||
public OrSignaturePattern(ISignaturePattern leftSp, ISignaturePattern rightSp) { | |||
this.leftSp = leftSp; | |||
this.rightSp = rightSp; | |||
} | |||
public boolean couldEverMatch(ResolvedType type) { | |||
return leftSp.couldEverMatch(type) || rightSp.couldEverMatch(type); | |||
} | |||
public List<ExactTypePattern> getExactDeclaringTypes() { | |||
if (exactDeclaringTypes == null) { | |||
exactDeclaringTypes = new ArrayList<ExactTypePattern>(); | |||
exactDeclaringTypes.addAll(leftSp.getExactDeclaringTypes()); | |||
exactDeclaringTypes.addAll(rightSp.getExactDeclaringTypes()); | |||
} | |||
return exactDeclaringTypes; | |||
} | |||
public boolean isMatchOnAnyName() { | |||
return leftSp.isMatchOnAnyName() || rightSp.isMatchOnAnyName(); | |||
} | |||
public boolean isStarAnnotation() { | |||
return leftSp.isStarAnnotation() || rightSp.isStarAnnotation(); | |||
} | |||
public boolean matches(Member member, World world, boolean b) { | |||
return (leftSp.matches(member, world, b)) || (rightSp.matches(member, world, b)); | |||
} | |||
public ISignaturePattern parameterizeWith(Map<String, UnresolvedType> typeVariableBindingMap, World world) { | |||
return new OrSignaturePattern(leftSp.parameterizeWith(typeVariableBindingMap, world), rightSp.parameterizeWith( | |||
typeVariableBindingMap, world)); | |||
} | |||
public ISignaturePattern resolveBindings(IScope scope, Bindings bindings) { | |||
// Whilst the real SignaturePattern returns 'this' we are safe to return 'this' here rather than build a new | |||
// AndSignaturePattern | |||
leftSp.resolveBindings(scope, bindings); | |||
rightSp.resolveBindings(scope, bindings); | |||
return this; | |||
} | |||
public static ISignaturePattern readOrSignaturePattern(VersionedDataInputStream s, ISourceContext context) throws IOException { | |||
OrSignaturePattern ret = new OrSignaturePattern(readCompoundSignaturePattern(s, context), readCompoundSignaturePattern(s, | |||
context)); | |||
s.readInt(); | |||
s.readInt(); | |||
// ret.readLocation(context, s); // TODO output position currently useless so dont need to do this | |||
return ret; | |||
} | |||
public ISignaturePattern getLeft() { | |||
return leftSp; | |||
} | |||
public ISignaturePattern getRight() { | |||
return rightSp; | |||
} | |||
public String toString() { | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(leftSp.toString()).append(" || ").append(rightSp.toString()); | |||
return sb.toString(); | |||
} | |||
} |
@@ -17,7 +17,6 @@ package org.aspectj.weaver.patterns; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
@@ -42,7 +41,7 @@ public class PatternParser { | |||
private boolean allowHasTypePatterns = false; | |||
/** extension handlers used in weaver tools API only */ | |||
private Set pointcutDesignatorHandlers = Collections.EMPTY_SET; | |||
private Set<PointcutDesignatorHandler> pointcutDesignatorHandlers = Collections.emptySet(); | |||
private World world; | |||
/** | |||
@@ -55,7 +54,7 @@ public class PatternParser { | |||
} | |||
/** only used by weaver tools API */ | |||
public void setPointcutDesignatorHandlers(Set handlers, World world) { | |||
public void setPointcutDesignatorHandlers(Set<PointcutDesignatorHandler> handlers, World world) { | |||
this.pointcutDesignatorHandlers = handlers; | |||
this.world = world; | |||
} | |||
@@ -183,21 +182,9 @@ public class PatternParser { | |||
} | |||
public DeclareAnnotation parseDeclareAtMethod(boolean isMethod) { | |||
if (maybeEat("(")) { | |||
DeclareAnnotation da = parseDeclareAtMethod(isMethod); | |||
eat(")", "missing ')' - unbalanced parentheses around signature pattern in declare @" | |||
+ (isMethod ? "method" : "constructor")); | |||
return da; | |||
} | |||
SignaturePattern sp = parseMethodOrConstructorSignaturePattern(); | |||
boolean isConstructorPattern = (sp.getKind() == Member.CONSTRUCTOR); | |||
if (isMethod && isConstructorPattern) { | |||
throw new ParserException("method signature pattern", tokenSource.peek(-1)); | |||
} | |||
if (!isMethod && !isConstructorPattern) { | |||
throw new ParserException("constructor signature pattern", tokenSource.peek(-1)); | |||
} | |||
if (isConstructorPattern) { | |||
ISignaturePattern sp = parseCompoundMethodOrConstructorSignaturePattern(isMethod);// parseMethodOrConstructorSignaturePattern(); | |||
if (!isMethod) { | |||
return new DeclareAnnotation(DeclareAnnotation.AT_CONSTRUCTOR, sp); | |||
} else { | |||
return new DeclareAnnotation(DeclareAnnotation.AT_METHOD, sp); | |||
@@ -205,13 +192,45 @@ public class PatternParser { | |||
} | |||
public DeclareAnnotation parseDeclareAtField() { | |||
if (maybeEat("(")) { | |||
DeclareAnnotation da = parseDeclareAtField(); | |||
eat(")", "missing ')' - unbalanced parentheses around field signature pattern in declare @field"); | |||
return da; | |||
ISignaturePattern compoundFieldSignaturePattern = parseCompoundFieldSignaturePattern(); | |||
return new DeclareAnnotation(DeclareAnnotation.AT_FIELD, compoundFieldSignaturePattern); | |||
} | |||
public ISignaturePattern parseCompoundFieldSignaturePattern() { | |||
ISignaturePattern atomicFieldSignaturePattern = parseMaybeParenthesizedFieldSignaturePattern(); | |||
while (isEitherAndOrOr()) { | |||
if (maybeEat("&&")) { | |||
atomicFieldSignaturePattern = new AndSignaturePattern(atomicFieldSignaturePattern, | |||
parseMaybeParenthesizedFieldSignaturePattern()); | |||
} | |||
if (maybeEat("||")) { | |||
atomicFieldSignaturePattern = new OrSignaturePattern(atomicFieldSignaturePattern, | |||
parseMaybeParenthesizedFieldSignaturePattern()); | |||
} | |||
} | |||
SignaturePattern fieldSigPattern = parseFieldSignaturePattern(); | |||
return new DeclareAnnotation(DeclareAnnotation.AT_FIELD, fieldSigPattern); | |||
return atomicFieldSignaturePattern; | |||
} | |||
private boolean isEitherAndOrOr() { | |||
String tokenstring = tokenSource.peek().getString(); | |||
return tokenstring.equals("&&") || tokenstring.equals("||"); | |||
} | |||
public ISignaturePattern parseCompoundMethodOrConstructorSignaturePattern(boolean isMethod) { | |||
ISignaturePattern atomicMethodCtorSignaturePattern = parseMaybeParenthesizedMethodOrConstructorSignaturePattern(isMethod); | |||
while (isEitherAndOrOr()) { | |||
if (maybeEat("&&")) { | |||
atomicMethodCtorSignaturePattern = new AndSignaturePattern(atomicMethodCtorSignaturePattern, | |||
parseMaybeParenthesizedMethodOrConstructorSignaturePattern(isMethod)); | |||
} | |||
if (maybeEat("||")) { | |||
atomicMethodCtorSignaturePattern = new OrSignaturePattern(atomicMethodCtorSignaturePattern, | |||
parseMaybeParenthesizedMethodOrConstructorSignaturePattern(isMethod)); | |||
} | |||
} | |||
return atomicMethodCtorSignaturePattern; | |||
} | |||
public DeclarePrecedence parseDominates() { | |||
@@ -421,8 +440,7 @@ public class PatternParser { | |||
boolean matchedByExtensionDesignator = false; | |||
// see if a registered handler wants to parse it, otherwise | |||
// treat as a reference pointcut | |||
for (Iterator iter = this.pointcutDesignatorHandlers.iterator(); iter.hasNext();) { | |||
PointcutDesignatorHandler pcd = (PointcutDesignatorHandler) iter.next(); | |||
for (PointcutDesignatorHandler pcd : pointcutDesignatorHandlers) { | |||
if (pcd.getDesignatorName().equals(kind)) { | |||
p = parseDesignatorPointcut(pcd); | |||
matchedByExtensionDesignator = true; | |||
@@ -1521,6 +1539,51 @@ public class PatternParser { | |||
return false; | |||
} | |||
public ISignaturePattern parseMaybeParenthesizedFieldSignaturePattern() { | |||
boolean negated = tokenSource.peek().getString().equals("!") && tokenSource.peek(1).getString().equals("("); | |||
if (negated) { | |||
eat("!"); | |||
} | |||
ISignaturePattern result = null; | |||
if (maybeEat("(")) { | |||
result = parseCompoundFieldSignaturePattern(); | |||
eat(")", "missing ')' - unbalanced parentheses around field signature pattern in declare @field"); | |||
if (negated) { | |||
result = new NotSignaturePattern(result); | |||
} | |||
} else { | |||
result = parseFieldSignaturePattern(); | |||
} | |||
return result; | |||
} | |||
public ISignaturePattern parseMaybeParenthesizedMethodOrConstructorSignaturePattern(boolean isMethod) { | |||
boolean negated = tokenSource.peek().getString().equals("!") && tokenSource.peek(1).getString().equals("("); | |||
if (negated) { | |||
eat("!"); | |||
} | |||
ISignaturePattern result = null; | |||
if (maybeEat("(")) { | |||
result = parseCompoundMethodOrConstructorSignaturePattern(isMethod); | |||
eat(")", "missing ')' - unbalanced parentheses around method/ctor signature pattern in declare annotation"); | |||
if (negated) { | |||
result = new NotSignaturePattern(result); | |||
} | |||
} else { | |||
SignaturePattern sp = parseMethodOrConstructorSignaturePattern(); | |||
boolean isConstructorPattern = (sp.getKind() == Member.CONSTRUCTOR); | |||
if (isMethod && isConstructorPattern) { | |||
throw new ParserException("method signature pattern", tokenSource.peek(-1)); | |||
} | |||
if (!isMethod && !isConstructorPattern) { | |||
throw new ParserException("constructor signature pattern", tokenSource.peek(-1)); | |||
} | |||
result = sp; | |||
} | |||
return result; | |||
} | |||
public SignaturePattern parseFieldSignaturePattern() { | |||
int startPos = tokenSource.peek().getStart(); | |||
@@ -15,6 +15,7 @@ package org.aspectj.weaver.patterns; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -41,7 +42,7 @@ import org.aspectj.weaver.UnresolvedType; | |||
import org.aspectj.weaver.VersionedDataInputStream; | |||
import org.aspectj.weaver.World; | |||
public class SignaturePattern extends PatternNode { | |||
public class SignaturePattern extends PatternNode implements ISignaturePattern { | |||
private MemberKind kind; | |||
private ModifiersPattern modifiers; | |||
private TypePattern returnType; | |||
@@ -289,7 +290,7 @@ public class SignaturePattern extends PatternNode { | |||
* return a copy of this signature pattern in which every type variable reference is replaced by the corresponding entry in the | |||
* map. | |||
*/ | |||
public SignaturePattern parameterizeWith(Map typeVariableMap, World w) { | |||
public SignaturePattern parameterizeWith(Map<String, UnresolvedType> typeVariableMap, World w) { | |||
SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType.parameterizeWith(typeVariableMap, w), declaringType | |||
.parameterizeWith(typeVariableMap, w), name, parameterTypes.parameterizeWith(typeVariableMap, w), throwsPattern | |||
.parameterizeWith(typeVariableMap, w), annotationPattern.parameterizeWith(typeVariableMap, w)); | |||
@@ -902,6 +903,7 @@ public class SignaturePattern extends PatternNode { | |||
} | |||
public static SignaturePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException { | |||
// ISignaturePattern kind should already have been read by the time this read is entered | |||
MemberKind kind = MemberKind.read(s); | |||
ModifiersPattern modifiers = ModifiersPattern.read(s); | |||
TypePattern returnType = TypePattern.read(s, context); | |||
@@ -979,4 +981,22 @@ public class SignaturePattern extends PatternNode { | |||
return isExactDeclaringTypePattern; | |||
} | |||
public boolean isMatchOnAnyName() { | |||
return getName().isAny(); | |||
} | |||
public List<ExactTypePattern> getExactDeclaringTypes() { | |||
if (declaringType instanceof ExactTypePattern) { | |||
List<ExactTypePattern> l = new ArrayList<ExactTypePattern>(); | |||
l.add((ExactTypePattern) declaringType); | |||
return l; | |||
} else { | |||
return Collections.emptyList(); | |||
} | |||
} | |||
public boolean couldEverMatch(ResolvedType type) { | |||
return declaringType.matches(type, TypePattern.STATIC).maybeTrue(); | |||
} | |||
} |
@@ -15,7 +15,6 @@ import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.URL; | |||
import java.util.HashSet; | |||
import java.util.Iterator; | |||
import java.util.Properties; | |||
import java.util.Set; | |||
@@ -57,15 +56,15 @@ public class PointcutParser { | |||
private ReflectionWorld world; | |||
private WeakClassLoaderReference classLoaderReference; | |||
private final Set supportedPrimitives; | |||
private final Set pointcutDesignators = new HashSet(); | |||
private final Set<PointcutPrimitive> supportedPrimitives; | |||
private final Set<PointcutDesignatorHandler> pointcutDesignators = new HashSet<PointcutDesignatorHandler>(); | |||
/** | |||
* @return a Set containing every PointcutPrimitive except if, cflow, and cflowbelow (useful for passing to PointcutParser | |||
* constructor). | |||
*/ | |||
public static Set getAllSupportedPointcutPrimitives() { | |||
Set primitives = new HashSet(); | |||
public static Set<PointcutPrimitive> getAllSupportedPointcutPrimitives() { | |||
Set<PointcutPrimitive> primitives = new HashSet<PointcutPrimitive>(); | |||
primitives.add(PointcutPrimitive.ADVICE_EXECUTION); | |||
primitives.add(PointcutPrimitive.ARGS); | |||
primitives.add(PointcutPrimitive.CALL); | |||
@@ -195,12 +194,11 @@ public class PointcutParser { | |||
* @param supportedPointcutKinds a set of PointcutPrimitives this parser should support | |||
* @throws UnsupportedOperationException if the set contains if, cflow, or cflow below | |||
*/ | |||
private PointcutParser(Set/* <PointcutPrimitives> */supportedPointcutKinds) { | |||
private PointcutParser(Set<PointcutPrimitive> supportedPointcutKinds) { | |||
supportedPrimitives = supportedPointcutKinds; | |||
for (Iterator iter = supportedPointcutKinds.iterator(); iter.hasNext();) { | |||
PointcutPrimitive element = (PointcutPrimitive) iter.next(); | |||
if ((element == PointcutPrimitive.IF) || (element == PointcutPrimitive.CFLOW) | |||
|| (element == PointcutPrimitive.CFLOW_BELOW)) { | |||
for (PointcutPrimitive pointcutPrimitive : supportedPointcutKinds) { | |||
if ((pointcutPrimitive == PointcutPrimitive.IF) || (pointcutPrimitive == PointcutPrimitive.CFLOW) | |||
|| (pointcutPrimitive == PointcutPrimitive.CFLOW_BELOW)) { | |||
throw new UnsupportedOperationException("Cannot handle if, cflow, and cflowbelow primitives"); | |||
} | |||
} | |||
@@ -251,8 +249,9 @@ public class PointcutParser { | |||
*/ | |||
public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) { | |||
this.pointcutDesignators.add(designatorHandler); | |||
if (world != null) | |||
if (world != null) { | |||
world.registerPointcutHandler(designatorHandler); | |||
} | |||
} | |||
/** | |||
@@ -368,8 +367,9 @@ public class PointcutParser { | |||
} | |||
private IScope buildResolutionScope(Class inScope, PointcutParameter[] formalParameters) { | |||
if (formalParameters == null) | |||
if (formalParameters == null) { | |||
formalParameters = new PointcutParameter[0]; | |||
} | |||
FormalBinding[] formalBindings = new FormalBinding[formalParameters.length]; | |||
for (int i = 0; i < formalBindings.length; i++) { | |||
formalBindings[i] = new FormalBinding(toUnresolvedType(formalParameters[i].getType()), formalParameters[i].getName(), i); | |||
@@ -413,8 +413,9 @@ public class PointcutParser { | |||
validateAgainstSupportedPrimitives(((AndPointcut) pc).getRight(), expression); | |||
break; | |||
case Pointcut.ARGS: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ARGS)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ARGS)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ARGS); | |||
} | |||
break; | |||
case Pointcut.CFLOW: | |||
CflowPointcut cfp = (CflowPointcut) pc; | |||
@@ -424,8 +425,9 @@ public class PointcutParser { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW); | |||
} | |||
case Pointcut.HANDLER: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.HANDLER)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.HANDLER)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.HANDLER); | |||
} | |||
break; | |||
case Pointcut.IF: | |||
case Pointcut.IF_FALSE: | |||
@@ -450,12 +452,14 @@ public class PointcutParser { | |||
} | |||
break; | |||
case Pointcut.WITHIN: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN); | |||
} | |||
break; | |||
case Pointcut.WITHINCODE: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN_CODE)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN_CODE)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN_CODE); | |||
} | |||
break; | |||
case Pointcut.ATTHIS_OR_TARGET: | |||
isThis = ((ThisOrTargetAnnotationPointcut) pc).isThis(); | |||
@@ -466,24 +470,29 @@ public class PointcutParser { | |||
} | |||
break; | |||
case Pointcut.ATARGS: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ARGS)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ARGS)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ARGS); | |||
} | |||
break; | |||
case Pointcut.ANNOTATION: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ANNOTATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ANNOTATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ANNOTATION); | |||
} | |||
break; | |||
case Pointcut.ATWITHIN: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHIN)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHIN)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHIN); | |||
} | |||
break; | |||
case Pointcut.ATWITHINCODE: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHINCODE)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHINCODE)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHINCODE); | |||
} | |||
break; | |||
case Pointcut.REFERENCE: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.REFERENCE); | |||
} | |||
break; | |||
case Pointcut.USER_EXTENSION: | |||
// always ok... | |||
@@ -497,29 +506,37 @@ public class PointcutParser { | |||
private void validateKindedPointcut(KindedPointcut pc, String expression) { | |||
Shadow.Kind kind = pc.getKind(); | |||
if ((kind == Shadow.MethodCall) || (kind == Shadow.ConstructorCall)) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.CALL)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.CALL)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CALL); | |||
} | |||
} else if ((kind == Shadow.MethodExecution) || (kind == Shadow.ConstructorExecution)) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.EXECUTION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.EXECUTION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.EXECUTION); | |||
} | |||
} else if (kind == Shadow.AdviceExecution) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ADVICE_EXECUTION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ADVICE_EXECUTION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ADVICE_EXECUTION); | |||
} | |||
} else if (kind == Shadow.FieldGet) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.GET)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.GET)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.GET); | |||
} | |||
} else if (kind == Shadow.FieldSet) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.SET)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.SET)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.SET); | |||
} | |||
} else if (kind == Shadow.Initialization) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.INITIALIZATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.INITIALIZATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.INITIALIZATION); | |||
} | |||
} else if (kind == Shadow.PreInitialization) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.PRE_INITIALIZATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.PRE_INITIALIZATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.PRE_INITIALIZATION); | |||
} | |||
} else if (kind == Shadow.StaticInitialization) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.STATIC_INITIALIZATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.STATIC_INITIALIZATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.STATIC_INITIALIZATION); | |||
} | |||
} | |||
} | |||
@@ -52,15 +52,15 @@ import org.aspectj.weaver.reflect.ReflectionWorld; | |||
public class StandardPointcutParser { | |||
private World world; | |||
private final Set supportedPrimitives; | |||
private final Set pointcutDesignators = new HashSet(); | |||
private final Set<PointcutPrimitive> supportedPrimitives; | |||
private final Set<PointcutDesignatorHandler> pointcutDesignators = new HashSet<PointcutDesignatorHandler>(); | |||
/** | |||
* @return a Set containing every PointcutPrimitive except if, cflow, and cflowbelow (useful for passing to PointcutParser | |||
* constructor). | |||
*/ | |||
public static Set getAllSupportedPointcutPrimitives() { | |||
Set primitives = new HashSet(); | |||
public static Set<PointcutPrimitive> getAllSupportedPointcutPrimitives() { | |||
Set<PointcutPrimitive> primitives = new HashSet<PointcutPrimitive>(); | |||
primitives.add(PointcutPrimitive.ADVICE_EXECUTION); | |||
primitives.add(PointcutPrimitive.ARGS); | |||
primitives.add(PointcutPrimitive.CALL); | |||
@@ -189,8 +189,9 @@ public class StandardPointcutParser { | |||
*/ | |||
public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) { | |||
this.pointcutDesignators.add(designatorHandler); | |||
if (world != null) | |||
if (world != null) { | |||
world.registerPointcutHandler(designatorHandler); | |||
} | |||
} | |||
/** | |||
@@ -243,7 +244,7 @@ public class StandardPointcutParser { | |||
return pcExpr; | |||
} | |||
protected Pointcut resolvePointcutExpression(String expression, Class inScope, PointcutParameter[] formalParameters) { | |||
protected Pointcut resolvePointcutExpression(String expression, Class<?> inScope, PointcutParameter[] formalParameters) { | |||
try { | |||
PatternParser parser = new PatternParser(expression); | |||
parser.setPointcutDesignatorHandlers(pointcutDesignators, world); | |||
@@ -257,7 +258,7 @@ public class StandardPointcutParser { | |||
} | |||
} | |||
protected Pointcut concretizePointcutExpression(Pointcut pc, Class inScope, PointcutParameter[] formalParameters) { | |||
protected Pointcut concretizePointcutExpression(Pointcut pc, Class<?> inScope, PointcutParameter[] formalParameters) { | |||
ResolvedType declaringTypeForResolution = null; | |||
if (inScope != null) { | |||
declaringTypeForResolution = getWorld().resolve(inScope.getName()); | |||
@@ -307,8 +308,9 @@ public class StandardPointcutParser { | |||
} | |||
private IScope buildResolutionScope(Class inScope, PointcutParameter[] formalParameters) { | |||
if (formalParameters == null) | |||
if (formalParameters == null) { | |||
formalParameters = new PointcutParameter[0]; | |||
} | |||
FormalBinding[] formalBindings = new FormalBinding[formalParameters.length]; | |||
for (int i = 0; i < formalBindings.length; i++) { | |||
formalBindings[i] = new FormalBinding(toUnresolvedType(formalParameters[i].getType()), formalParameters[i].getName(), i); | |||
@@ -356,8 +358,9 @@ public class StandardPointcutParser { | |||
validateAgainstSupportedPrimitives(((AndPointcut) pc).getRight(), expression); | |||
break; | |||
case Pointcut.ARGS: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ARGS)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ARGS)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ARGS); | |||
} | |||
break; | |||
case Pointcut.CFLOW: | |||
CflowPointcut cfp = (CflowPointcut) pc; | |||
@@ -367,8 +370,9 @@ public class StandardPointcutParser { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW); | |||
} | |||
case Pointcut.HANDLER: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.HANDLER)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.HANDLER)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.HANDLER); | |||
} | |||
break; | |||
case Pointcut.IF: | |||
case Pointcut.IF_FALSE: | |||
@@ -393,12 +397,14 @@ public class StandardPointcutParser { | |||
} | |||
break; | |||
case Pointcut.WITHIN: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN); | |||
} | |||
break; | |||
case Pointcut.WITHINCODE: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN_CODE)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN_CODE)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN_CODE); | |||
} | |||
break; | |||
case Pointcut.ATTHIS_OR_TARGET: | |||
isThis = ((ThisOrTargetAnnotationPointcut) pc).isThis(); | |||
@@ -409,24 +415,29 @@ public class StandardPointcutParser { | |||
} | |||
break; | |||
case Pointcut.ATARGS: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ARGS)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ARGS)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ARGS); | |||
} | |||
break; | |||
case Pointcut.ANNOTATION: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ANNOTATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_ANNOTATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ANNOTATION); | |||
} | |||
break; | |||
case Pointcut.ATWITHIN: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHIN)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHIN)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHIN); | |||
} | |||
break; | |||
case Pointcut.ATWITHINCODE: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHINCODE)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHINCODE)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHINCODE); | |||
} | |||
break; | |||
case Pointcut.REFERENCE: | |||
if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.REFERENCE); | |||
} | |||
break; | |||
case Pointcut.USER_EXTENSION: | |||
// always ok... | |||
@@ -440,29 +451,37 @@ public class StandardPointcutParser { | |||
private void validateKindedPointcut(KindedPointcut pc, String expression) { | |||
Shadow.Kind kind = pc.getKind(); | |||
if ((kind == Shadow.MethodCall) || (kind == Shadow.ConstructorCall)) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.CALL)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.CALL)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CALL); | |||
} | |||
} else if ((kind == Shadow.MethodExecution) || (kind == Shadow.ConstructorExecution)) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.EXECUTION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.EXECUTION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.EXECUTION); | |||
} | |||
} else if (kind == Shadow.AdviceExecution) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ADVICE_EXECUTION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.ADVICE_EXECUTION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ADVICE_EXECUTION); | |||
} | |||
} else if (kind == Shadow.FieldGet) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.GET)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.GET)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.GET); | |||
} | |||
} else if (kind == Shadow.FieldSet) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.SET)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.SET)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.SET); | |||
} | |||
} else if (kind == Shadow.Initialization) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.INITIALIZATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.INITIALIZATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.INITIALIZATION); | |||
} | |||
} else if (kind == Shadow.PreInitialization) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.PRE_INITIALIZATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.PRE_INITIALIZATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.PRE_INITIALIZATION); | |||
} | |||
} else if (kind == Shadow.StaticInitialization) { | |||
if (!supportedPrimitives.contains(PointcutPrimitive.STATIC_INITIALIZATION)) | |||
if (!supportedPrimitives.contains(PointcutPrimitive.STATIC_INITIALIZATION)) { | |||
throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.STATIC_INITIALIZATION); | |||
} | |||
} | |||
} | |||