You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EclipseAnnotationConvertor.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
  14. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
  15. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
  16. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
  17. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
  18. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
  19. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
  20. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
  21. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
  22. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
  23. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
  24. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant;
  25. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.IntConstant;
  26. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.StringConstant;
  27. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
  28. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  29. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
  30. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  31. import org.aspectj.weaver.AnnotationAJ;
  32. import org.aspectj.weaver.AnnotationNameValuePair;
  33. import org.aspectj.weaver.AnnotationValue;
  34. import org.aspectj.weaver.ArrayAnnotationValue;
  35. import org.aspectj.weaver.EnumAnnotationValue;
  36. import org.aspectj.weaver.ResolvedType;
  37. import org.aspectj.weaver.SimpleAnnotationValue;
  38. import org.aspectj.weaver.StandardAnnotation;
  39. import org.aspectj.weaver.World;
  40. // not yet used...
  41. public class EclipseAnnotationConvertor {
  42. /**
  43. * Convert one eclipse annotation into an AnnotationX object containing an AnnotationAJ object.
  44. *
  45. * This code and the helper methods used by it will go *BANG* if they encounter anything not currently supported - this is safer
  46. * than limping along with a malformed annotation. When the *BANG* is encountered the bug reporter should indicate the kind of
  47. * annotation they were working with and this code can be enhanced to support it.
  48. */
  49. public static AnnotationAJ convertEclipseAnnotation(Annotation eclipseAnnotation, World w, EclipseFactory factory) {
  50. // TODO if it is sourcevisible, we shouldn't let it through!!!!!!!!!
  51. // testcase!
  52. ResolvedType annotationType = factory.fromTypeBindingToRTX(eclipseAnnotation.type.resolvedType);
  53. // long bs = (eclipseAnnotation.bits & TagBits.AnnotationRetentionMASK);
  54. boolean isRuntimeVisible = (eclipseAnnotation.bits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
  55. StandardAnnotation annotationAJ = new StandardAnnotation(annotationType, isRuntimeVisible);
  56. generateAnnotation(eclipseAnnotation, annotationAJ);
  57. return annotationAJ;
  58. }
  59. static class MissingImplementationException extends RuntimeException {
  60. MissingImplementationException(String reason) {
  61. super(reason);
  62. }
  63. }
  64. private static void generateAnnotation(Annotation annotation, StandardAnnotation annotationAJ) {
  65. if (annotation instanceof NormalAnnotation) {
  66. NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
  67. MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
  68. if (memberValuePairs != null) {
  69. int memberValuePairsLength = memberValuePairs.length;
  70. for (int i = 0; i < memberValuePairsLength; i++) {
  71. MemberValuePair memberValuePair = memberValuePairs[i];
  72. MethodBinding methodBinding = memberValuePair.binding;
  73. if (methodBinding == null) {
  74. // is this just a marker annotation?
  75. throw new MissingImplementationException(
  76. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation
  77. + "]");
  78. } else {
  79. AnnotationValue av = generateElementValue(memberValuePair.value, methodBinding.returnType);
  80. AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), av);
  81. annotationAJ.addNameValuePair(anvp);
  82. }
  83. }
  84. } else {
  85. throw new MissingImplementationException(
  86. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
  87. }
  88. } else if (annotation instanceof SingleMemberAnnotation) {
  89. // this is a single member annotation (one member value)
  90. SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation;
  91. MethodBinding methodBinding = singleMemberAnnotation.memberValuePairs()[0].binding;
  92. if (methodBinding == null) {
  93. throw new MissingImplementationException(
  94. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
  95. } else {
  96. AnnotationValue av = generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType);
  97. annotationAJ.addNameValuePair(new AnnotationNameValuePair(new String(
  98. singleMemberAnnotation.memberValuePairs()[0].name), av));
  99. }
  100. } else if (annotation instanceof MarkerAnnotation) {
  101. MarkerAnnotation markerAnnotation = (MarkerAnnotation) annotation;
  102. } else {
  103. // this is a marker annotation (no member value pairs)
  104. throw new MissingImplementationException(
  105. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
  106. }
  107. }
  108. private static AnnotationValue generateElementValue(Expression defaultValue, TypeBinding memberValuePairReturnType) {
  109. Constant constant = defaultValue.constant;
  110. TypeBinding defaultValueBinding = defaultValue.resolvedType;
  111. if (defaultValueBinding == null) {
  112. throw new MissingImplementationException(
  113. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  114. + "]");
  115. } else {
  116. if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) {
  117. if (constant != null && constant != Constant.NotAConstant) {
  118. throw new MissingImplementationException(
  119. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  120. + defaultValue + "]");
  121. // generateElementValue(attributeOffset, defaultValue,
  122. // constant, memberValuePairReturnType.leafComponentType());
  123. } else {
  124. AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
  125. return new ArrayAnnotationValue(new AnnotationValue[] { av });
  126. }
  127. } else {
  128. if (constant != null && constant != Constant.NotAConstant) {
  129. if (constant instanceof IntConstant || constant instanceof BooleanConstant
  130. || constant instanceof StringConstant) {
  131. AnnotationValue av = generateElementValueForConstantExpression(defaultValue, defaultValueBinding);
  132. return av;
  133. }
  134. throw new MissingImplementationException(
  135. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  136. + defaultValue + "]");
  137. // generateElementValue(attributeOffset, defaultValue,
  138. // constant, memberValuePairReturnType.leafComponentType());
  139. } else {
  140. AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
  141. return av;
  142. }
  143. }
  144. }
  145. }
  146. public static AnnotationValue generateElementValueForConstantExpression(Expression defaultValue, TypeBinding defaultValueBinding) {
  147. if (defaultValueBinding != null) {
  148. Constant c = defaultValue.constant;
  149. if (c instanceof IntConstant) {
  150. IntConstant iConstant = (IntConstant) c;
  151. return new SimpleAnnotationValue(ElementValue.PRIMITIVE_INT, new Integer(iConstant.intValue()));
  152. } else if (c instanceof BooleanConstant) {
  153. BooleanConstant iConstant = (BooleanConstant) c;
  154. return new SimpleAnnotationValue(ElementValue.PRIMITIVE_BOOLEAN, new Boolean(iConstant.booleanValue()));
  155. } else if (c instanceof StringConstant) {
  156. StringConstant sConstant = (StringConstant) c;
  157. return new SimpleAnnotationValue(ElementValue.STRING, sConstant.stringValue());
  158. }
  159. }
  160. return null;
  161. }
  162. private static AnnotationValue generateElementValueForNonConstantExpression(Expression defaultValue,
  163. TypeBinding defaultValueBinding) {
  164. if (defaultValueBinding != null) {
  165. if (defaultValueBinding.isEnum()) {
  166. FieldBinding fieldBinding = null;
  167. if (defaultValue instanceof QualifiedNameReference) {
  168. QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
  169. fieldBinding = (FieldBinding) nameReference.binding;
  170. } else if (defaultValue instanceof SingleNameReference) {
  171. SingleNameReference nameReference = (SingleNameReference) defaultValue;
  172. fieldBinding = (FieldBinding) nameReference.binding;
  173. } else {
  174. throw new MissingImplementationException(
  175. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  176. + defaultValue + "]");
  177. }
  178. if (fieldBinding != null) {
  179. String sig = new String(fieldBinding.type.signature());
  180. AnnotationValue enumValue = new EnumAnnotationValue(sig, new String(fieldBinding.name));
  181. return enumValue;
  182. }
  183. throw new MissingImplementationException(
  184. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  185. + "]");
  186. } else if (defaultValueBinding.isAnnotationType()) {
  187. throw new MissingImplementationException(
  188. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  189. + "]");
  190. // contents[contentsOffset++] = (byte) '@';
  191. // generateAnnotation((Annotation) defaultValue,
  192. // attributeOffset);
  193. } else if (defaultValueBinding.isArrayType()) {
  194. // array type
  195. if (defaultValue instanceof ArrayInitializer) {
  196. ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
  197. int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0;
  198. AnnotationValue[] values = new AnnotationValue[arrayLength];
  199. for (int i = 0; i < arrayLength; i++) {
  200. values[i] = generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType());// ,
  201. // attributeOffset
  202. // )
  203. // ;
  204. }
  205. ArrayAnnotationValue aav = new ArrayAnnotationValue(values);
  206. return aav;
  207. } else {
  208. throw new MissingImplementationException(
  209. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  210. + defaultValue + "]");
  211. }
  212. } else {
  213. // class type
  214. throw new MissingImplementationException(
  215. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  216. + "]");
  217. // if (contentsOffset + 3 >= this.contents.length) {
  218. // resizeContents(3);
  219. // }
  220. // contents[contentsOffset++] = (byte) 'c';
  221. // if (defaultValue instanceof ClassLiteralAccess) {
  222. // ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess)
  223. // defaultValue;
  224. // final int classInfoIndex =
  225. // constantPool.literalIndex(classLiteralAccess
  226. // .targetType.signature());
  227. // contents[contentsOffset++] = (byte) (classInfoIndex >> 8);
  228. // contents[contentsOffset++] = (byte) classInfoIndex;
  229. // } else {
  230. // contentsOffset = attributeOffset;
  231. // }
  232. }
  233. } else {
  234. throw new MissingImplementationException(
  235. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  236. + "]");
  237. // contentsOffset = attributeOffset;
  238. }
  239. }
  240. }