Selaa lähdekoodia

44365: is() support in type patterns

tags/V1_6_9M1
aclement 14 vuotta sitten
vanhempi
commit
e60f463f95

+ 4
- 0
org.aspectj.matcher/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java Näytä tiedosto

@@ -464,4 +464,8 @@ public abstract class AbstractPatternNodeVisitor implements PatternNodeVisitor {
public Object visit(HasMemberTypePattern node, Object data) {
return node;
}

public Object visit(TypeCategoryTypePattern node, Object data) {
return node;
}
}

+ 1
- 0
org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java Näytä tiedosto

@@ -44,6 +44,7 @@ public interface PatternNodeVisitor {
Object visit(WildTypePattern node, Object data);
Object visit(TypePatternList node, Object data);
Object visit(HasMemberTypePattern node, Object data);
Object visit(TypeCategoryTypePattern node, Object data);

// Pointcuts
Object visit(AndPointcut node, Object data);

+ 105
- 0
org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java Näytä tiedosto

@@ -868,6 +868,42 @@ public class PatternParser {
}
}

// // Check for a type category
// IToken token = tokenSource.peek();
// if (token.isIdentifier()) {
// String category = token.getString();
// TypeCategoryTypePattern typeIsPattern = null;
// if (category.equals("isClass")) {
// typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.CLASS);
// } else if (category.equals("isAspect")) {
// typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ASPECT);
// } else if (category.equals("isInterface")) {
// typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.INTERFACE);
// } else if (category.equals("isInner")) {
// typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.INNER);
// } else if (category.equals("isAnonymous")) {
// typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ANONYMOUS);
// } else if (category.equals("isEnum")) {
// typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ENUM);
// } else if (category.equals("isAnnotation")) {
// typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ANNOTATION);
// }
// if (typeIsPattern != null) {
// tokenSource.next();
// typeIsPattern.setLocation(tokenSource.getSourceContext(), token.getStart(), token.getEnd());
// return typeIsPattern;
// }
// }
if (maybeEatIdentifier("is")) {
int pos = tokenSource.getIndex() - 1;
TypePattern typeIsPattern = parseIsTypePattern();
if (typeIsPattern != null) {
return typeIsPattern;
}
// rewind as if we never tried to parse it as a typeIs
tokenSource.setIndex(pos);
}

List<NamePattern> names = parseDottedNamePattern();

int dim = 0;
@@ -914,6 +950,75 @@ public class PatternParser {
return ret;
}

/**
* Attempt to parse a typeIs(<category>) construct. If it cannot be parsed we just return null and that should cause the caller
* to reset their position and attempt to consume it in another way. This means we won't have problems here: execution(*
* typeIs(..)) because someone has decided to call a method the same as our construct.
*
* @return a TypeIsTypePattern or null if could not be parsed
*/
public TypePattern parseIsTypePattern() {
int startPos = tokenSource.peek(-1).getStart(); // that will be the start of the 'typeIs'
if (!maybeEatAdjacent("(")) {
return null;
}
IToken token = tokenSource.next();
TypeCategoryTypePattern typeIsPattern = null;
if (token.isIdentifier()) {
String category = token.getString();
if (category.equals("ClassType")) {
typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.CLASS);
} else if (category.equals("AspectType")) {
typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ASPECT);
} else if (category.equals("InterfaceType")) {
typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.INTERFACE);
} else if (category.equals("InnerType")) {
typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.INNER);
} else if (category.equals("AnonymousType")) {
typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ANONYMOUS);
} else if (category.equals("EnumType")) {
typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ENUM);
} else if (category.equals("AnnotationType")) {
typeIsPattern = new TypeCategoryTypePattern(TypeCategoryTypePattern.ANNOTATION);
}
}
if (typeIsPattern == null) {
throw new ParserException("ClassType/AspectType/InterfaceType/InnerType/EnumType/AnnotationType/AnonymousType", token);
}
if (!maybeEat(")")) {
throw new ParserException(")", tokenSource.peek());
}
int endPos = tokenSource.peek(-1).getEnd();
typeIsPattern.setLocation(tokenSource.getSourceContext(), startPos, endPos);
return typeIsPattern;
}

// if (names.size() == 1 && !names.get(0).isAny()) {
// if (maybeEatAdjacent("(")) {
// if (maybeEat(")")) {
// // likely to be one of isClass()/isInterface()/isInner()/isAnonymous()/isAspect()
// if (names.size() == 1) {
// NamePattern np = names.get(0);
// String simpleName = np.maybeGetSimpleName();
// if (simpleName != null) {

// return new TypeCategoryTypePattern(TypeCategoryTypePattern.ANNOTATION, np);
// } else {
// throw new ParserException(
// "not a supported type category, supported are isClass/isInterface/isEnum/isAnnotation/isInner/isAnonymous",
// tokenSource.peek(-3));
// }
// }
// int stop = 1;
// // return new WildTypePattern(names, includeSubtypes, dim + (isVarArgs ? 1 : 0), endPos, isVarArgs,
// // typeParameters);
// }
// } else {
// throw new ParserException("category type pattern is missing closing parentheses", tokenSource.peek(-2));
// }
// }
// }

