From 40604fc14bc345ce828f1dcb3d8b285540312299 Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 8 Apr 2010 21:16:10 +0000 Subject: [PATCH] 307120 --- .../lookup/EclipseResolvedMember.java | 147 +++++++++++++----- 1 file changed, 110 insertions(+), 37 deletions(-) diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseResolvedMember.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseResolvedMember.java index 82d243f03..b5031766c 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseResolvedMember.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseResolvedMember.java @@ -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; -- 2.39.5