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

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