diff options
author | Andy Clement <aclement@vmware.com> | 2012-02-29 13:58:34 -0800 |
---|---|---|
committer | Andy Clement <aclement@vmware.com> | 2012-02-29 13:58:34 -0800 |
commit | 3ae3c6c6dae22ae29cdd1f126e4eaf68f0f78238 (patch) | |
tree | 62d43c73008e8c0b9172ed109aea0105d0ee5e2d | |
parent | 89756cdfe58319d4e8e29b88de6fd8810d84244d (diff) | |
download | aspectj-conditionalThis.tar.gz aspectj-conditionalThis.zip |
enable this?() syntaxconditionalThis
5 files changed, 80 insertions, 27 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/NameBindingPointcut.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/NameBindingPointcut.java index 511ff6859..c0824aae8 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/NameBindingPointcut.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/NameBindingPointcut.java @@ -25,6 +25,7 @@ import org.aspectj.weaver.ast.Var; * * @author Erik Hilsdale * @author Jim Hugunin + * @author Andy Clement */ public abstract class NameBindingPointcut extends Pointcut { @@ -45,8 +46,7 @@ public abstract class NameBindingPointcut extends Pointcut { return Test.makeInstanceof(var, myType.resolve(world)); } - public abstract List/*<BindingTypePattern>*/ getBindingTypePatterns(); - public abstract List/*<BindingAnnotationTypePattern>*/ getBindingAnnotationTypePatterns(); - + public abstract List<BindingTypePattern> getBindingTypePatterns(); + public abstract List<BindingAnnotationTypePattern> getBindingAnnotationTypePatterns(); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java index 6bcb4ce4a..7c54271ba 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java @@ -562,10 +562,14 @@ public class PatternParser { * @return Pointcut */ private Pointcut parseThisOrTargetPointcut(String kind) { + boolean optional = false; + if (maybeEat("?")) { + optional = true; + } eat("("); TypePattern type = parseTypePattern(); eat(")"); - return new ThisOrTargetPointcut(kind.equals("this"), type); + return new ThisOrTargetPointcut(kind.equals("this"), type,optional); } private Pointcut parseThisOrTargetAnnotationPointcut() { diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/Pointcut.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/Pointcut.java index f927286ec..2cd7719a8 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/Pointcut.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/Pointcut.java @@ -168,6 +168,7 @@ public abstract class Pointcut extends PatternNode { public static final byte ATARGS = 21; public static final byte USER_EXTENSION = 22; + public static final byte THIS_OR_TARGET_WITH_OPTIONAL = 23; public byte getPointcutKind() { return pointcutKind; @@ -282,7 +283,7 @@ public abstract class Pointcut extends PatternNode { ret = WithinPointcut.read(s, context); break; case THIS_OR_TARGET: - ret = ThisOrTargetPointcut.read(s, context); + ret = ThisOrTargetPointcut.read(s, context, false); break; case ARGS: ret = ArgsPointcut.read(s, context); @@ -335,6 +336,9 @@ public abstract class Pointcut extends PatternNode { case NONE: ret = makeMatchesNothing(RESOLVED); break; + case THIS_OR_TARGET_WITH_OPTIONAL: + ret = ThisOrTargetPointcut.read(s,context,true); + break; default: throw new BCException("unknown kind: " + kind); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java index f2e77440b..1594f9a3a 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java @@ -50,6 +50,7 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { private boolean isThis; private TypePattern typePattern; private String declarationText; + private boolean optional = false; private static final int thisKindSet; private static final int targetKindSet; @@ -74,10 +75,11 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { return (typePattern instanceof BindingTypePattern); } - public ThisOrTargetPointcut(boolean isThis, TypePattern type) { + public ThisOrTargetPointcut(boolean isThis, TypePattern type, boolean optional) { this.isThis = isThis; this.typePattern = type; this.pointcutKind = THIS_OR_TARGET; + this.optional = optional; this.declarationText = (isThis ? "this(" : "target(") + type + ")"; } @@ -91,11 +93,12 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { @Override public Pointcut parameterizeWith(Map typeVariableMap, World w) { - ThisOrTargetPointcut ret = new ThisOrTargetPointcut(isThis, typePattern.parameterizeWith(typeVariableMap, w)); + ThisOrTargetPointcut ret = new ThisOrTargetPointcut(isThis, typePattern.parameterizeWith(typeVariableMap, w),optional); ret.copyLocationFrom(this); return ret; } + @Override public int couldMatchKinds() { return isThis ? thisKindSet : targetKindSet; @@ -107,7 +110,7 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { } private boolean couldMatch(Shadow shadow) { - return isThis ? shadow.hasThis() : shadow.hasTarget(); + return optional || (isThis ? shadow.hasThis() : shadow.hasTarget()) ; } @Override @@ -115,27 +118,35 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { if (!couldMatch(shadow)) { return FuzzyBoolean.NO; } - UnresolvedType typeToMatch = isThis ? shadow.getThisType() : shadow.getTargetType(); - // optimization for case of this(Object) or target(Object) - // works for an ExactTypePattern (and we know there are no annotations to match here of course) - if (typePattern.getExactType().equals(ResolvedType.OBJECT)) { + if (isThis?shadow.hasThis():shadow.hasTarget()) { + UnresolvedType typeToMatch = isThis ? shadow.getThisType() : shadow.getTargetType(); + // optimization for case of this(Object) or target(Object) + // works for an ExactTypePattern (and we know there are no annotations to match here of course) + if (typePattern.getExactType().equals(ResolvedType.OBJECT)) { + return FuzzyBoolean.YES; + } + return typePattern.matches(typeToMatch.resolve(shadow.getIWorld()), TypePattern.DYNAMIC); + } else { // assert optional return FuzzyBoolean.YES; } - return typePattern.matches(typeToMatch.resolve(shadow.getIWorld()), TypePattern.DYNAMIC); } @Override public void write(CompressingDataOutputStream s) throws IOException { - s.writeByte(Pointcut.THIS_OR_TARGET); + if (optional) { + s.writeByte(Pointcut.THIS_OR_TARGET_WITH_OPTIONAL); + } else { + s.writeByte(Pointcut.THIS_OR_TARGET); + } s.writeBoolean(isThis); typePattern.write(s); writeLocation(s); } - public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException { + public static Pointcut read(VersionedDataInputStream s, ISourceContext context, boolean optional) throws IOException { boolean isThis = s.readBoolean(); TypePattern type = TypePattern.read(s, context); - ThisOrTargetPointcut ret = new ThisOrTargetPointcut(isThis, type); + ThisOrTargetPointcut ret = new ThisOrTargetPointcut(isThis, type, optional); ret.readLocation(context, s); return ret; } @@ -165,8 +176,8 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { * @see org.aspectj.weaver.patterns.NameBindingPointcut#getBindingAnnotationTypePatterns() */ @Override - public List getBindingAnnotationTypePatterns() { - return Collections.EMPTY_LIST; + public List<BindingAnnotationTypePattern> getBindingAnnotationTypePatterns() { + return Collections.emptyList(); } /* @@ -175,13 +186,13 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { * @see org.aspectj.weaver.patterns.NameBindingPointcut#getBindingTypePatterns() */ @Override - public List getBindingTypePatterns() { + public List<BindingTypePattern> getBindingTypePatterns() { if (typePattern instanceof BindingTypePattern) { - List l = new ArrayList(); - l.add(typePattern); + List<BindingTypePattern> l = new ArrayList<BindingTypePattern>(); + l.add((BindingTypePattern)typePattern); return l; } else { - return Collections.EMPTY_LIST; + return Collections.emptyList(); } } @@ -222,9 +233,36 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { return Literal.TRUE; } - Var var = isThis ? shadow.getThisVar() : shadow.getTargetVar(); + if (isThis?shadow.hasThis():shadow.hasTarget()) { + Var var = isThis ? shadow.getThisVar() : shadow.getTargetVar(); + + return exposeStateForVar(var, typePattern, state, shadow.getIWorld()); + } else { // assert optional + + Var v = new NullVar(typePattern.getExactType().resolve(shadow.getIWorld())); +// return exposeStateForVar(var, typePattern, state, shadow.getIWorld()); + if (typePattern instanceof BindingTypePattern) { + BindingTypePattern b = (BindingTypePattern)typePattern; + state.set(b.getFormalIndex(), v); + } +// ResolvedType myType = typePattern.getExactType().resolve(world); +// if (myType.isParameterizedType()) { +// // unchecked warning already issued... +// myType = (ResolvedType) myType.getRawType(); +// } +// return Test.makeInstanceof(var, myType.resolve(world)); + return Literal.TRUE; +// return exposeStateForVar(null, typePattern, state, shadow.getIWorld()); + } + } + + public static class NullVar extends Var { - return exposeStateForVar(var, typePattern, state, shadow.getIWorld()); + public NullVar(ResolvedType variableType) { + super(variableType); + // TODO Auto-generated constructor stub + } + } @Override @@ -242,7 +280,7 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { inAspect.crosscuttingMembers.exposeType(newType.getExactType()); } - Pointcut ret = new ThisOrTargetPointcut(isThis, newType); + Pointcut ret = new ThisOrTargetPointcut(isThis, newType, optional); ret.copyLocationFrom(this); return ret; } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java index ac30af5f9..e1f126f46 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java @@ -49,10 +49,12 @@ import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.World; import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; +import org.aspectj.weaver.ast.Var; import org.aspectj.weaver.patterns.ExactTypePattern; import org.aspectj.weaver.patterns.ExposedState; import org.aspectj.weaver.patterns.PerClause; import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.ThisOrTargetPointcut.NullVar; /** * Advice implemented for BCEL @@ -538,8 +540,12 @@ class BcelAdvice extends Advice { if (exposedState.isErroneousVar(i)) { continue; // Erroneous vars have already had error msgs reported! } - BcelVar v = (BcelVar) exposedState.get(i); - + + Var var = exposedState.get(i); + if (var instanceof NullVar) { + il.append(InstructionConstants.ACONST_NULL); + } else { + BcelVar v = (BcelVar) var; if (v == null) { // if not @AJ aspect, go on with the regular binding handling if (!isAnnotationStyleAspect) { @@ -605,6 +611,7 @@ class BcelAdvice extends Advice { UnresolvedType desiredTy = getBindingParameterTypes()[i]; v.appendLoadAndConvert(il, fact, desiredTy.resolve(world)); } + } } // ATAJ: for code style aspect, handles the extraFlag as usual ie not |