Browse Source

enable this?() syntax

conditionalThis
Andy Clement 12 years ago
parent
commit
3ae3c6c6da

+ 3
- 3
org.aspectj.matcher/src/org/aspectj/weaver/patterns/NameBindingPointcut.java View File

@@ -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();

}

+ 5
- 1
org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java View File

@@ -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() {

+ 5
- 1
org.aspectj.matcher/src/org/aspectj/weaver/patterns/Pointcut.java View File

@@ -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);
}

+ 58
- 20
org.aspectj.matcher/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java View File

@@ -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;
}

+ 9
- 2
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java View File

@@ -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

Loading…
Cancel
Save