]> source.dussan.org Git - aspectj.git/commitdiff
307120
authoraclement <aclement>
Thu, 8 Apr 2010 21:16:10 +0000 (21:16 +0000)
committeraclement <aclement>
Thu, 8 Apr 2010 21:16:10 +0000 (21:16 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseResolvedMember.java

index 82d243f038ac9d1057bbf6076105887300bcddd2..b5031766cef1601f12af3119dd69b7f8fc1d9720 100644 (file)
@@ -34,10 +34,13 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.aspectj.weaver.AnnotationAJ;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.MemberKind;
+import org.aspectj.weaver.ReferenceType;
+import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedMemberImpl;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.bcel.BcelObjectType;
 
 /**
  * In the pipeline world, we can be weaving before all types have come through from compilation. In some cases this means the weaver
@@ -83,37 +86,74 @@ public class EclipseResolvedMember extends ResolvedMemberImpl {
        }
 
        public AnnotationAJ[] getAnnotations() {
-               // long abits =
-               realBinding.getAnnotationTagBits(); // ensure resolved
-               Annotation[] annos = getEclipseAnnotations();
-               if (annos == null) {
+               if (isTypeDeclarationAvailable()) {
+                       // long abits =
+                       realBinding.getAnnotationTagBits(); // ensure resolved
+                       Annotation[] annos = getEclipseAnnotations();
+                       if (annos == null) {
+                               return null;
+                       }
+                       AnnotationAJ[] annoAJs = new AnnotationAJ[annos.length];
+                       for (int i = 0; i < annos.length; i++) {
+                               annoAJs[i] = EclipseAnnotationConvertor.convertEclipseAnnotation(annos[i], w, eclipseFactory);
+                       }
+                       return annoAJs;
+               } else {
+                       UnresolvedType declaringType = this.getDeclaringType();
+                       if (declaringType instanceof ReferenceType) {
+                               ReferenceType referenceDeclaringType = (ReferenceType)declaringType;
+                               if (referenceDeclaringType.getDelegate() instanceof BcelObjectType) {
+                                       // worth a look!
+                                       ResolvedMember field = ((ResolvedType)declaringType).lookupField(this);
+                                       if (field!=null) {
+                                               return field.getAnnotations();                                          
+                                       }
+                               }
+                       }
                        return null;
                }
-               AnnotationAJ[] annoAJs = new AnnotationAJ[annos.length];
-               for (int i = 0; i < annos.length; i++) {
-                       annoAJs[i] = EclipseAnnotationConvertor.convertEclipseAnnotation(annos[i], w, eclipseFactory);
-               }
-               return annoAJs;
        }
 
        public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
-               // long abits =
-               realBinding.getAnnotationTagBits(); // ensure resolved
-               Annotation[] annos = getEclipseAnnotations();
-               if (annos == null)
-                       return null;
-               for (int i = 0; i < annos.length; i++) {
-                       Annotation anno = annos[i];
-                       UnresolvedType ut = UnresolvedType.forSignature(new String(anno.resolvedType.signature()));
-                       if (w.resolve(ut).equals(ofType)) {
-                               // Found the one
-                               return EclipseAnnotationConvertor.convertEclipseAnnotation(anno, w, eclipseFactory);
+               if (isTypeDeclarationAvailable()) {
+                       // long abits =
+                       realBinding.getAnnotationTagBits(); // ensure resolved
+                       Annotation[] annos = getEclipseAnnotations();
+                       if (annos == null)
+                               return null;
+                       for (int i = 0; i < annos.length; i++) {
+                               Annotation anno = annos[i];
+                               UnresolvedType ut = UnresolvedType.forSignature(new String(anno.resolvedType.signature()));
+                               if (w.resolve(ut).equals(ofType)) {
+                                       // Found the one
+                                       return EclipseAnnotationConvertor.convertEclipseAnnotation(anno, w, eclipseFactory);
+                               }
+                       }
+               } else {                
+                       UnresolvedType declaringType = this.getDeclaringType();
+                       if (declaringType instanceof ReferenceType) {
+                               ReferenceType referenceDeclaringType = (ReferenceType)declaringType;
+                               if (referenceDeclaringType.getDelegate() instanceof BcelObjectType) {
+                                       // worth a look!
+                                       ResolvedMember field = ((ResolvedType)declaringType).lookupField(this);
+                                       if (field!=null) {
+                                               return field.getAnnotationOfType(ofType);                                               
+                                       }
+                               }
                        }
                }
                return null;
        }
 
        public String getAnnotationDefaultValue() {
+               // Andy, if you are debugging in here and your problem is some kind of incremental build failure where a match on
+               // a member annotation value is failing then you should look at bug 307120.  Under that bug you discovered that
+               // for privileged field accesses from ITDs, an EclipseResolvedMember may be created (inside the privileged munger - see
+               // PrivilegedHandler) and then later when the annotations are looked up on it, that fails because we can't find the
+               // declaration for the member.  This is because on the incremental build the member will likely represent something
+               // inside a binary type (BinaryTypeBinding) - and when that happens we should not look on the type declaration but
+               // instead on the delegate for the declaringClass because it will likely be a BcelObjectType with the right stuff
+               // in it - see the other checks on BcelObjectType in this class.
                if (realBinding instanceof MethodBinding) {
                        AbstractMethodDeclaration methodDecl = getTypeDeclaration().declarationOf((MethodBinding) realBinding);
                        if (methodDecl instanceof AnnotationMethodDeclaration) {
@@ -153,24 +193,40 @@ public class EclipseResolvedMember extends ResolvedMemberImpl {
                if (cachedAnnotationTypes == null) {
                        // long abits =
                        realBinding.getAnnotationTagBits(); // ensure resolved
-                       Annotation[] annos = getEclipseAnnotations();
-                       if (annos == null) {
-                               cachedAnnotationTypes = ResolvedType.EMPTY_RESOLVED_TYPE_ARRAY;
+                       if (isTypeDeclarationAvailable()) {
+                               Annotation[] annos = getEclipseAnnotations();
+                               if (annos == null) {
+                                       cachedAnnotationTypes = ResolvedType.EMPTY_RESOLVED_TYPE_ARRAY;
+                               } else {
+                                       cachedAnnotationTypes = new ResolvedType[annos.length];
+                                       for (int i = 0; i < annos.length; i++) {
+                                               Annotation type = annos[i];
+                                               TypeBinding typebinding = type.resolvedType;
+                                               // If there was a problem resolving the annotation (the import couldn't be found) then that can manifest
+                                               // here as typebinding == null. Normally errors are reported prior to weaving (so weaving is avoided and
+                                               // the null is not encountered) but the use of hasfield/hasmethod can cause early attempts to look at
+                                               // annotations and if we NPE here then the real error will not get reported.
+                                               if (typebinding == null) {
+                                                       // Give up now - expect proper error to be reported
+                                                       cachedAnnotationTypes = ResolvedType.EMPTY_RESOLVED_TYPE_ARRAY;
+                                                       return cachedAnnotationTypes;
+                                               }
+                                               cachedAnnotationTypes[i] = w.resolve(UnresolvedType.forSignature(new String(typebinding.signature())));
+                                       }
+                               }
                        } else {
-                               cachedAnnotationTypes = new ResolvedType[annos.length];
-                               for (int i = 0; i < annos.length; i++) {
-                                       Annotation type = annos[i];
-                                       TypeBinding typebinding = type.resolvedType;
-                                       // If there was a problem resolving the annotation (the import couldn't be found) then that can manifest
-                                       // here as typebinding == null. Normally errors are reported prior to weaving (so weaving is avoided and
-                                       // the null is not encountered) but the use of hasfield/hasmethod can cause early attempts to look at
-                                       // annotations and if we NPE here then the real error will not get reported.
-                                       if (typebinding == null) {
-                                               // Give up now - expect proper error to be reported
-                                               cachedAnnotationTypes = ResolvedType.EMPTY_RESOLVED_TYPE_ARRAY;
-                                               return cachedAnnotationTypes;
+                               // annotations may be accessible through the declaringClass if there is a bcel object behind it...
+                               cachedAnnotationTypes = ResolvedType.EMPTY_RESOLVED_TYPE_ARRAY;
+                               UnresolvedType declaringType = this.getDeclaringType();
+                               if (declaringType instanceof ReferenceType) {
+                                       ReferenceType referenceDeclaringType = (ReferenceType)declaringType;
+                                       if (referenceDeclaringType.getDelegate() instanceof BcelObjectType) {
+                                               // worth a look!
+                                               ResolvedMember field = ((ResolvedType)declaringType).lookupField(this);
+                                               if (field!=null) {
+                                                       cachedAnnotationTypes = field.getAnnotationTypes();                                             
+                                               }
                                        }
-                                       cachedAnnotationTypes[i] = w.resolve(UnresolvedType.forSignature(new String(typebinding.signature())));
                                }
                        }
                }
@@ -208,9 +264,18 @@ public class EclipseResolvedMember extends ResolvedMemberImpl {
                return argumentNames;
        }
 
+       /**
+        * Discover the (eclipse form) annotations on this resolved member.  This is done by going to the type declaration,
+        * looking up the member (field/method) then grabbing the annotations.
+        * 
+        * @return an array of (eclipse form) annotations on this member
+        */
        private Annotation[] getEclipseAnnotations() {
                TypeDeclaration tDecl = getTypeDeclaration();
-               if (tDecl != null) {// if the code is broken then tDecl may be null
+               // two possible reasons for it being null:
+               // 1. code is broken
+               // 2. this resolvedmember is an EclipseResolvedMember created up front to represent a privileged'd accessed member
+               if (tDecl != null) {
                        if (realBinding instanceof MethodBinding) {
                                MethodBinding methodBinding = (MethodBinding) realBinding;
                                AbstractMethodDeclaration methodDecl = tDecl.declarationOf(methodBinding);
@@ -243,7 +308,15 @@ public class EclipseResolvedMember extends ResolvedMemberImpl {
                }
                return null;
        }
+       
+       private boolean isTypeDeclarationAvailable() {
+               return getTypeDeclaration()!=null;
+       }
 
+       /**
+        * @return the type declaration that contained this member, or NULL if it is not available (eg. this isn't currently related to
+        * a SOURCE-FORM artifact, it is instead related to a BINARY-FORM artifact)
+        */
        private TypeDeclaration getTypeDeclaration() {
                if (realBinding instanceof MethodBinding) {
                        MethodBinding mb = (MethodBinding) realBinding;