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;
}
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
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++) {
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) {
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+}