]> source.dussan.org Git - aspectj.git/commitdiff
fixes for 117882
authoraclement <aclement>
Sun, 4 Dec 2005 13:40:06 +0000 (13:40 +0000)
committeraclement <aclement>
Sun, 4 Dec 2005 13:40:06 +0000 (13:40 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
weaver/src/org/aspectj/weaver/FakeAnnotation.java [new file with mode: 0644]

index e743af75e5143a66883bbd78aad53daa2bd9b00a..966f2c564a476ad114ea8f92a5bb32b1f28e9706 100644 (file)
@@ -54,8 +54,10 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.AsmRelationshipProvider;
 import org.aspectj.weaver.ConcreteTypeMunger;
+import org.aspectj.weaver.FakeAnnotation;
 import org.aspectj.weaver.ReferenceType;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.TypeVariable;
@@ -726,6 +728,9 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
                }
                TypeBinding tb = factory.makeTypeBinding(aspectType);
                
+               
+               
+               
                // 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
@@ -739,6 +744,54 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
                Annotation[] 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
+                       // on the weaver type temporarily
+                       ResolvedType theTargetType = factory.fromEclipse(sourceType);
+                       TypeBinding theAnnotationType = toAdd[0].resolvedType;
+                       String name = new String(theAnnotationType.qualifiedPackageName())+"."+new String(theAnnotationType.sourceName());
+                       String sig = new String(theAnnotationType.signature());
+                       if (theTargetType.hasAnnotation(UnresolvedType.forSignature(sig))) {
+                               CompilationAndWeavingContext.leavingPhase(tok);
+                               return false;
+                       }
+                       
+                       // FIXME asc tidy up this code that duplicates whats below!
+                       // Simple checks on the bits
+                       boolean giveupnow = false;
+                       if (((abits & TagBits.AnnotationTargetMASK)!=0)) {
+                               if ( isAnnotationTargettingSomethingOtherThanAnnotationOrNormal(abits)) {
+                                       // error will have been already reported
+                                       giveupnow = true;
+                               } else if (  (sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType)==0) ||
+                                     (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType)==0) ) {
+                               
+                                 if (reportProblems) {
+                                   if (decA.isExactPattern()) {
+                                     factory.showMessage(IMessage.ERROR,
+                                               WeaverMessages.format(WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION,rtx.getName(),toAdd[0].type,stringifyTargets(abits)),
+                                               decA.getSourceLocation(), null);
+                                   } 
+                                   // dont put out the lint - the weaving process will do that
+//                                 else {
+//                                       if (factory.getWorld().getLint().invalidTargetForAnnotation.isEnabled()) {
+//                                               factory.getWorld().getLint().invalidTargetForAnnotation.signal(new String[]{rtx.getName(),toAdd[0].type.toString(),stringifyTargets(abits)},decA.getSourceLocation(),null);
+//                                       }
+//                                 }
+                                 }
+                                 giveupnow=true;
+                           }
+                       }
+                       if (giveupnow) { 
+                               CompilationAndWeavingContext.leavingPhase(tok);
+                               return false;
+                       }
+                       
+                       theTargetType.addAnnotation(new AnnotationX(new FakeAnnotation(name,sig,(abits & TagBits.AnnotationRuntimeRetention)!=0),factory.getWorld()));
+                       CompilationAndWeavingContext.leavingPhase(tok);
+                       return true;
+               }
+               
                Annotation currentAnnotations[] = sourceType.scope.referenceContext.annotations;
                if (currentAnnotations!=null) 
                for (int i = 0; i < currentAnnotations.length; i++) {
@@ -797,6 +850,10 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
                CompilationAndWeavingContext.leavingPhase(tok);
                return true;
        }
+
+       private boolean isAnnotationTargettingSomethingOtherThanAnnotationOrNormal(long abits) {
+               return (abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType))==0;
+       }
        
 
        private void reportDeclareParentsMessage(WeaveMessage.WeaveMessageKind wmk,SourceTypeBinding sourceType,ResolvedType parent) {
diff --git a/weaver/src/org/aspectj/weaver/FakeAnnotation.java b/weaver/src/org/aspectj/weaver/FakeAnnotation.java
new file mode 100644 (file)
index 0000000..ea36cea
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * initial implementation              Andy Clement
+ *******************************************************************************/
+package org.aspectj.weaver;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.aspectj.apache.bcel.classfile.annotation.Annotation;
+import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
+
+/**
+ * For implementing declare @type interacting with declare @parents during compilation - we need to be 
+ * able to add an annotation to 'binary type binding' (this is how types are seen during incremental compilation).
+ * Unlike a SourceTypeBinding - a BinaryTypeBinding does not allow easy interaction with its annotations - 
+ * so what we do is take the eclipse annotation, suck out the name/signature and visibility and put that information
+ * in a 'FakeAnnotation'.  The FakeAnnotation is attached to the BCEL delegate for the binary type binding -
+ * this will allow type resolution to succeed correctly.  The FakeAnnotation never makes it to disk, since the weaver
+ * does the job properly, attaching a real annotation.
+ */
+public class FakeAnnotation extends Annotation {
+
+       private String name;
+       private String sig;
+       private boolean isRuntimeVisible;
+       
+       public FakeAnnotation(String name,String sig,boolean isRuntimeVisible) {
+               super(0,null,true);
+               this.name = name;
+               this.sig = sig;
+               this.isRuntimeVisible = isRuntimeVisible;
+       }
+
+       public String getTypeName() {
+               return name;
+       }
+
+       public String getTypeSignature() {
+               return sig;
+       }
+
+       public void addElementNameValuePair(ElementNameValuePair evp) {
+               // doesnt need to know about name/value pairs
+       }
+
+       protected void dump(DataOutputStream dos) throws IOException {
+               // should be serialized
+       }
+
+       public int getTypeIndex() {
+               return 0;
+       }
+
+       public List getValues() {
+               return null;
+       }
+
+       public boolean isRuntimeVisible() {
+               return isRuntimeVisible;
+       }
+
+       protected void isRuntimeVisible(boolean b) {
+       }
+
+       public String toShortString() {
+               return "@"+this.name;
+       }
+
+       public String toString() {
+               return this.name;
+       }
+}