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

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