1 /* *******************************************************************
2 * Copyright (c) 2006 Contributors
4 * This program and the accompanying materials are made available
5 * under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Andy Clement initial implementation
11 * ******************************************************************/
12 package org.aspectj.ajdt.internal.compiler.lookup;
14 import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
15 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
16 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
17 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
18 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
19 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
20 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
21 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
22 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
23 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
24 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
25 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
26 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant;
27 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.IntConstant;
28 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.StringConstant;
29 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
30 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
31 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
32 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
33 import org.aspectj.weaver.AnnotationAJ;
34 import org.aspectj.weaver.AnnotationNameValuePair;
35 import org.aspectj.weaver.AnnotationValue;
36 import org.aspectj.weaver.ArrayAnnotationValue;
37 import org.aspectj.weaver.ClassAnnotationValue;
38 import org.aspectj.weaver.EnumAnnotationValue;
39 import org.aspectj.weaver.ResolvedType;
40 import org.aspectj.weaver.SimpleAnnotationValue;
41 import org.aspectj.weaver.StandardAnnotation;
42 import org.aspectj.weaver.World;
45 public class EclipseAnnotationConvertor {
47 * Convert one eclipse annotation into an AnnotationX object containing an AnnotationAJ object.
49 * This code and the helper methods used by it will go *BANG* if they encounter anything not currently supported - this is safer
50 * than limping along with a malformed annotation. When the *BANG* is encountered the bug reporter should indicate the kind of
51 * annotation they were working with and this code can be enhanced to support it.
53 public static AnnotationAJ convertEclipseAnnotation(Annotation eclipseAnnotation, World w, EclipseFactory factory) {
54 // TODO if it is sourcevisible, we shouldn't let it through!!!!!!!!!
56 ResolvedType annotationType = factory.fromTypeBindingToRTX(eclipseAnnotation.type.resolvedType);
57 // long bs = (eclipseAnnotation.bits & TagBits.AnnotationRetentionMASK);
58 boolean isRuntimeVisible = (eclipseAnnotation.bits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
59 StandardAnnotation annotationAJ = new StandardAnnotation(annotationType, isRuntimeVisible);
60 generateAnnotation(eclipseAnnotation, annotationAJ);
64 static class MissingImplementationException extends RuntimeException {
65 MissingImplementationException(String reason) {
70 private static void generateAnnotation(Annotation annotation, StandardAnnotation annotationAJ) {
71 if (annotation instanceof NormalAnnotation) {
72 NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
73 MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
74 if (memberValuePairs != null) {
75 int memberValuePairsLength = memberValuePairs.length;
76 for (MemberValuePair memberValuePair : memberValuePairs) {
77 MethodBinding methodBinding = memberValuePair.binding;
78 if (methodBinding == null) {
79 // is this just a marker annotation?
80 throw new MissingImplementationException(
81 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation
84 AnnotationValue av = generateElementValue(memberValuePair.value, methodBinding.returnType);
85 AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), av);
86 annotationAJ.addNameValuePair(anvp);
90 throw new MissingImplementationException(
91 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
93 } else if (annotation instanceof SingleMemberAnnotation) {
94 // this is a single member annotation (one member value)
95 SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation;
96 MethodBinding methodBinding = singleMemberAnnotation.memberValuePairs()[0].binding;
97 if (methodBinding == null) {
98 throw new MissingImplementationException(
99 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
101 AnnotationValue av = generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType);
102 annotationAJ.addNameValuePair(new AnnotationNameValuePair(new String(
103 singleMemberAnnotation.memberValuePairs()[0].name), av));
105 } else if (annotation instanceof MarkerAnnotation) {
106 MarkerAnnotation markerAnnotation = (MarkerAnnotation) annotation;
108 // this is a marker annotation (no member value pairs)
109 throw new MissingImplementationException(
110 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
114 private static AnnotationValue generateElementValue(Expression defaultValue, TypeBinding memberValuePairReturnType) {
115 Constant constant = defaultValue.constant;
116 TypeBinding defaultValueBinding = defaultValue.resolvedType;
117 if (defaultValueBinding == null) {
118 throw new MissingImplementationException(
119 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
122 if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) {
123 if (constant != null && constant != Constant.NotAConstant) {
124 throw new MissingImplementationException(
125 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
126 + defaultValue + "]");
127 // generateElementValue(attributeOffset, defaultValue,
128 // constant, memberValuePairReturnType.leafComponentType());
130 AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
131 return new ArrayAnnotationValue(new AnnotationValue[] { av });
134 if (constant != null && constant != Constant.NotAConstant) {
135 if (constant instanceof IntConstant || constant instanceof BooleanConstant
136 || constant instanceof StringConstant) {
137 AnnotationValue av = generateElementValueForConstantExpression(defaultValue, defaultValueBinding);
140 throw new MissingImplementationException(
141 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
142 + defaultValue + "]");
143 // generateElementValue(attributeOffset, defaultValue,
144 // constant, memberValuePairReturnType.leafComponentType());
146 AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
153 public static AnnotationValue generateElementValueForConstantExpression(Expression defaultValue, TypeBinding defaultValueBinding) {
154 if (defaultValueBinding != null) {
155 Constant c = defaultValue.constant;
156 if (c instanceof IntConstant) {
157 IntConstant iConstant = (IntConstant) c;
158 return new SimpleAnnotationValue(ElementValue.PRIMITIVE_INT, new Integer(iConstant.intValue()));
159 } else if (c instanceof BooleanConstant) {
160 BooleanConstant iConstant = (BooleanConstant) c;
161 return new SimpleAnnotationValue(ElementValue.PRIMITIVE_BOOLEAN, iConstant.booleanValue());
162 } else if (c instanceof StringConstant) {
163 StringConstant sConstant = (StringConstant) c;
164 return new SimpleAnnotationValue(ElementValue.STRING, sConstant.stringValue());
170 private static AnnotationValue generateElementValueForNonConstantExpression(Expression defaultValue,
171 TypeBinding defaultValueBinding) {
172 if (defaultValueBinding != null) {
173 if (defaultValueBinding.isEnum()) {
174 FieldBinding fieldBinding = null;
175 if (defaultValue instanceof QualifiedNameReference) {
176 QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
177 fieldBinding = (FieldBinding) nameReference.binding;
178 } else if (defaultValue instanceof SingleNameReference) {
179 SingleNameReference nameReference = (SingleNameReference) defaultValue;
180 fieldBinding = (FieldBinding) nameReference.binding;
182 throw new MissingImplementationException(
183 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
184 + defaultValue + "]");
186 if (fieldBinding != null) {
187 String sig = new String(fieldBinding.type.signature());
188 AnnotationValue enumValue = new EnumAnnotationValue(sig, new String(fieldBinding.name));
191 throw new MissingImplementationException(
192 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
194 } else if (defaultValueBinding.isAnnotationType()) {
195 throw new MissingImplementationException(
196 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
198 // contents[contentsOffset++] = (byte) '@';
199 // generateAnnotation((Annotation) defaultValue,
201 } else if (defaultValueBinding.isArrayType()) {
203 if (defaultValue instanceof ArrayInitializer) {
204 ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
205 int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0;
206 AnnotationValue[] values = new AnnotationValue[arrayLength];
207 for (int i = 0; i < arrayLength; i++) {
208 values[i] = generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType());// ,
213 ArrayAnnotationValue aav = new ArrayAnnotationValue(values);
216 throw new MissingImplementationException(
217 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
218 + defaultValue + "]");
222 if (defaultValue instanceof ClassLiteralAccess) {
223 ClassLiteralAccess cla = (ClassLiteralAccess)defaultValue;
224 ClassAnnotationValue cav = new ClassAnnotationValue(new String(cla.targetType.signature()));
227 throw new MissingImplementationException(
228 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
232 throw new MissingImplementationException(
233 "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
235 // contentsOffset = attributeOffset;