aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraclement <aclement>2009-11-30 21:04:12 +0000
committeraclement <aclement>2009-11-30 21:04:12 +0000
commit037bb06b37960d5facbd0e701d48af5b5a22133c (patch)
treedaa716d05036712384c3d8ce219391b6ce95cd0d
parent6abc8f8488c57bf668ff826b678926a3f8c100d7 (diff)
downloadaspectj-037bb06b37960d5facbd0e701d48af5b5a22133c.tar.gz
aspectj-037bb06b37960d5facbd0e701d48af5b5a22133c.zip
296484:296501: annotationbinding
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java16
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java16
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java2
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationFieldTypePattern.java356
4 files changed, 202 insertions, 188 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java b/org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java
index e655101f9..201fd352d 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java
@@ -58,6 +58,8 @@ public class NameMangler {
public static final String INITFAILURECAUSE_FIELD_NAME = PREFIX + "initFailureCause";
+ public static final String ANNOTATION_CACHE_FIELD_NAME = PREFIX + "anno$";
+
public static boolean isSyntheticMethod(String methodName, boolean declaredInAspect) {
if (methodName.startsWith(PREFIX)) {
// it's synthetic unless it is an advice method
@@ -179,8 +181,10 @@ public class NameMangler {
* This field goes on the class the field is declared onto
*/
public static String interFieldClassField(int modifiers, UnresolvedType aspectType, UnresolvedType classType, String name) {
- if (Modifier.isPublic(modifiers))
+ // return name;
+ if (Modifier.isPublic(modifiers)) {
return name;
+ }
// ??? might want to handle case where aspect and class are in same package similar to public
return makeName("interField", makeVisibilityName(modifiers, aspectType), name);
}
@@ -221,8 +225,9 @@ public class NameMangler {
* interface)
*/
public static String interMethod(int modifiers, UnresolvedType aspectType, UnresolvedType classType, String name) {
- if (Modifier.isPublic(modifiers))
+ if (Modifier.isPublic(modifiers)) {
return name;
+ }
// ??? might want to handle case where aspect and class are in same package similar to public
return makeName("interMethodDispatch2", makeVisibilityName(modifiers, aspectType), name);
}
@@ -326,12 +331,13 @@ public class NameMangler {
public static String getExtractableName(Member shadowSignature) {
String name = shadowSignature.getName();
MemberKind kind = shadowSignature.getKind();
- if (kind == Member.CONSTRUCTOR)
+ if (kind == Member.CONSTRUCTOR) {
return "init$";
- else if (kind == Member.STATIC_INITIALIZATION)
+ } else if (kind == Member.STATIC_INITIALIZATION) {
return "clinit$";
- else
+ } else {
return name;
+ }
}
public static String proceedMethodName(String adviceMethodName) {
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
index fa887eb95..1f82713e4 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
@@ -144,22 +144,6 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
public TypeVariable[] getTypeVariables();
- // /**
- // * If this member is defined by a parameterized super-type, return the
- // erasure
- // * of that member.
- // * For example:
- // * interface I<T> { T foo(T aTea); }
- // * class C implements I<String> {
- // * String foo(String aString) { return "something"; }
- // * }
- // * The resolved member for C.foo has signature String foo(String). The
- // * erasure of that member is Object foo(Object) -- use upper bound of type
- // * variable.
- // * A type is a supertype of itself.
- // */
- // public ResolvedMember getErasure();
-
/**
* Returns true if this member matches the other. The matching takes into account name and parameter types only. When comparing
* parameter types, we allow any type variable to match any other type variable regardless of bounds.
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
index 8f793f8d0..963b0a86b 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
@@ -2266,7 +2266,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
ResolvedPointcutDefinition toAdd = (ResolvedPointcutDefinition) i.next();
for (Iterator j = acc.iterator(); j.hasNext();) {
ResolvedPointcutDefinition existing = (ResolvedPointcutDefinition) j.next();
- if (toAdd==null || existing == toAdd) {
+ if (toAdd==null || existing==null || existing == toAdd) {
continue;
}
UnresolvedType pointcutDeclaringTypeUT = existing.getDeclaringType();
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationFieldTypePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationFieldTypePattern.java
index 0263035eb..ea2ec2a70 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationFieldTypePattern.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationFieldTypePattern.java
@@ -36,171 +36,195 @@ import org.aspectj.weaver.World;
*/
public class ExactAnnotationFieldTypePattern extends ExactAnnotationTypePattern {
- UnresolvedType annotationType;
- private ResolvedMember field;
-
- public ExactAnnotationFieldTypePattern(ExactAnnotationTypePattern p, String formalName) {
- super(formalName);
- this.annotationType = p.annotationType;
- this.copyLocationFrom(p);
- }
-
- public ExactAnnotationFieldTypePattern(UnresolvedType annotationType, String formalName) {
- super(formalName);
- this.annotationType = annotationType;
- }
-
- /**
- * resolve one of these funky things. Need to: <br>
- * (a) Check the formal is bound <br>
- * (b) Check the annotation type is valid
- */
- public AnnotationTypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) {
- if (resolved) return this;
- resolved = true;
- FormalBinding formalBinding = scope.lookupFormal(formalName);
- if (formalBinding == null) {
- scope.message(IMessage.ERROR, this, "When using @annotation(<annotationType>(<annotationField>)), <annotationField> must be bound");
- return this;
- }
-
- annotationType = scope.getWorld().resolve(annotationType, true);
-
- // May not be directly found if in a package, so go looking if that is the case:
- if (ResolvedType.isMissing(annotationType)) {
- String cleanname = annotationType.getName();
- UnresolvedType type = null;
- while (ResolvedType.isMissing(type = scope.lookupType(cleanname, this))) {
- int lastDot = cleanname.lastIndexOf('.');
- if (lastDot == -1) break;
- cleanname = cleanname.substring(0, lastDot) + "$" + cleanname.substring(lastDot + 1);
- }
- annotationType = scope.getWorld().resolve(type, true);
- if (ResolvedType.isMissing(annotationType)) {
- // there are likely to be other errors around that have led to us being unable to
- // resolve the annotation type, let's quit now
- return this;
- }
- }
-
- verifyIsAnnotationType((ResolvedType) annotationType, scope);
-
- if (!formalBinding.getType().resolve(scope.getWorld()).isEnum()) {
- scope.message(IMessage.ERROR, this, "The field within the annotation must be an Enum. '" + formalBinding.getType()
- + "' is not an Enum (compiler limitation)");
- }
- bindingPattern = true;
-
- // Check that the formal is bound to a type that is represented by one field in the annotation type
- ReferenceType theAnnotationType = (ReferenceType) annotationType;
- ResolvedMember[] annotationFields = theAnnotationType.getDeclaredMethods();
- field = null;
- for (int i = 0; i < annotationFields.length; i++) {
- ResolvedMember resolvedMember = annotationFields[i];
- if (resolvedMember.getReturnType().equals(formalBinding.getType())) {
- if (field != null) {
- scope.message(IMessage.ERROR, this, "The field type '" + formalBinding.getType() + "' is ambiguous for annotation type '"
- + theAnnotationType.getName() + "'");
- }
- field = resolvedMember;
- }
- }
- if (field == null) {
- scope.message(IMessage.ERROR, this, "No field of type '" + formalBinding.getType() + "' exists on annotation type '"
- + theAnnotationType.getName() + "'");
- }
-
- BindingAnnotationFieldTypePattern binding = new BindingAnnotationFieldTypePattern(formalBinding.getType(), formalBinding.getIndex(),
- theAnnotationType);
- binding.copyLocationFrom(this);
- bindings.register(binding, scope);
- binding.resolveBinding(scope.getWorld());
- return binding;
- }
-
- public void write(DataOutputStream s) throws IOException {
- s.writeByte(AnnotationTypePattern.EXACTFIELD);
- s.writeUTF(formalName);
- annotationType.write(s);
- writeLocation(s);
- }
-
- public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
- ExactAnnotationFieldTypePattern ret;
- String formalName = s.readUTF();
- UnresolvedType annotationType = UnresolvedType.read(s);
- ret = new ExactAnnotationFieldTypePattern(annotationType, formalName);
- ret.readLocation(context, s);
- return ret;
- }
-
- // ---
-
- public Object accept(PatternNodeVisitor visitor, Object data) {
- return visitor.visit(this, data);
- }
-
- public boolean equals(Object obj) {
- if (!(obj instanceof ExactAnnotationFieldTypePattern)) return false;
- ExactAnnotationFieldTypePattern other = (ExactAnnotationFieldTypePattern) obj;
- return
- (other.annotationType.equals(annotationType)) &&
- (other.field.equals(field)) && (other.formalName.equals(this.formalName));
- }
-
- public int hashCode() {
- int hashcode = annotationType.hashCode();
- hashcode = hashcode * 37 + field.hashCode();
- hashcode = hashcode * 37 + formalName.hashCode();
- return hashcode;
- }
-
- // TODO these are currently unimplemented as I believe it resolves to a Binding form *always* and so they don't get
- // called
-
- public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
- throw new BCException("unimplemented");
- }
-
- public UnresolvedType getAnnotationType() {
- throw new BCException("unimplemented");
- }
-
- public Map getAnnotationValues() {
- throw new BCException("unimplemented");
- }
-
- public ResolvedType getResolvedAnnotationType() {
- throw new BCException("unimplemented");
- }
-
-
- public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations) {
- throw new BCException("unimplemented");
- }
-
- public FuzzyBoolean matches(AnnotatedElement annotated) {
- throw new BCException("unimplemented");
- }
-
- public FuzzyBoolean matchesRuntimeType(AnnotatedElement annotated) {
- throw new BCException("unimplemented");
- }
-
- public AnnotationTypePattern parameterizeWith(Map typeVariableMap, World w) {
- throw new BCException("unimplemented");
- }
-
- public void resolve(World world) {
- throw new BCException("unimplemented");
- }
-
- public String toString() {
- if (!resolved && formalName != null) return formalName;
- StringBuffer ret = new StringBuffer();
- ret.append("@").append(annotationType.toString());
- ret.append("(").append(formalName).append(")");
- return ret.toString();
- }
+ UnresolvedType annotationType;
+ private ResolvedMember field;
+
+ public ExactAnnotationFieldTypePattern(ExactAnnotationTypePattern p, String formalName) {
+ super(formalName);
+ this.annotationType = p.annotationType;
+ this.copyLocationFrom(p);
+ }
+
+ public ExactAnnotationFieldTypePattern(UnresolvedType annotationType, String formalName) {
+ super(formalName);
+ this.annotationType = annotationType;
+ }
+
+ /**
+ * resolve one of these funky things. Need to: <br>
+ * (a) Check the formal is bound <br>
+ * (b) Check the annotation type is valid
+ */
+ @Override
+ public AnnotationTypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) {
+ if (resolved) {
+ return this;
+ }
+ resolved = true;
+ FormalBinding formalBinding = scope.lookupFormal(formalName);
+ if (formalBinding == null) {
+ scope.message(IMessage.ERROR, this,
+ "When using @annotation(<annotationType>(<annotationField>)), <annotationField> must be bound");
+ return this;
+ }
+
+ annotationType = scope.getWorld().resolve(annotationType, true);
+
+ // May not be directly found if in a package, so go looking if that is the case:
+ if (ResolvedType.isMissing(annotationType)) {
+ String cleanname = annotationType.getName();
+ UnresolvedType type = null;
+ while (ResolvedType.isMissing(type = scope.lookupType(cleanname, this))) {
+ int lastDot = cleanname.lastIndexOf('.');
+ if (lastDot == -1) {
+ break;
+ }
+ cleanname = cleanname.substring(0, lastDot) + "$" + cleanname.substring(lastDot + 1);
+ }
+ annotationType = scope.getWorld().resolve(type, true);
+ if (ResolvedType.isMissing(annotationType)) {
+ // there are likely to be other errors around that have led to us being unable to
+ // resolve the annotation type, let's quit now
+ return this;
+ }
+ }
+
+ verifyIsAnnotationType((ResolvedType) annotationType, scope);
+
+ ResolvedType formalBindingType = formalBinding.getType().resolve(scope.getWorld());
+
+ if (!(formalBindingType.isEnum() || formalBindingType.getSignature().equals("Ljava/lang/String;"))) {
+ scope.message(IMessage.ERROR, this, "The field within the annotation must be an enum or string. '"
+ + formalBinding.getType() + "' is not (compiler limitation)");
+ }
+ bindingPattern = true;
+
+ // Check that the formal is bound to a type that is represented by one field in the annotation type
+ ReferenceType theAnnotationType = (ReferenceType) annotationType;
+ ResolvedMember[] annotationFields = theAnnotationType.getDeclaredMethods();
+ field = null;
+ for (int i = 0; i < annotationFields.length; i++) {
+ ResolvedMember resolvedMember = annotationFields[i];
+ if (resolvedMember.getReturnType().equals(formalBinding.getType())) {
+ if (field != null) {
+ scope.message(IMessage.ERROR, this, "The field type '" + formalBinding.getType()
+ + "' is ambiguous for annotation type '" + theAnnotationType.getName() + "'");
+ }
+ field = resolvedMember;
+ }
+ }
+ if (field == null) {
+ scope.message(IMessage.ERROR, this, "No field of type '" + formalBinding.getType() + "' exists on annotation type '"
+ + theAnnotationType.getName() + "'");
+ }
+
+ BindingAnnotationFieldTypePattern binding = new BindingAnnotationFieldTypePattern(formalBinding.getType(), formalBinding
+ .getIndex(), theAnnotationType);
+ binding.copyLocationFrom(this);
+ bindings.register(binding, scope);
+ binding.resolveBinding(scope.getWorld());
+ return binding;
+ }
+
+ @Override
+ public void write(DataOutputStream s) throws IOException {
+ s.writeByte(AnnotationTypePattern.EXACTFIELD);
+ s.writeUTF(formalName);
+ annotationType.write(s);
+ writeLocation(s);
+ }
+
+ public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
+ ExactAnnotationFieldTypePattern ret;
+ String formalName = s.readUTF();
+ UnresolvedType annotationType = UnresolvedType.read(s);
+ ret = new ExactAnnotationFieldTypePattern(annotationType, formalName);
+ ret.readLocation(context, s);
+ return ret;
+ }
+
+ // ---
+
+ @Override
+ public Object accept(PatternNodeVisitor visitor, Object data) {
+ return visitor.visit(this, data);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ExactAnnotationFieldTypePattern)) {
+ return false;
+ }
+ ExactAnnotationFieldTypePattern other = (ExactAnnotationFieldTypePattern) obj;
+ return (other.annotationType.equals(annotationType)) && (other.field.equals(field))
+ && (other.formalName.equals(this.formalName));
+ }
+
+ @Override
+ public int hashCode() {
+ int hashcode = annotationType.hashCode();
+ hashcode = hashcode * 37 + field.hashCode();
+ hashcode = hashcode * 37 + formalName.hashCode();
+ return hashcode;
+ }
+
+ // TODO these are currently unimplemented as I believe it resolves to a Binding form *always* and so they don't get
+ // called
+
+ @Override
+ public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public UnresolvedType getAnnotationType() {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public Map getAnnotationValues() {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public ResolvedType getResolvedAnnotationType() {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations) {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public FuzzyBoolean matches(AnnotatedElement annotated) {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public FuzzyBoolean matchesRuntimeType(AnnotatedElement annotated) {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public AnnotationTypePattern parameterizeWith(Map typeVariableMap, World w) {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public void resolve(World world) {
+ throw new BCException("unimplemented");
+ }
+
+ @Override
+ public String toString() {
+ if (!resolved && formalName != null) {
+ return formalName;
+ }
+ StringBuffer ret = new StringBuffer();
+ ret.append("@").append(annotationType.toString());
+ ret.append("(").append(formalName).append(")");
+ return ret.toString();
+ }
}