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.

EclipseSourceType.java 50KB

18 years ago
18 years ago
12 years ago
18 years ago
12 years ago
12 years ago
18 years ago
18 years ago
18 years ago
11 years ago
18 years ago
18 years ago
12 years ago
18 years ago
11 years ago
18 years ago
18 years ago
18 years ago
11 years ago
11 years ago
11 years ago
13 years ago
18 years ago
18 years ago
11 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
13 years ago
13 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. /* *******************************************************************
  2. * Copyright (c) 2002,2010 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. * PARC initial implementation
  11. * Alexandre Vasseur support for @AJ perClause
  12. * ******************************************************************/
  13. package org.aspectj.ajdt.internal.compiler.lookup;
  14. import java.util.ArrayList;
  15. import java.util.Collection;
  16. import java.util.Collections;
  17. import java.util.List;
  18. import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
  19. import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
  20. import org.aspectj.ajdt.internal.compiler.ast.DeclareAnnotationDeclaration;
  21. import org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration;
  22. import org.aspectj.ajdt.internal.compiler.ast.InterTypeDeclaration;
  23. import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
  24. import org.aspectj.ajdt.internal.core.builder.EclipseSourceContext;
  25. import org.aspectj.bridge.IMessage;
  26. import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
  27. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
  28. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  29. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
  30. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
  31. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
  32. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
  33. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
  34. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
  35. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Literal;
  36. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
  37. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
  38. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NameReference;
  39. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
  40. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
  41. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
  42. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
  43. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral;
  44. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  45. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeParameter;
  46. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant;
  47. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
  48. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
  49. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
  50. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
  51. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
  52. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
  53. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  54. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
  55. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
  56. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
  57. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
  58. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  59. import org.aspectj.weaver.AbstractReferenceTypeDelegate;
  60. import org.aspectj.weaver.AnnotationAJ;
  61. import org.aspectj.weaver.AnnotationAnnotationValue;
  62. import org.aspectj.weaver.AnnotationNameValuePair;
  63. import org.aspectj.weaver.AnnotationTargetKind;
  64. import org.aspectj.weaver.AnnotationValue;
  65. import org.aspectj.weaver.ArrayAnnotationValue;
  66. import org.aspectj.weaver.BCException;
  67. import org.aspectj.weaver.ClassAnnotationValue;
  68. import org.aspectj.weaver.EnumAnnotationValue;
  69. import org.aspectj.weaver.ReferenceType;
  70. import org.aspectj.weaver.ResolvedMember;
  71. import org.aspectj.weaver.ResolvedMemberImpl;
  72. import org.aspectj.weaver.ResolvedPointcutDefinition;
  73. import org.aspectj.weaver.ResolvedType;
  74. import org.aspectj.weaver.StandardAnnotation;
  75. import org.aspectj.weaver.TypeVariable;
  76. import org.aspectj.weaver.UnresolvedType;
  77. import org.aspectj.weaver.WeaverStateInfo;
  78. import org.aspectj.weaver.World;
  79. import org.aspectj.weaver.bcel.AtAjAttributes.LazyResolvedPointcutDefinition;
  80. import org.aspectj.weaver.patterns.Declare;
  81. import org.aspectj.weaver.patterns.FormalBinding;
  82. import org.aspectj.weaver.patterns.ParserException;
  83. import org.aspectj.weaver.patterns.PatternParser;
  84. import org.aspectj.weaver.patterns.PerClause;
  85. import org.aspectj.weaver.patterns.PerFromSuper;
  86. import org.aspectj.weaver.patterns.PerSingleton;
  87. import org.aspectj.weaver.patterns.Pointcut;
  88. /**
  89. * Supports viewing eclipse TypeDeclarations/SourceTypeBindings as a ResolvedType
  90. *
  91. * @author Jim Hugunin
  92. * @author Andy Clement
  93. */
  94. public class EclipseSourceType extends AbstractReferenceTypeDelegate {
  95. private static final char[] pointcutSig = "Lorg/aspectj/lang/annotation/Pointcut;".toCharArray();
  96. private static final char[] aspectSig = "Lorg/aspectj/lang/annotation/Aspect;".toCharArray();
  97. protected ResolvedPointcutDefinition[] declaredPointcuts = null;
  98. protected ResolvedMember[] declaredMethods = null;
  99. protected ResolvedMember[] declaredFields = null;
  100. public List<Declare> declares = new ArrayList<Declare>();
  101. public List<EclipseTypeMunger> typeMungers = new ArrayList<EclipseTypeMunger>();
  102. private final EclipseFactory factory;
  103. private final SourceTypeBinding binding;
  104. private final TypeDeclaration declaration;
  105. private final CompilationUnitDeclaration unit;
  106. private boolean annotationsFullyResolved = false;
  107. private boolean annotationTypesAreResolved = false;
  108. private ResolvedType[] annotationTypes = null;
  109. private boolean discoveredAnnotationTargetKinds = false;
  110. private AnnotationTargetKind[] annotationTargetKinds;
  111. private AnnotationAJ[] annotations = null;
  112. protected EclipseFactory eclipseWorld() {
  113. return factory;
  114. }
  115. public EclipseSourceType(ReferenceType resolvedTypeX, EclipseFactory factory, SourceTypeBinding binding,
  116. TypeDeclaration declaration, CompilationUnitDeclaration unit) {
  117. super(resolvedTypeX, true);
  118. this.factory = factory;
  119. this.binding = binding;
  120. this.declaration = declaration;
  121. this.unit = unit;
  122. setSourceContext(new EclipseSourceContext(declaration.compilationResult));
  123. resolvedTypeX.setStartPos(declaration.sourceStart);
  124. resolvedTypeX.setEndPos(declaration.sourceEnd);
  125. }
  126. public boolean isAspect() {
  127. final boolean isCodeStyle = declaration instanceof AspectDeclaration;
  128. return isCodeStyle ? isCodeStyle : isAnnotationStyleAspect();
  129. }
  130. public boolean isAnonymous() {
  131. if (declaration.binding != null) {
  132. return declaration.binding.isAnonymousType();
  133. }
  134. return ((declaration.modifiers & (ASTNode.IsAnonymousType | ASTNode.IsLocalType)) != 0);
  135. }
  136. public boolean isNested() {
  137. if (declaration.binding != null) {
  138. return (declaration.binding.isMemberType());
  139. }
  140. return ((declaration.modifiers & ASTNode.IsMemberType) != 0);
  141. }
  142. public ResolvedType getOuterClass() {
  143. if (declaration.binding != null) {
  144. ReferenceBinding enclosingType = declaration.binding.enclosingType();
  145. return enclosingType==null?null:eclipseWorld().fromEclipse(enclosingType);
  146. }
  147. // TODO are we going to make a mistake here if the binding is null?
  148. // Do we ever get asked when the binding is null
  149. if (declaration.enclosingType == null) {
  150. return null;
  151. }
  152. return eclipseWorld().fromEclipse(declaration.enclosingType.binding);
  153. }
  154. public boolean isAnnotationStyleAspect() {
  155. if (declaration.annotations == null) {
  156. return false;
  157. }
  158. ResolvedType[] annotations = getAnnotationTypes();
  159. for (int i = 0; i < annotations.length; i++) {
  160. if ("org.aspectj.lang.annotation.Aspect".equals(annotations[i].getName())) {
  161. return true;
  162. }
  163. }
  164. return false;
  165. }
  166. /** Returns "" if there is a problem */
  167. private String getPointcutStringFromAnnotationStylePointcut(AbstractMethodDeclaration amd) {
  168. Annotation[] ans = amd.annotations;
  169. if (ans == null) {
  170. return "";
  171. }
  172. for (int i = 0; i < ans.length; i++) {
  173. if (ans[i].resolvedType == null) {
  174. continue; // XXX happens if we do this very early from
  175. }
  176. // buildInterTypeandPerClause
  177. // may prevent us from resolving references made in @Pointcuts to
  178. // an @Pointcut in a code-style aspect
  179. char[] sig = ans[i].resolvedType.signature();
  180. if (CharOperation.equals(pointcutSig, sig)) {
  181. if (ans[i].memberValuePairs().length == 0) {
  182. return ""; // empty pointcut expression
  183. }
  184. Expression expr = ans[i].memberValuePairs()[0].value;
  185. if (expr instanceof StringLiteral) {
  186. StringLiteral sLit = ((StringLiteral) expr);
  187. return new String(sLit.source());
  188. } else if (expr instanceof NameReference && (((NameReference) expr).binding instanceof FieldBinding)) {
  189. Binding b = ((NameReference) expr).binding;
  190. Constant c = ((FieldBinding) b).constant;
  191. return c.stringValue();
  192. } else {
  193. throw new BCException("Do not know how to recover pointcut definition from " + expr + " (type "
  194. + expr.getClass().getName() + ")");
  195. }
  196. }
  197. }
  198. return "";
  199. }
  200. private boolean isAnnotationStylePointcut(Annotation[] annotations) {
  201. if (annotations == null) {
  202. return false;
  203. }
  204. for (int i = 0; i < annotations.length; i++) {
  205. if (annotations[i].resolvedType == null) {
  206. continue; // XXX happens if we do this very early from
  207. }
  208. // buildInterTypeandPerClause
  209. // may prevent us from resolving references made in @Pointcuts to
  210. // an @Pointcut in a code-style aspect
  211. char[] sig = annotations[i].resolvedType.signature();
  212. if (CharOperation.equals(pointcutSig, sig)) {
  213. return true;
  214. }
  215. }
  216. return false;
  217. }
  218. public WeaverStateInfo getWeaverState() {
  219. return null;
  220. }
  221. public ResolvedType getSuperclass() {
  222. if (binding.isInterface()) {
  223. return getResolvedTypeX().getWorld().getCoreType(UnresolvedType.OBJECT);
  224. }
  225. // XXX what about java.lang.Object
  226. return eclipseWorld().fromEclipse(binding.superclass());
  227. }
  228. public ResolvedType[] getDeclaredInterfaces() {
  229. return eclipseWorld().fromEclipse(binding.superInterfaces());
  230. }
  231. protected void fillDeclaredMembers() {
  232. List<ResolvedMember> declaredPointcuts = new ArrayList<ResolvedMember>();
  233. List<ResolvedMember> declaredMethods = new ArrayList<ResolvedMember>();
  234. List<ResolvedMember> declaredFields = new ArrayList<ResolvedMember>();
  235. MethodBinding[] ms = binding.methods(); // the important side-effect of this call is to make
  236. // sure bindings are completed
  237. AbstractMethodDeclaration[] methods = declaration.methods;
  238. if (methods != null) {
  239. for (int i = 0, len = methods.length; i < len; i++) {
  240. AbstractMethodDeclaration amd = methods[i];
  241. if (amd == null || amd.ignoreFurtherInvestigation) {
  242. continue;
  243. }
  244. if (amd instanceof PointcutDeclaration) {
  245. PointcutDeclaration d = (PointcutDeclaration) amd;
  246. ResolvedPointcutDefinition df = d.makeResolvedPointcutDefinition(factory);
  247. if (df != null) {
  248. declaredPointcuts.add(df);
  249. }
  250. } else if (amd instanceof InterTypeDeclaration) {
  251. // these are handled in a separate pass
  252. continue;
  253. } else if (amd instanceof DeclareDeclaration && !(amd instanceof DeclareAnnotationDeclaration)) { // surfaces
  254. // the
  255. // annotated
  256. // ajc$ method
  257. // these are handled in a separate pass
  258. continue;
  259. } else if (amd instanceof AdviceDeclaration) {
  260. // these are ignored during compilation and only used during
  261. // weaving
  262. continue;
  263. } else if ((amd.annotations != null) && isAnnotationStylePointcut(amd.annotations)) {
  264. // consider pointcuts defined via annotations
  265. ResolvedPointcutDefinition df = makeResolvedPointcutDefinition(amd);
  266. if (df != null) {
  267. declaredPointcuts.add(df);
  268. }
  269. } else {
  270. if (amd.binding == null || !amd.binding.isValidBinding()) {
  271. continue;
  272. }
  273. ResolvedMember member = factory.makeResolvedMember(amd.binding);
  274. if (unit != null) {
  275. boolean positionKnown = true;
  276. if (amd.binding.sourceMethod() == null) {
  277. if (amd.binding.declaringClass instanceof SourceTypeBinding) {
  278. SourceTypeBinding stb = ((SourceTypeBinding) amd.binding.declaringClass);
  279. if (stb.scope == null || stb.scope.referenceContext == null) {
  280. positionKnown = false;
  281. }
  282. }
  283. }
  284. if (positionKnown) { // pr229829
  285. member.setSourceContext(new EclipseSourceContext(unit.compilationResult, amd.binding.sourceStart()));
  286. member.setPosition(amd.binding.sourceStart(), amd.binding.sourceEnd());
  287. } else {
  288. member.setSourceContext(new EclipseSourceContext(unit.compilationResult, 0));
  289. member.setPosition(0, 0);
  290. }
  291. }
  292. declaredMethods.add(member);
  293. }
  294. }
  295. }
  296. if (isEnum()) {
  297. // The bindings for the eclipse binding will include values/valueof
  298. for (int m=0,len=ms.length;m<len;m++) {
  299. MethodBinding mb = ms[m];
  300. if ((mb instanceof SyntheticMethodBinding) && mb.isStatic()) { // cannot use .isSynthetic() because it isn't truly synthetic
  301. if (CharOperation.equals(mb.selector,valuesCharArray) && mb.parameters.length==0 && mb.returnType.isArrayType() && ((ArrayBinding)mb.returnType).leafComponentType()==binding) {
  302. // static <EnumType>[] values()
  303. ResolvedMember valuesMember = factory.makeResolvedMember(mb);
  304. valuesMember.setSourceContext(new EclipseSourceContext(unit.compilationResult, 0));
  305. valuesMember.setPosition(0, 0);
  306. declaredMethods.add(valuesMember);
  307. } else if (CharOperation.equals(mb.selector,valueOfCharArray) && mb.parameters.length==1 && CharOperation.equals(mb.parameters[0].signature(),jlString) && mb.returnType==binding) {
  308. // static <EnumType> valueOf(String)
  309. ResolvedMember valueOfMember = factory.makeResolvedMember(mb);
  310. valueOfMember.setSourceContext(new EclipseSourceContext(unit.compilationResult, 0));
  311. valueOfMember.setPosition(0, 0);
  312. declaredMethods.add(valueOfMember);
  313. }
  314. }
  315. }
  316. }
  317. FieldBinding[] fields = binding.fields();
  318. for (int i = 0, len = fields.length; i < len; i++) {
  319. FieldBinding f = fields[i];
  320. declaredFields.add(factory.makeResolvedMember(f));
  321. }
  322. this.declaredPointcuts = declaredPointcuts.toArray(new ResolvedPointcutDefinition[declaredPointcuts.size()]);
  323. this.declaredMethods = declaredMethods.toArray(new ResolvedMember[declaredMethods.size()]);
  324. this.declaredFields = declaredFields.toArray(new ResolvedMember[declaredFields.size()]);
  325. }
  326. private final static char[] valuesCharArray = "values".toCharArray();
  327. private final static char[] valueOfCharArray = "valueOf".toCharArray();
  328. private final static char[] jlString = "Ljava/lang/String;".toCharArray();
  329. private ResolvedPointcutDefinition makeResolvedPointcutDefinition(AbstractMethodDeclaration md) {
  330. if (md.binding == null) {
  331. return null; // there is another error that has caused this...
  332. // pr138143
  333. }
  334. EclipseSourceContext eSourceContext = new EclipseSourceContext(md.compilationResult);
  335. Pointcut pc = null;
  336. if (!md.isAbstract()) {
  337. String expression = getPointcutStringFromAnnotationStylePointcut(md);
  338. try {
  339. pc = new PatternParser(expression, eSourceContext).parsePointcut();
  340. } catch (ParserException pe) { // error will be reported by other
  341. // means...
  342. pc = Pointcut.makeMatchesNothing(Pointcut.SYMBOLIC);
  343. }
  344. }
  345. FormalBinding[] bindings = buildFormalAdviceBindingsFrom(md);
  346. ResolvedPointcutDefinition rpd = new LazyResolvedPointcutDefinition(factory.fromBinding(md.binding.declaringClass),
  347. md.modifiers, new String(md.selector), factory.fromBindings(md.binding.parameters),
  348. factory.fromBinding(md.binding.returnType), pc, new EclipseScope(bindings, md.scope));
  349. rpd.setPosition(md.sourceStart, md.sourceEnd);
  350. rpd.setSourceContext(eSourceContext);
  351. return rpd;
  352. }
  353. private static final char[] joinPoint = "Lorg/aspectj/lang/JoinPoint;".toCharArray();
  354. private static final char[] joinPointStaticPart = "Lorg/aspectj/lang/JoinPoint$StaticPart;".toCharArray();
  355. private static final char[] joinPointEnclosingStaticPart = "Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;".toCharArray();
  356. private static final char[] proceedingJoinPoint = "Lorg/aspectj/lang/ProceedingJoinPoint;".toCharArray();
  357. private FormalBinding[] buildFormalAdviceBindingsFrom(AbstractMethodDeclaration mDecl) {
  358. if (mDecl.arguments == null) {
  359. return new FormalBinding[0];
  360. }
  361. if (mDecl.binding == null) {
  362. return new FormalBinding[0];
  363. }
  364. EclipseFactory factory = EclipseFactory.fromScopeLookupEnvironment(mDecl.scope);
  365. String extraArgName = "";// maybeGetExtraArgName();
  366. FormalBinding[] ret = new FormalBinding[mDecl.arguments.length];
  367. for (int i = 0; i < mDecl.arguments.length; i++) {
  368. Argument arg = mDecl.arguments[i];
  369. String name = new String(arg.name);
  370. TypeBinding argTypeBinding = mDecl.binding.parameters[i];
  371. UnresolvedType type = factory.fromBinding(argTypeBinding);
  372. if (CharOperation.equals(joinPoint, argTypeBinding.signature())
  373. || CharOperation.equals(joinPointStaticPart, argTypeBinding.signature())
  374. || CharOperation.equals(joinPointEnclosingStaticPart, argTypeBinding.signature())
  375. || CharOperation.equals(proceedingJoinPoint, argTypeBinding.signature()) || name.equals(extraArgName)) {
  376. ret[i] = new FormalBinding.ImplicitFormalBinding(type, name, i);
  377. } else {
  378. ret[i] = new FormalBinding(type, name, i, arg.sourceStart, arg.sourceEnd);
  379. }
  380. }
  381. return ret;
  382. }
  383. /**
  384. * This method may not return all fields, for example it may not include the ajc$initFailureCause or ajc$perSingletonInstance
  385. * fields - see bug 129613
  386. */
  387. public ResolvedMember[] getDeclaredFields() {
  388. if (declaredFields == null) {
  389. fillDeclaredMembers();
  390. }
  391. return declaredFields;
  392. }
  393. /**
  394. * This method may not return all methods, for example it may not include clinit, aspectOf, hasAspect or ajc$postClinit methods
  395. * - see bug 129613
  396. */
  397. public ResolvedMember[] getDeclaredMethods() {
  398. if (declaredMethods == null) {
  399. fillDeclaredMembers();
  400. }
  401. return declaredMethods;
  402. }
  403. public ResolvedMember[] getDeclaredPointcuts() {
  404. if (declaredPointcuts == null) {
  405. fillDeclaredMembers();
  406. }
  407. return declaredPointcuts;
  408. }
  409. public int getModifiers() {
  410. // only return the real Java modifiers, not the extra eclipse ones
  411. return binding.modifiers & ExtraCompilerModifiers.AccJustFlag;
  412. }
  413. public String toString() {
  414. return "EclipseSourceType(" + new String(binding.sourceName()) + ")";
  415. }
  416. // XXX make sure this is applied to classes and interfaces
  417. public void checkPointcutDeclarations() {
  418. ResolvedMember[] pointcuts = getDeclaredPointcuts();
  419. boolean sawError = false;
  420. for (int i = 0, len = pointcuts.length; i < len; i++) {
  421. if (pointcuts[i] == null) {
  422. // Something else is broken in this file and will be reported separately
  423. continue;
  424. }
  425. if (pointcuts[i].isAbstract()) {
  426. if (!this.isAspect()) {
  427. eclipseWorld().showMessage(IMessage.ERROR, "The abstract pointcut " + pointcuts[i].getName()+ " can only be defined in an aspect",
  428. pointcuts[i].getSourceLocation(), null);
  429. sawError = true;
  430. } else if (!binding.isAbstract()) {
  431. eclipseWorld().showMessage(IMessage.ERROR, "abstract pointcut in concrete aspect: " + pointcuts[i],
  432. pointcuts[i].getSourceLocation(), null);
  433. sawError = true;
  434. }
  435. }
  436. for (int j = i + 1; j < len; j++) {
  437. if (pointcuts[j] == null) {
  438. // Something else is broken in this file and will be reported separately
  439. continue;
  440. }
  441. if (pointcuts[i].getName().equals(pointcuts[j].getName())) {
  442. eclipseWorld().showMessage(IMessage.ERROR, "duplicate pointcut name: " + pointcuts[j].getName(),
  443. pointcuts[i].getSourceLocation(), pointcuts[j].getSourceLocation());
  444. sawError = true;
  445. }
  446. }
  447. }
  448. // now check all inherited pointcuts to be sure that they're handled
  449. // reasonably
  450. if (sawError || !isAspect()) {
  451. return;
  452. }
  453. // find all pointcuts that override ones from super and check override
  454. // is legal
  455. // i.e. same signatures and greater or equal visibility
  456. // find all inherited abstract pointcuts and make sure they're
  457. // concretized if I'm concrete
  458. // find all inherited pointcuts and make sure they don't conflict
  459. getResolvedTypeX().getExposedPointcuts(); // ??? this is an odd
  460. // construction
  461. }
  462. // ???
  463. // public CrosscuttingMembers collectCrosscuttingMembers() {
  464. // return crosscuttingMembers;
  465. // }
  466. // public ISourceLocation getSourceLocation() {
  467. // TypeDeclaration dec = binding.scope.referenceContext;
  468. // return new EclipseSourceLocation(dec.compilationResult, dec.sourceStart,
  469. // dec.sourceEnd);
  470. // }
  471. public boolean isInterface() {
  472. return binding.isInterface();
  473. }
  474. // XXXAJ5: Should be constants in the eclipse compiler somewhere, once it
  475. // supports 1.5
  476. public final static short ACC_ANNOTATION = 0x2000;
  477. public final static short ACC_ENUM = 0x4000;
  478. public boolean isEnum() {
  479. return (binding.getAccessFlags() & ACC_ENUM) != 0;
  480. }
  481. public boolean isAnnotation() {
  482. return (binding.getAccessFlags() & ACC_ANNOTATION) != 0;
  483. }
  484. public boolean isAnnotationWithRuntimeRetention() {
  485. if (!isAnnotation()) {
  486. return false;
  487. } else {
  488. return (binding.getAnnotationTagBits() & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
  489. }
  490. }
  491. public String getRetentionPolicy() {
  492. if (isAnnotation()) {
  493. if ((binding.getAnnotationTagBits() & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention) {
  494. return "RUNTIME";
  495. }
  496. if ((binding.getAnnotationTagBits() & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationSourceRetention) {
  497. return "SOURCE";
  498. }
  499. if ((binding.getAnnotationTagBits() & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention) {
  500. return "CLASS";
  501. }
  502. }
  503. return null;
  504. }
  505. public boolean canAnnotationTargetType() {
  506. if (isAnnotation()) {
  507. return ((binding.getAnnotationTagBits() & TagBits.AnnotationForType) != 0);
  508. }
  509. return false;
  510. }
  511. public AnnotationTargetKind[] getAnnotationTargetKinds() {
  512. if (discoveredAnnotationTargetKinds) {
  513. return annotationTargetKinds;
  514. }
  515. discoveredAnnotationTargetKinds = true;
  516. annotationTargetKinds = null; // null means we have no idea or the
  517. // @Target annotation hasn't been used
  518. // if (isAnnotation()) {
  519. // Annotation[] annotationsOnThisType = declaration.annotations;
  520. // if (annotationsOnThisType != null) {
  521. // for (int i = 0; i < annotationsOnThisType.length; i++) {
  522. // Annotation a = annotationsOnThisType[i];
  523. // if (a.resolvedType != null) {
  524. // String packageName = new
  525. // String(a.resolvedType.qualifiedPackageName()).concat(".");
  526. // String sourceName = new String(a.resolvedType.qualifiedSourceName());
  527. // if ((packageName +
  528. // sourceName).equals(UnresolvedType.AT_TARGET.getName())) {
  529. // MemberValuePair[] pairs = a.memberValuePairs();
  530. // for (int j = 0; j < pairs.length; j++) {
  531. // MemberValuePair pair = pairs[j];
  532. // targetKind = pair.value.toString();
  533. // return targetKind;
  534. // }
  535. // }
  536. // }
  537. // }
  538. // }
  539. // }
  540. // return targetKind;
  541. if (isAnnotation()) {
  542. List<AnnotationTargetKind> targetKinds = new ArrayList<AnnotationTargetKind>();
  543. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForAnnotationType) != 0) {
  544. targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE);
  545. }
  546. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForConstructor) != 0) {
  547. targetKinds.add(AnnotationTargetKind.CONSTRUCTOR);
  548. }
  549. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForField) != 0) {
  550. targetKinds.add(AnnotationTargetKind.FIELD);
  551. }
  552. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForLocalVariable) != 0) {
  553. targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE);
  554. }
  555. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForMethod) != 0) {
  556. targetKinds.add(AnnotationTargetKind.METHOD);
  557. }
  558. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForPackage) != 0) {
  559. targetKinds.add(AnnotationTargetKind.PACKAGE);
  560. }
  561. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForParameter) != 0) {
  562. targetKinds.add(AnnotationTargetKind.PARAMETER);
  563. }
  564. if ((binding.getAnnotationTagBits() & TagBits.AnnotationForType) != 0) {
  565. targetKinds.add(AnnotationTargetKind.TYPE);
  566. }
  567. if (!targetKinds.isEmpty()) {
  568. annotationTargetKinds = new AnnotationTargetKind[targetKinds.size()];
  569. return targetKinds.toArray(annotationTargetKinds);
  570. }
  571. }
  572. return annotationTargetKinds;
  573. }
  574. /**
  575. * Ensure the annotation types have been resolved, where resolved means the eclipse type bindings have been converted to their
  576. * ResolvedType representations. This does not deeply resolve the annotations, it only does the type names.
  577. */
  578. private void ensureAnnotationTypesResolved() {
  579. // may need to re-resolve if new annotations have been added
  580. int declarationAnnoCount = (declaration.annotations == null ? 0 : declaration.annotations.length);
  581. if (!annotationTypesAreResolved || declarationAnnoCount != annotationTypes.length) {
  582. Annotation[] as = declaration.annotations;
  583. if (as == null) {
  584. annotationTypes = ResolvedType.NONE;
  585. } else {
  586. annotationTypes = new ResolvedType[as.length];
  587. for (int a = 0; a < as.length; a++) {
  588. TypeBinding tb = as[a].type.resolveType(declaration.staticInitializerScope);
  589. if (tb == null) {
  590. annotationTypes[a] = ResolvedType.MISSING;
  591. } else {
  592. annotationTypes[a] = factory.fromTypeBindingToRTX(tb);
  593. }
  594. }
  595. }
  596. annotationTypesAreResolved = true;
  597. }
  598. }
  599. public boolean hasAnnotation(UnresolvedType ofType) {
  600. ensureAnnotationTypesResolved();
  601. for (int a = 0, max = annotationTypes.length; a < max; a++) {
  602. if (ofType.equals(annotationTypes[a])) {
  603. return true;
  604. }
  605. }
  606. return false;
  607. }
  608. /**
  609. * WARNING: This method does not have a complete implementation.
  610. *
  611. * The aim is that it converts Eclipse annotation objects to the AspectJ form of annotations (the type AnnotationAJ). The
  612. * AnnotationX objects returned are wrappers over either a Bcel annotation type or the AspectJ AnnotationAJ type. The minimal
  613. * implementation provided here is for processing the RetentionPolicy and Target annotation types - these are the only ones
  614. * which the weaver will attempt to process from an EclipseSourceType.
  615. *
  616. * More notes: The pipeline has required us to implement this. With the pipeline we can be weaving a type and asking questions
  617. * of annotations before they have been turned into Bcel objects - ie. when they are still in EclipseSourceType form. Without
  618. * the pipeline we would have converted everything to Bcel objects before proceeding with weaving. Because the pipeline won't
  619. * start weaving until all aspects have been compiled and the fact that no AspectJ constructs match on the values within
  620. * annotations, this code only needs to deal with converting system annotations that the weaver needs to process
  621. * (RetentionPolicy, Target).
  622. */
  623. public AnnotationAJ[] getAnnotations() {
  624. int declarationAnnoCount = (declaration.annotations == null ? 0 : declaration.annotations.length);
  625. if (annotations != null && annotations.length == declarationAnnoCount) {
  626. return annotations; // only do this once
  627. }
  628. if (!annotationsFullyResolved || annotations.length!=declarationAnnoCount) {
  629. TypeDeclaration.resolveAnnotations(declaration.staticInitializerScope, declaration.annotations, binding);
  630. annotationsFullyResolved = true;
  631. }
  632. Annotation[] as = declaration.annotations;
  633. if (as == null || as.length == 0) {
  634. annotations = AnnotationAJ.EMPTY_ARRAY;
  635. } else {
  636. annotations = new AnnotationAJ[as.length];
  637. for (int i = 0; i < as.length; i++) {
  638. annotations[i] = convertEclipseAnnotation(as[i], factory.getWorld());
  639. }
  640. }
  641. return annotations;
  642. }
  643. public boolean hasAnnotations() {
  644. return (declaration.annotations != null && declaration.annotations.length != 0);
  645. }
  646. /**
  647. * Convert one eclipse annotation into an AnnotationX object containing an AnnotationAJ object.
  648. *
  649. * This code and the helper methods used by it will go *BANG* if they encounter anything not currently supported - this is safer
  650. * than limping along with a malformed annotation. When the *BANG* is encountered the bug reporter should indicate the kind of
  651. * annotation they were working with and this code can be enhanced to support it.
  652. */
  653. public AnnotationAJ convertEclipseAnnotation(Annotation eclipseAnnotation, World w) {
  654. // TODO if it is sourcevisible, we shouldn't let it through!!!!!!!!!
  655. // testcase!
  656. ResolvedType annotationType = factory.fromTypeBindingToRTX(eclipseAnnotation.type.resolvedType);
  657. // long bs = (eclipseAnnotation.bits & TagBits.AnnotationRetentionMASK);
  658. boolean isRuntimeVisible = (eclipseAnnotation.bits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
  659. StandardAnnotation annotationAJ = new StandardAnnotation(annotationType, isRuntimeVisible);
  660. generateAnnotation(eclipseAnnotation, annotationAJ, w);
  661. return annotationAJ;
  662. }
  663. static class MissingImplementationException extends RuntimeException {
  664. MissingImplementationException(String reason) {
  665. super(reason);
  666. }
  667. }
  668. /**
  669. * Use the information in the supplied eclipse based annotation to fill in the standard annotation.
  670. *
  671. * @param annotation eclipse based annotation representation
  672. * @param annotationAJ AspectJ based annotation representation
  673. */
  674. private void generateAnnotation(Annotation annotation, StandardAnnotation annotationAJ, World w) {
  675. if (annotation instanceof NormalAnnotation) {
  676. NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
  677. MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
  678. if (memberValuePairs != null) {
  679. int memberValuePairsLength = memberValuePairs.length;
  680. for (int i = 0; i < memberValuePairsLength; i++) {
  681. MemberValuePair memberValuePair = memberValuePairs[i];
  682. MethodBinding methodBinding = memberValuePair.binding;
  683. if (methodBinding == null) {
  684. // is this just a marker annotation?
  685. if (memberValuePair.value instanceof MarkerAnnotation) {
  686. MarkerAnnotation eMarkerAnnotation = (MarkerAnnotation) memberValuePair.value;
  687. AnnotationBinding eMarkerAnnotationBinding = eMarkerAnnotation.getCompilerAnnotation();
  688. ReferenceBinding eAnnotationType = eMarkerAnnotationBinding.getAnnotationType();
  689. ResolvedType ajAnnotationType = factory.fromTypeBindingToRTX(eAnnotationType);
  690. boolean isRuntimeVisible = (eMarkerAnnotation.bits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
  691. StandardAnnotation ajAnnotation = new StandardAnnotation(ajAnnotationType, isRuntimeVisible);
  692. AnnotationValue av = new AnnotationAnnotationValue(ajAnnotation);
  693. AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), av);
  694. annotationAJ.addNameValuePair(anvp);
  695. // } else if (memberValuePair.value instanceof NormalAnnotation) {
  696. // NormalAnnotation eNormalAnnotation = (NormalAnnotation) memberValuePair.value;
  697. // AnnotationBinding eMarkerAnnotationBinding = eNormalAnnotation.getCompilerAnnotation();
  698. // ReferenceBinding eAnnotationType = eMarkerAnnotationBinding.getAnnotationType();
  699. // ResolvedType ajAnnotationType = factory.fromTypeBindingToRTX(eAnnotationType);
  700. // boolean isRuntimeVisible = (eNormalAnnotation.bits & TagBits.AnnotationRetentionMASK) ==
  701. // TagBits.AnnotationRuntimeRetention;
  702. // StandardAnnotation ajAnnotation = new StandardAnnotation(ajAnnotationType, isRuntimeVisible);
  703. // MemberValuePair[] pairs = eNormalAnnotation.memberValuePairs;
  704. // if (pairs != null) {
  705. // for (int p = 0; p < pairs.length; p++) {
  706. // MemberValuePair pair = pairs[p];
  707. // throw new IllegalStateException("nyi");
  708. //
  709. // }
  710. // }
  711. // AnnotationValue av = new AnnotationAnnotationValue(ajAnnotation);
  712. // AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), av);
  713. // annotationAJ.addNameValuePair(anvp);
  714. } else if (memberValuePair.value instanceof Literal) {
  715. AnnotationValue av = generateElementValue(memberValuePair.value,
  716. ((Literal) memberValuePair.value).resolvedType);
  717. AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), av);
  718. annotationAJ.addNameValuePair(anvp);
  719. } else if (memberValuePair.value instanceof ArrayInitializer) {
  720. ArrayInitializer arrayInitializer = (ArrayInitializer) memberValuePair.value;
  721. Expression[] expressions = arrayInitializer.expressions;
  722. AnnotationValue[] arrayValues = new AnnotationValue[expressions.length];
  723. for (int e = 0; e < expressions.length; e++) {
  724. arrayValues[e] = generateElementValue(expressions[e],
  725. ((ArrayBinding) arrayInitializer.resolvedType).leafComponentType);
  726. }
  727. AnnotationValue array = new ArrayAnnotationValue(arrayValues);
  728. AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), array);
  729. annotationAJ.addNameValuePair(anvp);
  730. } else {
  731. throw new MissingImplementationException(
  732. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation ["
  733. + annotation + "]");
  734. }
  735. } else {
  736. AnnotationValue av = generateElementValue(memberValuePair.value, methodBinding.returnType);
  737. AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(memberValuePair.name), av);
  738. annotationAJ.addNameValuePair(anvp);
  739. }
  740. }
  741. }
  742. } else if (annotation instanceof SingleMemberAnnotation) {
  743. // this is a single member annotation (one member value)
  744. SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation;
  745. MemberValuePair mvp = singleMemberAnnotation.memberValuePairs()[0];
  746. if (mvp.value instanceof ArrayInitializer) {
  747. ArrayInitializer arrayInitializer = (ArrayInitializer) mvp.value;
  748. Expression[] expressions = arrayInitializer.expressions;
  749. AnnotationValue[] arrayValues = new AnnotationValue[expressions.length];
  750. for (int e = 0; e < expressions.length; e++) {
  751. arrayValues[e] = generateElementValue(expressions[e],
  752. ((ArrayBinding) arrayInitializer.resolvedType).leafComponentType);
  753. }
  754. AnnotationValue array = new ArrayAnnotationValue(arrayValues);
  755. AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(mvp.name), array);
  756. annotationAJ.addNameValuePair(anvp);
  757. } else if (mvp.value instanceof Literal) {
  758. AnnotationValue av = generateElementValue(mvp.value,
  759. ((Literal) mvp.value).resolvedType);
  760. AnnotationNameValuePair anvp = new AnnotationNameValuePair(new String(mvp.name), av);
  761. annotationAJ.addNameValuePair(anvp);
  762. } else {
  763. MethodBinding methodBinding = mvp.binding;
  764. if (methodBinding == null) {
  765. throw new MissingImplementationException(
  766. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
  767. } else {
  768. AnnotationValue av = generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType);
  769. annotationAJ.addNameValuePair(new AnnotationNameValuePair(new String(
  770. singleMemberAnnotation.memberValuePairs()[0].name), av));
  771. }
  772. }
  773. } else if (annotation instanceof MarkerAnnotation) {
  774. return;
  775. } else {
  776. // this is something else...
  777. throw new MissingImplementationException(
  778. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
  779. }
  780. }
  781. private AnnotationValue generateElementValue(Expression defaultValue, TypeBinding memberValuePairReturnType) {
  782. Constant constant = defaultValue.constant;
  783. TypeBinding defaultValueBinding = defaultValue.resolvedType;
  784. if (defaultValueBinding == null) {
  785. throw new MissingImplementationException(
  786. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  787. + "]");
  788. } else {
  789. if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) {
  790. if (constant != null && constant != Constant.NotAConstant) {
  791. // Testcase for this clause is MultiProjectIncrementalTests.testAnnotations_pr262154()
  792. AnnotationValue av = EclipseAnnotationConvertor.generateElementValueForConstantExpression(defaultValue,
  793. defaultValueBinding);
  794. return new ArrayAnnotationValue(new AnnotationValue[] { av });
  795. } else {
  796. AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
  797. return new ArrayAnnotationValue(new AnnotationValue[] { av });
  798. }
  799. } else {
  800. if (constant != null && constant != Constant.NotAConstant) {
  801. AnnotationValue av = EclipseAnnotationConvertor.generateElementValueForConstantExpression(defaultValue,
  802. defaultValueBinding);
  803. if (av == null) {
  804. throw new MissingImplementationException(
  805. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  806. + defaultValue + "]");
  807. }
  808. return av;
  809. // generateElementValue(attributeOffset, defaultValue,
  810. // constant, memberValuePairReturnType.leafComponentType());
  811. } else {
  812. AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
  813. return av;
  814. }
  815. }
  816. }
  817. }
  818. private AnnotationValue generateElementValueForNonConstantExpression(Expression defaultValue, TypeBinding defaultValueBinding) {
  819. if (defaultValueBinding != null) {
  820. if (defaultValueBinding.isEnum()) {
  821. FieldBinding fieldBinding = null;
  822. if (defaultValue instanceof QualifiedNameReference) {
  823. QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
  824. fieldBinding = (FieldBinding) nameReference.binding;
  825. } else if (defaultValue instanceof SingleNameReference) {
  826. SingleNameReference nameReference = (SingleNameReference) defaultValue;
  827. fieldBinding = (FieldBinding) nameReference.binding;
  828. } else {
  829. throw new MissingImplementationException(
  830. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  831. + defaultValue + "]");
  832. }
  833. if (fieldBinding != null) {
  834. String sig = new String(fieldBinding.type.signature());
  835. AnnotationValue enumValue = new EnumAnnotationValue(sig, new String(fieldBinding.name));
  836. return enumValue;
  837. }
  838. throw new MissingImplementationException(
  839. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  840. + "]");
  841. } else if (defaultValue instanceof ClassLiteralAccess) {
  842. ClassLiteralAccess cla = (ClassLiteralAccess)defaultValue;
  843. TypeBinding claTargetType = cla.targetType;
  844. // ResolvedType classLiteralType = factory.fromTypeBindingToRTX(defaultValueBinding);
  845. String classLiteralSig = new String(claTargetType.signature());
  846. AnnotationValue classValue = new ClassAnnotationValue(classLiteralSig);
  847. return classValue;
  848. } else if (defaultValueBinding.isAnnotationType()) {
  849. if (defaultValue instanceof MarkerAnnotation) {
  850. ResolvedType ajAnnotationType = factory.fromTypeBindingToRTX(defaultValueBinding);
  851. StandardAnnotation ajAnnotation = new StandardAnnotation(ajAnnotationType,
  852. ajAnnotationType.isAnnotationWithRuntimeRetention());
  853. AnnotationValue av = new AnnotationAnnotationValue(ajAnnotation);
  854. return av;
  855. } else if (defaultValue instanceof NormalAnnotation) {
  856. NormalAnnotation normalAnnotation = (NormalAnnotation) defaultValue;
  857. ResolvedType ajAnnotationType = factory.fromTypeBindingToRTX(defaultValueBinding);
  858. StandardAnnotation ajAnnotation = new StandardAnnotation(ajAnnotationType,
  859. ajAnnotationType.isAnnotationWithRuntimeRetention());
  860. MemberValuePair[] pairs = normalAnnotation.memberValuePairs;
  861. if (pairs != null) {
  862. for (int p = 0; p < pairs.length; p++) {
  863. MemberValuePair pair = pairs[p];
  864. Expression valueEx = pair.value;
  865. AnnotationValue pairValue = null;
  866. if (valueEx instanceof Literal) {
  867. pairValue = generateElementValue(valueEx, ((Literal) valueEx).resolvedType);
  868. } else {
  869. pairValue = generateElementValue(pair.value, pair.binding.returnType);
  870. }
  871. ajAnnotation.addNameValuePair(new AnnotationNameValuePair(new String(pair.name), pairValue));
  872. }
  873. }
  874. AnnotationValue av = new AnnotationAnnotationValue(ajAnnotation);
  875. return av;
  876. } else {
  877. throw new MissingImplementationException(
  878. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  879. + defaultValue + "]");
  880. }
  881. } else if (defaultValueBinding.isArrayType()) {
  882. // array type
  883. if (defaultValue instanceof ArrayInitializer) {
  884. ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
  885. int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0;
  886. AnnotationValue[] values = new AnnotationValue[arrayLength];
  887. for (int i = 0; i < arrayLength; i++) {
  888. values[i] = generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType());// ,
  889. // attributeOffset
  890. // )
  891. // ;
  892. }
  893. ArrayAnnotationValue aav = new ArrayAnnotationValue(values);
  894. return aav;
  895. } else {
  896. throw new MissingImplementationException(
  897. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  898. + defaultValue + "]");
  899. }
  900. // } else if (defaultValue instanceof MagicLiteral) {
  901. // if (defaultValue instanceof FalseLiteral) {
  902. // new AnnotationValue
  903. // } else if (defaultValue instanceof TrueLiteral) {
  904. //
  905. // } else {
  906. // throw new MissingImplementationException(
  907. // "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  908. // +defaultValue+"]");
  909. // }
  910. } else {
  911. // class type
  912. throw new MissingImplementationException(
  913. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  914. + "]");
  915. // if (contentsOffset + 3 >= this.contents.length) {
  916. // resizeContents(3);
  917. // }
  918. // contents[contentsOffset++] = (byte) 'c';
  919. // if (defaultValue instanceof ClassLiteralAccess) {
  920. // ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess)
  921. // defaultValue;
  922. // final int classInfoIndex =
  923. // constantPool.literalIndex(classLiteralAccess
  924. // .targetType.signature());
  925. // contents[contentsOffset++] = (byte) (classInfoIndex >> 8);
  926. // contents[contentsOffset++] = (byte) classInfoIndex;
  927. // } else {
  928. // contentsOffset = attributeOffset;
  929. // }
  930. }
  931. } else {
  932. throw new MissingImplementationException(
  933. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  934. + "]");
  935. // contentsOffset = attributeOffset;
  936. }
  937. }
  938. public ResolvedType[] getAnnotationTypes() {
  939. ensureAnnotationTypesResolved();
  940. return annotationTypes;
  941. }
  942. public PerClause getPerClause() {
  943. // should probably be: ((AspectDeclaration)declaration).perClause;
  944. // but we don't need this level of detail, and working with real per
  945. // clauses
  946. // at this stage of compilation is not worth the trouble
  947. if (!isAnnotationStyleAspect()) {
  948. if (declaration instanceof AspectDeclaration) {
  949. PerClause pc = ((AspectDeclaration) declaration).perClause;
  950. if (pc != null) {
  951. return pc;
  952. }
  953. }
  954. return new PerSingleton();
  955. } else {
  956. // for @Aspect, we do need the real kind though we don't need the
  957. // real perClause
  958. // at least try to get the right perclause
  959. PerClause pc = null;
  960. if (declaration instanceof AspectDeclaration) {
  961. pc = ((AspectDeclaration) declaration).perClause;
  962. }
  963. if (pc == null) {
  964. PerClause.Kind kind = getPerClauseForTypeDeclaration(declaration);
  965. // returning a perFromSuper is enough to get the correct kind..
  966. // (that's really a hack - AV)
  967. return new PerFromSuper(kind);
  968. }
  969. return pc;
  970. }
  971. }
  972. PerClause.Kind getPerClauseForTypeDeclaration(TypeDeclaration typeDeclaration) {
  973. Annotation[] annotations = typeDeclaration.annotations;
  974. if (annotations == null) {
  975. // Can happen if an aspect is extending a regular class
  976. return null;
  977. }
  978. for (int i = 0; i < annotations.length; i++) {
  979. Annotation annotation = annotations[i];
  980. if (annotation != null && annotation.resolvedType != null
  981. && CharOperation.equals(aspectSig, annotation.resolvedType.signature())) {
  982. // found @Aspect(...)
  983. if (annotation.memberValuePairs() == null || annotation.memberValuePairs().length == 0) {
  984. // it is an @Aspect or @Aspect()
  985. // needs to use PerFromSuper if declaration extends a super
  986. // aspect
  987. PerClause.Kind kind = lookupPerClauseKind(typeDeclaration.binding.superclass);
  988. // if no super aspect, we have a @Aspect() means singleton
  989. if (kind == null) {
  990. return PerClause.SINGLETON;
  991. } else {
  992. return kind;
  993. }
  994. } else if (annotation instanceof SingleMemberAnnotation) {
  995. // it is an @Aspect(...something...)
  996. SingleMemberAnnotation theAnnotation = (SingleMemberAnnotation) annotation;
  997. String clause = new String(((StringLiteral) theAnnotation.memberValue).source());// TODO
  998. // cast
  999. // safe
  1000. // ?
  1001. return determinePerClause(typeDeclaration, clause);
  1002. } else if (annotation instanceof NormalAnnotation) {
  1003. // this kind if it was added by the visitor!
  1004. // it is an @Aspect(...something...)
  1005. NormalAnnotation theAnnotation = (NormalAnnotation) annotation;
  1006. if (theAnnotation.memberValuePairs == null || theAnnotation.memberValuePairs.length < 1) {
  1007. return PerClause.SINGLETON;
  1008. }
  1009. String clause = new String(((StringLiteral) theAnnotation.memberValuePairs[0].value).source());// TODO
  1010. // cast
  1011. // safe
  1012. // ?
  1013. return determinePerClause(typeDeclaration, clause);
  1014. } else {
  1015. eclipseWorld().showMessage(
  1016. IMessage.ABORT,
  1017. "@Aspect annotation is expected to be SingleMemberAnnotation with 'String value()' as unique element",
  1018. new EclipseSourceLocation(typeDeclaration.compilationResult, typeDeclaration.sourceStart,
  1019. typeDeclaration.sourceEnd), null);
  1020. return PerClause.SINGLETON;// fallback strategy just to avoid NPE
  1021. }
  1022. }
  1023. }
  1024. return null;// no @Aspect annotation at all (not as aspect)
  1025. }
  1026. private PerClause.Kind determinePerClause(TypeDeclaration typeDeclaration, String clause) {
  1027. if (clause.startsWith("perthis(")) {
  1028. return PerClause.PEROBJECT;
  1029. } else if (clause.startsWith("pertarget(")) {
  1030. return PerClause.PEROBJECT;
  1031. } else if (clause.startsWith("percflow(")) {
  1032. return PerClause.PERCFLOW;
  1033. } else if (clause.startsWith("percflowbelow(")) {
  1034. return PerClause.PERCFLOW;
  1035. } else if (clause.startsWith("pertypewithin(")) {
  1036. return PerClause.PERTYPEWITHIN;
  1037. } else if (clause.startsWith("issingleton(")) {
  1038. return PerClause.SINGLETON;
  1039. } else {
  1040. eclipseWorld().showMessage(
  1041. IMessage.ABORT,
  1042. "cannot determine perClause '" + clause + "'",
  1043. new EclipseSourceLocation(typeDeclaration.compilationResult, typeDeclaration.sourceStart,
  1044. typeDeclaration.sourceEnd), null);
  1045. return PerClause.SINGLETON;// fallback strategy just to avoid NPE
  1046. }
  1047. }
  1048. // adapted from AspectDeclaration
  1049. private PerClause.Kind lookupPerClauseKind(ReferenceBinding binding) {
  1050. final PerClause.Kind kind;
  1051. if (binding instanceof BinaryTypeBinding) {
  1052. ResolvedType superTypeX = factory.fromEclipse(binding);
  1053. PerClause perClause = superTypeX.getPerClause();
  1054. // clause is null for non aspect classes since coming from BCEL
  1055. // attributes
  1056. if (perClause != null) {
  1057. kind = superTypeX.getPerClause().getKind();
  1058. } else {
  1059. kind = null;
  1060. }
  1061. } else if (binding instanceof SourceTypeBinding) {
  1062. SourceTypeBinding sourceSc = (SourceTypeBinding) binding;
  1063. if (sourceSc.scope.referenceContext instanceof AspectDeclaration) {
  1064. // code style
  1065. kind = ((AspectDeclaration) sourceSc.scope.referenceContext).perClause.getKind();
  1066. } else { // if (sourceSc.scope.referenceContext instanceof
  1067. // TypeDeclaration) {
  1068. // if @Aspect: perFromSuper, else if @Aspect(..) get from anno
  1069. // value, else null
  1070. kind = getPerClauseForTypeDeclaration((sourceSc.scope.referenceContext));
  1071. }
  1072. } else {
  1073. // XXX need to handle this too
  1074. kind = null;
  1075. }
  1076. return kind;
  1077. }
  1078. public Collection getDeclares() {
  1079. return declares;
  1080. }
  1081. public Collection getPrivilegedAccesses() {
  1082. return Collections.EMPTY_LIST;
  1083. }
  1084. public Collection getTypeMungers() {
  1085. return typeMungers;
  1086. }
  1087. public boolean doesNotExposeShadowMungers() {
  1088. return true;
  1089. }
  1090. public String getDeclaredGenericSignature() {
  1091. return CharOperation.charToString(binding.genericSignature());
  1092. }
  1093. public boolean isGeneric() {
  1094. return binding.isGenericType();
  1095. }
  1096. public TypeVariable[] getTypeVariables() {
  1097. if (declaration.typeParameters == null) {
  1098. return new TypeVariable[0];
  1099. }
  1100. TypeVariable[] typeVariables = new TypeVariable[declaration.typeParameters.length];
  1101. for (int i = 0; i < typeVariables.length; i++) {
  1102. typeVariables[i] = typeParameter2TypeVariable(declaration.typeParameters[i]);
  1103. }
  1104. return typeVariables;
  1105. }
  1106. private TypeVariable typeParameter2TypeVariable(TypeParameter typeParameter) {
  1107. String name = new String(typeParameter.name);
  1108. ReferenceBinding superclassBinding = typeParameter.binding.superclass;
  1109. UnresolvedType superclass = UnresolvedType.forSignature(new String(superclassBinding.signature()));
  1110. UnresolvedType[] superinterfaces = null;
  1111. ReferenceBinding[] superInterfaceBindings = typeParameter.binding.superInterfaces;
  1112. if (superInterfaceBindings != null) {
  1113. superinterfaces = new UnresolvedType[superInterfaceBindings.length];
  1114. for (int i = 0; i < superInterfaceBindings.length; i++) {
  1115. superinterfaces[i] = UnresolvedType.forSignature(new String(superInterfaceBindings[i].signature()));
  1116. }
  1117. }
  1118. // XXX what about lower binding?
  1119. TypeVariable tv = new TypeVariable(name, superclass, superinterfaces);
  1120. tv.setDeclaringElement(factory.fromBinding(typeParameter.binding.declaringElement));
  1121. tv.setRank(typeParameter.binding.rank);
  1122. return tv;
  1123. }
  1124. }