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
}
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) {
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())));
}
}
}
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);
}
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;