]> source.dussan.org Git - aspectj.git/commitdiff
296484:296501: annotationbinding
authoraclement <aclement>
Mon, 30 Nov 2009 21:04:12 +0000 (21:04 +0000)
committeraclement <aclement>
Mon, 30 Nov 2009 21:04:12 +0000 (21:04 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/NameMangler.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationFieldTypePattern.java

index e655101f9e5a6926537c32a90754eb728c3ff222..201fd352dfca310163bdd24a1656eb85456a58e0 100644 (file)
@@ -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) {
index fa887eb95a89a3c6815008ecc601a9f5823ea6ab..1f82713e4f07158b9da3f8bab3a6c9e3f3082a75 100644 (file)
@@ -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.
index 8f793f8d03be104981d0635c45433dacefb738ec..963b0a86b1c110a12c9e977e438d71f8c8e512ec 100644 (file)
@@ -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();
index 0263035eb23aa3f5946201578b9cf267d44e54a9..ea2ec2a70e1c51dd212c953e363d4c53042994a7 100644 (file)
@@ -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();
+       }
 
 }