public interface AnnotatedElement {
boolean hasAnnotation(ResolvedTypeX ofType);
+ ResolvedTypeX[] getAnnotationTypes();
// SomeType getAnnotation(TypeX ofType);
}
public boolean hasAnnotation(ResolvedTypeX ofType) {
throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
}
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
+ */
+ public ResolvedTypeX[] getAnnotationTypes() {
+ throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
+ }
// ---- fields 'n' stuff
public boolean hasAnnotation(ResolvedTypeX ofType) {
throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
}
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
+ */
+ public ResolvedTypeX[] getAnnotationTypes() {
+ throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
+ }
// ---- fields
public static final byte AND = 5;
public static final byte ELLIPSIS_KEY = 6;
public static final byte ANY_KEY = 7;
+ public static final byte WILD = 8;
public static AnnotationTypePattern read(DataInputStream s, ISourceContext context) throws IOException {
byte key = s.readByte();
case NOT: return NotAnnotationTypePattern.read(s, context);
case OR: return OrAnnotationTypePattern.read(s, context);
case AND: return AndAnnotationTypePattern.read(s, context);
+ case WILD: return WildAnnotationTypePattern.read(s,context);
case ELLIPSIS_KEY: return ELLIPSIS;
case ANY_KEY: return ANY;
}
*/
public ExactAnnotationTypePattern(TypeX annotationType) {
this.annotationType = annotationType;
- this.resolved = false;
+ this.resolved = (annotationType instanceof ResolvedTypeX);
}
public ExactAnnotationTypePattern(String formalName) {
//XXX doesn't handle errors for extra tokens very well (sometimes ignores)
public class PatternParser {
-
- private static final String AT = "@";
-
- private ITokenSource tokenSource;
-
+
+ private ITokenSource tokenSource;
private ISourceContext sourceContext;
/**
eat(")");
return p;
}
- if (maybeEat(AT)) {
+ if (maybeEat("@")) {
int startPos = tokenSource.peek().getStart();
Pointcut p = parseAnnotationPointcut();
int endPos = tokenSource.peek(-1).getEnd();
}
private TypePattern parseAtomicTypePattern() {
+ AnnotationTypePattern ap = maybeParseAnnotationPattern();
if (maybeEat("!")) {
//int startPos = tokenSource.peek(-1).getStart();
//??? we lose source location for true start of !type
eat(")");
return p;
}
- if (maybeEat("@")) {
- AnnotationTypePattern ap = null;
- if (maybeEat("(")) {
- ap = parseAnnotationTypePattern();
- eat(")");
- } else {
- ap = parseSimpleAnnotationName();
- }
- int startPos = tokenSource.peek().getStart();
- TypePattern p = parseAtomicTypePattern();
- int endPos = tokenSource.peek(-1).getEnd();
- p.setLocation(sourceContext, startPos, endPos);
- if (ap != null) {
- if (p == TypePattern.ANY) {
- p = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0);
- }
- p.setAnnotationTypePattern(ap);
- }
- return p;
- }
+// if (maybeEat("@")) {
+// AnnotationTypePattern ap = null;
+// if (maybeEat("(")) {
+// ap = parseAnnotationTypePattern();
+// eat(")");
+// } else {
+// ap = parseSimpleAnnotationName();
+// }
+// int startPos = tokenSource.peek().getStart();
+// TypePattern p = parseAtomicTypePattern();
+// int endPos = tokenSource.peek(-1).getEnd();
+// p.setLocation(sourceContext, startPos, endPos);
+// if (ap != null) {
+// if (p == TypePattern.ANY) {
+// p = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0);
+// }
+// p.setAnnotationTypePattern(ap);
+// }
+// return p;
+// }
int startPos = tokenSource.peek().getStart();
TypePattern p = parseSingleTypePattern();
int endPos = tokenSource.peek(-1).getEnd();
p.setLocation(sourceContext, startPos, endPos);
return p;
}
+
+ public AnnotationTypePattern maybeParseAnnotationPattern() {
+ AnnotationTypePattern ret = AnnotationTypePattern.ANY;
+ AnnotationTypePattern nextPattern = null;
+ while ((nextPattern = maybeParseSingleAnnotationPattern()) != null) {
+ if (ret == AnnotationTypePattern.ANY) {
+ ret = nextPattern;
+ } else {
+ ret = new AndAnnotationTypePattern(ret,nextPattern);
+ }
+ }
+ return ret;
+ }
+ public AnnotationTypePattern maybeParseSingleAnnotationPattern() {
+ AnnotationTypePattern ret = null;
+ // LALR(2) - fix by making "!@" a single token
+ int startIndex = tokenSource.getIndex();
+ if (maybeEat("!")) {
+ if (maybeEat("@")) {
+ if (maybeEat("(")) {
+ TypePattern p = parseTypePattern();
+ ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));
+ return ret;
+ } else {
+ TypePattern p = parseSingleTypePattern();
+ ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));
+ return ret;
+ }
+ } else {
+ tokenSource.setIndex(startIndex); // not for us!
+ return ret;
+ }
+ }
+ if (maybeEat("@")) {
+ if (maybeEat("(")) {
+ TypePattern p = parseTypePattern();
+ ret = new WildAnnotationTypePattern(p);
+ return ret;
+ } else {
+ TypePattern p = parseSingleTypePattern();
+ ret = new WildAnnotationTypePattern(p);
+ return ret;
+ }
+ } else {
+ tokenSource.setIndex(startIndex); // not for us!
+ return ret;
+ }
+ }
+
public TypePattern parseSingleTypePattern() {
List names = parseDottedNamePattern();
// new ArrayList();
eat("]");
dim++;
}
-
-
+ boolean isVarArgs = maybeEat("...");
+
boolean includeSubtypes = maybeEat("+");
int endPos = tokenSource.peek(-1).getEnd();
//??? what about the source location of any's????
if (names.size() == 1 && ((NamePattern)names.get(0)).isAny() && dim == 0) return TypePattern.ANY;
- return new WildTypePattern(names, includeSubtypes, dim, endPos);
+ return new WildTypePattern(names, includeSubtypes, dim, endPos,isVarArgs);
}
protected AnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
AnnotationTypePattern p = null;
int startPos = tokenSource.peek().getStart();
- if (maybeEat(AT)) {
+ if (maybeEat("@")) {
p = parseSimpleAnnotationName();
} else {
String formal = parseIdentifier();
return null;
}
}
-
- public AnnotationTypePattern maybeParseAnnotationPattern() {
- AnnotationTypePattern ret = null;
- int start = tokenSource.getIndex();
- if (maybeEat("@")) {
- if (maybeEat("(")) {
- ret = parseAnnotationTypePattern();
- eat(")");
- } else {
- ret = parseSimpleAnnotationName();
- }
- }
- if (ret == null) {
- // failed to find one...
- tokenSource.setIndex(start);
- ret = AnnotationTypePattern.ANY;
- }
- return ret;
- }
-
+
public boolean peek(String token) {
IToken next = tokenSource.peek();
return next.getString() == token;
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.AnnotatedElement;
+import org.aspectj.weaver.BCException;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.TypeX;
+
+/**
+ * @author colyer
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+public class WildAnnotationTypePattern extends AnnotationTypePattern {
+
+ private TypePattern typePattern;
+
+ /**
+ *
+ */
+ public WildAnnotationTypePattern(TypePattern typePattern) {
+ super();
+ this.typePattern = typePattern;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.AnnotationTypePattern#matches(org.aspectj.weaver.AnnotatedElement)
+ */
+ public FuzzyBoolean matches(AnnotatedElement annotated) {
+ // matches if the type of any of the annotations on the AnnotatedElement is
+ // matched by the typePattern.
+ ResolvedTypeX[] annTypes = annotated.getAnnotationTypes();
+ for (int i = 0; i < annTypes.length; i++) {
+ if (typePattern.matches(annTypes[i],TypePattern.STATIC).alwaysTrue()) {
+ return FuzzyBoolean.YES;
+ }
+ }
+ return FuzzyBoolean.NO;
+ }
+
+ /**
+ * This can modify in place, or return a new TypePattern if the type changes.
+ */
+ public AnnotationTypePattern resolveBindings(IScope scope, Bindings bindings,
+ boolean allowBinding)
+ {
+ this.typePattern = typePattern.resolveBindings(scope,bindings,false,false);
+ if (typePattern instanceof ExactTypePattern) {
+ ExactTypePattern et = (ExactTypePattern)typePattern;
+ return new ExactAnnotationTypePattern(et.getExactType());
+ } else {
+ return this;
+ }
+ }
+
+ private static final byte VERSION = 1; // rev if ser. form changes
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
+ */
+ public void write(DataOutputStream s) throws IOException {
+ s.writeByte(AnnotationTypePattern.WILD);
+ s.writeByte(VERSION);
+ typePattern.write(s);
+ writeLocation(s);
+ }
+
+ public static AnnotationTypePattern read(DataInputStream s,ISourceContext context) throws IOException {
+ AnnotationTypePattern ret;
+ byte version = s.readByte();
+ if (version > VERSION) {
+ throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
+ }
+ TypePattern t = TypePattern.read(s,context);
+ ret = new WildAnnotationTypePattern(t);
+ ret.readLocation(context,s);
+ return ret;
+ }
+
+}
String[] knownMatches;
int dim;
- WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim) {
- super(includeSubtypes,false);
+ WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs) {
+ super(includeSubtypes,isVarArgs);
this.namePatterns = namePatterns;
this.dim = dim;
ellipsisCount = 0;
}
public WildTypePattern(List names, boolean includeSubtypes, int dim) {
- this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim);
+ this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim,false);
}
this(names, includeSubtypes, dim);
this.end = endPos;
}
-
+
+ public WildTypePattern(List names, boolean includeSubtypes, int dim, int endPos, boolean isVarArg) {
+ this(names, includeSubtypes, dim);
+ this.end = endPos;
+ this.isVarArgs = isVarArg;
+ }
+
//XXX inefficient implementation
public static char[][] splitNames(String s) {
List ret = new ArrayList();
}
s.writeBoolean(includeSubtypes);
s.writeInt(dim);
+ s.writeBoolean(isVarArgs);
//??? storing this information with every type pattern is wasteful of .class
// file size. Storing it on enclosing types would be more efficient
FileUtil.writeStringArray(knownMatches, s);
}
boolean includeSubtypes = s.readBoolean();
int dim = s.readInt();
- WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim);
+ boolean varArg = s.readBoolean();
+ WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim,varArg);
ret.knownMatches = FileUtil.readStringArray(s);
ret.importedPrefixes = FileUtil.readStringArray(s);
ret.readLocation(context, s);
package org.aspectj.weaver.patterns;
import org.aspectj.weaver.AnnotatedElement;
-import org.aspectj.weaver.BcweaverTests;
import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.BcweaverTests;
import org.aspectj.weaver.TypeX;
import org.aspectj.weaver.bcel.BcelWorld;
return false;
}
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
+ */
+ public ResolvedTypeX[] getAnnotationTypes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
}