]> source.dussan.org Git - aspectj.git/commitdiff
fixes for 128655
authoraclement <aclement>
Tue, 21 Feb 2006 09:25:47 +0000 (09:25 +0000)
committeraclement <aclement>
Tue, 21 Feb 2006 09:25:47 +0000 (09:25 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java

index fa492d9c260f5a82402dc13d531b58b3c814ec66..1524feb31b4e2c86dbb97ff9b6e204b89fbc5e74 100644 (file)
@@ -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;