public TypePattern parseHasFieldTypePattern() {
int startPos = tokenSource.peek(-1).getStart();
eat("(");

+ 129
- 0
org.aspectj.matcher/src/org/aspectj/weaver/patterns/TypeCategoryTypePattern.java Näytä tiedosto

@@ -0,0 +1,129 @@
/* *******************************************************************
* 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
* ******************************************************************/

package org.aspectj.weaver.patterns;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Map;

import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.World;

/**
* A TypeCategoryTypePattern matches on the category of a type, one of class/interface/aspect/inner/anonymous/enum/annotation, and
* these are specified in the pointcut via isClass() isInterface() isAspect() isInner() isAnonymous() isEnum() isAnnotation().
*
* @author Andy Clement
* @since 1.6.9
*/
public class TypeCategoryTypePattern extends TypePattern {

public static final int CLASS = 1;
public static final int INTERFACE = 2;
public static final int ASPECT = 3;
public static final int INNER = 4;
public static final int ANONYMOUS = 5;
public static final int ENUM = 6;
public static final int ANNOTATION = 7;

private int category;

private int VERSION = 1;

public TypeCategoryTypePattern(int category) {
super(false);
this.category = category;
}

@Override
protected boolean matchesExactly(ResolvedType type) {
return isRightCategory(type);
}

@Override
protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
return isRightCategory(type);
}

@Override
public FuzzyBoolean matchesInstanceof(ResolvedType type) {
return FuzzyBoolean.fromBoolean(isRightCategory(type));
}

@Override
public TypePattern parameterizeWith(Map typeVariableMap, World w) {
return this;
}

@Override
public Object accept(PatternNodeVisitor visitor, Object data) {
return visitor.visit(this, data);
}

@Override
public boolean equals(Object other) {
if (!(other instanceof TypeCategoryTypePattern)) {
return false;
}
TypeCategoryTypePattern o = (TypeCategoryTypePattern) other;
return o.category == category;
}

// TODO is sourcelocation part of the identity or just a 'nice to have' - if important it should be in hashcode/equals
// TODO but if that is the case it needs addressing for all type patterns

@Override
public int hashCode() {
return category * 37;
}

@Override
public void write(DataOutputStream s) throws IOException {
s.writeByte(TypePattern.TYPE_CATEGORY);
s.writeInt(VERSION);
s.writeInt(category);
writeLocation(s);
}

public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
int version = s.readInt();
int category = s.readInt();
TypeCategoryTypePattern tp = new TypeCategoryTypePattern(category);
tp.readLocation(context, s);
return tp;
}

/**
* @return true if the supplied type is of the category specified for this type pattern
*/
private boolean isRightCategory(ResolvedType type) {
switch (category) {
case CLASS:
return type.isClass();
case INTERFACE:
return type.isInterface();
case ASPECT:
return type.isAspect();
case ANONYMOUS:
return type.isAnonymous();
case INNER:
return type.isNested();
case ENUM:
return type.isEnum();
case ANNOTATION:
return type.isAnnotation();
}
return false;
}

}

+ 8
- 5
org.aspectj.matcher/src/org/aspectj/weaver/patterns/TypePattern.java Näytä tiedosto

@@ -300,6 +300,7 @@ public abstract class TypePattern extends PatternNode {
public static final byte NO_KEY = 9;
public static final byte ANY_WITH_ANNO = 10;
public static final byte HAS_MEMBER = 11;
public static final byte TYPE_CATEGORY = 12;

public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
byte key = s.readByte();
@@ -326,6 +327,8 @@ public abstract class TypePattern extends PatternNode {
return AnyWithAnnotationTypePattern.read(s, context);
case HAS_MEMBER:
return HasMemberTypePattern.read(s, context);
case TYPE_CATEGORY:
return TypeCategoryTypePattern.read(s, context);
}
throw new BCException("unknown TypePattern kind: " + key);
}
@@ -335,15 +338,15 @@ public abstract class TypePattern extends PatternNode {
}

/**
* For quickly recognizing the pattern '!void'
*/
* For quickly recognizing the pattern '!void'
*/
public boolean isBangVoid() {
return false;
}

/**
* for quickly recognizing the pattern 'void'
*/
/**
* for quickly recognizing the pattern 'void'
*/
public boolean isVoid() {
return false;
}

+ 5
- 0
org.aspectj.matcher/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java Näytä tiedosto

@@ -512,6 +512,11 @@ public class DumpPointcutVisitor implements PatternNodeVisitor {
return null;
}

public Object visit(TypeCategoryTypePattern node, Object data) {
append(node);
return null;
}

public static void check(String s) {
check(Pointcut.fromString(s), false);
}

Loading…
Peruuta
Tallenna