From 7fc015eda24931c4d1c490fc2d1057170bdf85bc Mon Sep 17 00:00:00 2001 From: acolyer Date: Wed, 8 Dec 2004 10:00:01 +0000 Subject: updates to annotation parsing... --- .../src/org/aspectj/weaver/AnnotatedElement.java | 1 + weaver/src/org/aspectj/weaver/Member.java | 7 ++ weaver/src/org/aspectj/weaver/TypeX.java | 7 ++ .../weaver/patterns/AnnotationTypePattern.java | 2 + .../patterns/ExactAnnotationTypePattern.java | 2 +- .../org/aspectj/weaver/patterns/PatternParser.java | 128 +++++++++++++-------- .../weaver/patterns/WildAnnotationTypePattern.java | 95 +++++++++++++++ .../aspectj/weaver/patterns/WildTypePattern.java | 18 ++- .../weaver/patterns/AnnotationPatternTestCase.java | 10 +- 9 files changed, 213 insertions(+), 57 deletions(-) create mode 100644 weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java (limited to 'weaver') diff --git a/weaver/src/org/aspectj/weaver/AnnotatedElement.java b/weaver/src/org/aspectj/weaver/AnnotatedElement.java index e2a6c7de4..f83e551d0 100644 --- a/weaver/src/org/aspectj/weaver/AnnotatedElement.java +++ b/weaver/src/org/aspectj/weaver/AnnotatedElement.java @@ -15,5 +15,6 @@ package org.aspectj.weaver; public interface AnnotatedElement { boolean hasAnnotation(ResolvedTypeX ofType); + ResolvedTypeX[] getAnnotationTypes(); // SomeType getAnnotation(TypeX ofType); } diff --git a/weaver/src/org/aspectj/weaver/Member.java b/weaver/src/org/aspectj/weaver/Member.java index d6b63e275..9bd4fa7d4 100644 --- a/weaver/src/org/aspectj/weaver/Member.java +++ b/weaver/src/org/aspectj/weaver/Member.java @@ -471,6 +471,13 @@ public class Member implements Comparable, AnnotatedElement { 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 diff --git a/weaver/src/org/aspectj/weaver/TypeX.java b/weaver/src/org/aspectj/weaver/TypeX.java index a10561c48..020682322 100644 --- a/weaver/src/org/aspectj/weaver/TypeX.java +++ b/weaver/src/org/aspectj/weaver/TypeX.java @@ -555,6 +555,13 @@ public class TypeX implements AnnotatedElement { 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 diff --git a/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java index 5b2560cbe..ad8eab5c8 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java @@ -55,6 +55,7 @@ public abstract class AnnotationTypePattern extends PatternNode { 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(); @@ -64,6 +65,7 @@ public abstract class AnnotationTypePattern extends PatternNode { 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; } diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java index 0539d6af1..8d7bc8d5a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java @@ -38,7 +38,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { */ public ExactAnnotationTypePattern(TypeX annotationType) { this.annotationType = annotationType; - this.resolved = false; + this.resolved = (annotationType instanceof ResolvedTypeX); } public ExactAnnotationTypePattern(String formalName) { diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java index 08ff3a1df..a91a44b6f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java @@ -23,11 +23,8 @@ import org.aspectj.weaver.TypeX; //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; /** @@ -189,7 +186,7 @@ public class PatternParser { eat(")"); return p; } - if (maybeEat(AT)) { + if (maybeEat("@")) { int startPos = tokenSource.peek().getStart(); Pointcut p = parseAnnotationPointcut(); int endPos = tokenSource.peek(-1).getEnd(); @@ -502,6 +499,7 @@ public class PatternParser { } private TypePattern parseAtomicTypePattern() { + AnnotationTypePattern ap = maybeParseAnnotationPattern(); if (maybeEat("!")) { //int startPos = tokenSource.peek(-1).getStart(); //??? we lose source location for true start of !type @@ -513,33 +511,82 @@ public class PatternParser { 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(); @@ -557,15 +604,15 @@ public class PatternParser { 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); } @@ -604,7 +651,7 @@ public class PatternParser { protected AnnotationTypePattern parseAnnotationNameOrVarTypePattern() { AnnotationTypePattern p = null; int startPos = tokenSource.peek().getStart(); - if (maybeEat(AT)) { + if (maybeEat("@")) { p = parseSimpleAnnotationName(); } else { String formal = parseIdentifier(); @@ -1066,26 +1113,7 @@ public class PatternParser { 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; diff --git a/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java new file mode 100644 index 000000000..f76a4e65f --- /dev/null +++ b/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java @@ -0,0 +1,95 @@ +/* ******************************************************************* + * 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; + } + +} diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java index 09bf402ea..2cef3745c 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java @@ -38,8 +38,8 @@ public class WildTypePattern extends TypePattern { 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; @@ -50,7 +50,7 @@ public class WildTypePattern extends TypePattern { } 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); } @@ -58,7 +58,13 @@ public class WildTypePattern extends TypePattern { 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(); @@ -559,6 +565,7 @@ public class WildTypePattern extends TypePattern { } 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); @@ -579,7 +586,8 @@ public class WildTypePattern extends TypePattern { } 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); diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java index 489d24550..0ddbc34e2 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java @@ -10,8 +10,8 @@ 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; @@ -336,5 +336,13 @@ public class AnnotationPatternTestCase extends TestCase { return false; } + /* (non-Javadoc) + * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes() + */ + public ResolvedTypeX[] getAnnotationTypes() { + // TODO Auto-generated method stub + return null; + } + } } -- cgit v1.2.3