]> source.dussan.org Git - aspectj.git/blob
3d2fb727f0cffcb94fdfdb6ad69ff39047800d07
[aspectj.git] /
1 /* *******************************************************************
2  * Copyright (c) 2006 Contributors
3  * All rights reserved.
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
8  *
9  * Contributors:
10  *     Andy Clement                 initial implementation
11  * ******************************************************************/
12 package org.aspectj.ajdt.internal.compiler.lookup;
13
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;
43
44 // not yet used...
45 public class EclipseAnnotationConvertor {
46         /**
47          * Convert one eclipse annotation into an AnnotationX object containing an AnnotationAJ object.
48          *
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.
52          */
53         public static AnnotationAJ convertEclipseAnnotation(Annotation eclipseAnnotation, World w, EclipseFactory factory) {
54                 // TODO if it is sourcevisible, we shouldn't let it through!!!!!!!!!
55                 // testcase!
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);
61                 return annotationAJ;
62         }
63
64         static class MissingImplementationException extends RuntimeException {
65                 MissingImplementationException(String reason) {
66                         super(reason);
67                 }
68         }
69
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
82                                                                                 + "]");
83                                         } else {
84                                                 AnnotationValue av = generateElementValue(memberValuePair.value, methodBinding.returnType);
85                                                 AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), av);
86                                                 annotationAJ.addNameValuePair(anvp);
87                                         }
88                                 }
89                         } else {
90                                 throw new MissingImplementationException(
91                                                 "Please raise an AspectJ bug.  AspectJ does not know how to convert this annotation [" + annotation + "]");
92                         }
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 + "]");
100                         } else {
101                                 AnnotationValue av = generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType);
102                                 annotationAJ.addNameValuePair(new AnnotationNameValuePair(new String(
103                                                 singleMemberAnnotation.memberValuePairs()[0].name), av));
104                         }
105                 } else if (annotation instanceof MarkerAnnotation) {
106                         MarkerAnnotation markerAnnotation = (MarkerAnnotation) annotation;
107                 } else {
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 + "]");
111                 }
112         }
113
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
120                                         + "]");
121                 } else {
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());
129                                 } else {
130                                         AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
131                                         return new ArrayAnnotationValue(new AnnotationValue[] { av });
132                                 }
133                         } else {
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);
138                                                 return av;
139                                         }
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());
145                                 } else {
146                                         AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
147                                         return av;
148                                 }
149                         }
150                 }
151         }
152
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());
165                         }
166                 }
167                 return null;
168         }
169
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;
181                                 } else {
182                                         throw new MissingImplementationException(
183                                                         "Please raise an AspectJ bug.  AspectJ does not know how to convert this annotation value ["
184                                                                         + defaultValue + "]");
185                                 }
186                                 if (fieldBinding != null) {
187                                         String sig = new String(fieldBinding.type.signature());
188                                         AnnotationValue enumValue = new EnumAnnotationValue(sig, new String(fieldBinding.name));
189                                         return enumValue;
190                                 }
191                                 throw new MissingImplementationException(
192                                                 "Please raise an AspectJ bug.  AspectJ does not know how to convert this annotation value [" + defaultValue
193                                                 + "]");
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
197                                                 + "]");
198                                 // contents[contentsOffset++] = (byte) '@';
199                                 // generateAnnotation((Annotation) defaultValue,
200                                 // attributeOffset);
201                         } else if (defaultValueBinding.isArrayType()) {
202                                 // array type
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());// ,
209                                                 // attributeOffset
210                                                 // )
211                                                 // ;
212                                         }
213                                         ArrayAnnotationValue aav = new ArrayAnnotationValue(values);
214                                         return aav;
215                                 } else {
216                                         throw new MissingImplementationException(
217                                                         "Please raise an AspectJ bug.  AspectJ does not know how to convert this annotation value ["
218                                                                         + defaultValue + "]");
219                                 }
220                         } else {
221                                 // class type
222                                 if (defaultValue instanceof ClassLiteralAccess) {
223                                         ClassLiteralAccess cla = (ClassLiteralAccess)defaultValue;
224                                         ClassAnnotationValue cav = new ClassAnnotationValue(new String(cla.targetType.signature()));
225                                         return cav;
226                                 }
227                                 throw new MissingImplementationException(
228                                                 "Please raise an AspectJ bug.  AspectJ does not know how to convert this annotation value [" + defaultValue
229                                                 + "]");
230                         }
231                 } else {
232                         throw new MissingImplementationException(
233                                         "Please raise an AspectJ bug.  AspectJ does not know how to convert this annotation value [" + defaultValue
234                                         + "]");
235                         // contentsOffset = attributeOffset;
236                 }
237         }
238
239 }