From 7279108648417c97156e45dbe2ceeb46cdf51d9f Mon Sep 17 00:00:00 2001 From: aclement Date: Tue, 21 Feb 2006 09:25:47 +0000 Subject: [PATCH] fixes for 128655 --- .../compiler/lookup/AjLookupEnvironment.java | 80 ++++++++++++++++--- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index fa492d9c2..1524feb31 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -33,9 +33,11 @@ import org.aspectj.bridge.context.ContextToken; import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.aspectj.org.eclipse.jdt.internal.compiler.env.AccessRestriction; import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment; @@ -59,6 +61,7 @@ import org.aspectj.weaver.AsmRelationshipProvider; import org.aspectj.weaver.ConcreteTypeMunger; import org.aspectj.weaver.FakeAnnotation; import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.UnresolvedType; @@ -756,21 +759,49 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } TypeBinding tb = factory.makeTypeBinding(aspectType); + // Hideousness follows: + // There are multiple situations to consider here and they relate to the combinations of + // where the annotation is coming from and where the annotation is going to be put: + // + // 1. Straight full build, all from source - the annotation is from a dec@type and + // is being put on some type. Both types are real SourceTypeBindings. WORKS + // 2. Incremental build, changing the affected type - the annotation is from a + // dec@type in a BinaryTypeBinding (so has to be accessed via bcel) and the + // affected type is a real SourceTypeBinding. Mostly works (pr128665) + // 3. ? - - // TODO asc determine if there really is a problem here (see comment below) - - // ClassCastException here means we probably have either a parameterized type or a raw type, we need the - // commented out code to get it to work ... currently uncommented because I've not seen a case where its - // required yet ... SourceTypeBinding stb = (SourceTypeBinding)tb; - MethodBinding[] mbs = stb.getMethods(decA.getAnnotationMethod().toCharArray()); - long abits = mbs[0].getAnnotationTagBits(); // ensure resolved - TypeDeclaration typeDecl = ((SourceTypeBinding)mbs[0].declaringClass).scope.referenceContext; - AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(mbs[0]); - Annotation[] toAdd = methodDecl.annotations; // this is what to add - abits = toAdd[0].resolvedType.getAnnotationTagBits(); + Annotation[] toAdd = null; + long abits = 0; + + // Might have to retrieve the annotation through BCEL and construct an eclipse one for it. + if (stb instanceof BinaryTypeBinding) { + ReferenceType rt = (ReferenceType)factory.fromEclipse(stb); + ResolvedMember[] methods = rt.getDeclaredMethods(); + ResolvedMember decaMethod = null; + String nameToLookFor = decA.getAnnotationMethod(); + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals(nameToLookFor)) {decaMethod = methods[i];break;} + } + if (decaMethod!=null) { // could assert this ... + AnnotationX[] axs = decaMethod.getAnnotations(); + toAdd = new Annotation[1]; + toAdd[0] = createAnnotationFromBcelAnnotation(axs[0],decaMethod.getSourceLocation().getOffset(),factory); + // BUG BUG BUG - We dont test these abits are correct, in fact we'll be very lucky if they are. + // What does that mean? It means on an incremental compile you might get away with an + // annotation that isn't allowed on a type being put on a type. + abits = toAdd[0].resolvedType.getAnnotationTagBits(); + } + } else { + // much nicer, its a real SourceTypeBinding so we can stay in eclipse land + MethodBinding[] mbs = stb.getMethods(decA.getAnnotationMethod().toCharArray()); + abits = mbs[0].getAnnotationTagBits(); // ensure resolved + TypeDeclaration typeDecl = ((SourceTypeBinding)mbs[0].declaringClass).scope.referenceContext; + AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(mbs[0]); + toAdd = methodDecl.annotations; // this is what to add + abits = toAdd[0].resolvedType.getAnnotationTagBits(); + } if (sourceType instanceof BinaryTypeBinding) { // In this case we can't access the source type binding to add a new annotation, so let's put something @@ -878,6 +909,31 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC CompilationAndWeavingContext.leavingPhase(tok); return true; } + + /** + * Transform an annotation from its AJ form to an eclipse form. We *DONT* care about the + * values of the annotation. that is because it is only being stuck on a type during + * type completion to allow for other constructs (decps, decas) that might be looking for it - + * when the class actually gets to disk it wont have this new annotation on it and during + * weave time we will do the right thing copying across values too. + */ + private static Annotation createAnnotationFromBcelAnnotation(AnnotationX annX,int pos, EclipseFactory factory) { + String name = annX.getTypeName(); + TypeBinding tb = factory.makeTypeBinding(annX.getSignature()); + char[][] typeName = CharOperation.splitOn('.',name.toCharArray()); + long[] positions = new long[] {pos}; + TypeReference annType = new QualifiedTypeReference(typeName,positions); + NormalAnnotation ann = new NormalAnnotation(annType,pos); + ann.resolvedType=tb; // yuck - is this OK in all cases? + // We don't need membervalues... +// Expression pcExpr = new StringLiteral(pointcutExpression.toCharArray(),pos,pos); +// MemberValuePair[] mvps = new MemberValuePair[2]; +// mvps[0] = new MemberValuePair("value".toCharArray(),pos,pos,pcExpr); +// Expression argNamesExpr = new StringLiteral(argNames.toCharArray(),pos,pos); +// mvps[1] = new MemberValuePair("argNames".toCharArray(),pos,pos,argNamesExpr); +// ann.memberValuePairs = mvps; + return ann; + } private boolean isAnnotationTargettingSomethingOtherThanAnnotationOrNormal(long abits) { return (abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType))==0; -- 2.39.5