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 49KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  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, "abstract pointcut only allowed in aspect" + pointcuts[i].getName(),
  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 {
  758. MethodBinding methodBinding = mvp.binding;
  759. if (methodBinding == null) {
  760. throw new MissingImplementationException(
  761. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
  762. } else {
  763. AnnotationValue av = generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType);
  764. annotationAJ.addNameValuePair(new AnnotationNameValuePair(new String(
  765. singleMemberAnnotation.memberValuePairs()[0].name), av));
  766. }
  767. }
  768. } else if (annotation instanceof MarkerAnnotation) {
  769. return;
  770. } else {
  771. // this is something else...
  772. throw new MissingImplementationException(
  773. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation [" + annotation + "]");
  774. }
  775. }
  776. private AnnotationValue generateElementValue(Expression defaultValue, TypeBinding memberValuePairReturnType) {
  777. Constant constant = defaultValue.constant;
  778. TypeBinding defaultValueBinding = defaultValue.resolvedType;
  779. if (defaultValueBinding == null) {
  780. throw new MissingImplementationException(
  781. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  782. + "]");
  783. } else {
  784. if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) {
  785. if (constant != null && constant != Constant.NotAConstant) {
  786. // Testcase for this clause is MultiProjectIncrementalTests.testAnnotations_pr262154()
  787. AnnotationValue av = EclipseAnnotationConvertor.generateElementValueForConstantExpression(defaultValue,
  788. defaultValueBinding);
  789. return new ArrayAnnotationValue(new AnnotationValue[] { av });
  790. } else {
  791. AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
  792. return new ArrayAnnotationValue(new AnnotationValue[] { av });
  793. }
  794. } else {
  795. if (constant != null && constant != Constant.NotAConstant) {
  796. AnnotationValue av = EclipseAnnotationConvertor.generateElementValueForConstantExpression(defaultValue,
  797. defaultValueBinding);
  798. if (av == null) {
  799. throw new MissingImplementationException(
  800. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  801. + defaultValue + "]");
  802. }
  803. return av;
  804. // generateElementValue(attributeOffset, defaultValue,
  805. // constant, memberValuePairReturnType.leafComponentType());
  806. } else {
  807. AnnotationValue av = generateElementValueForNonConstantExpression(defaultValue, defaultValueBinding);
  808. return av;
  809. }
  810. }
  811. }
  812. }
  813. private AnnotationValue generateElementValueForNonConstantExpression(Expression defaultValue, TypeBinding defaultValueBinding) {
  814. if (defaultValueBinding != null) {
  815. if (defaultValueBinding.isEnum()) {
  816. FieldBinding fieldBinding = null;
  817. if (defaultValue instanceof QualifiedNameReference) {
  818. QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
  819. fieldBinding = (FieldBinding) nameReference.binding;
  820. } else if (defaultValue instanceof SingleNameReference) {
  821. SingleNameReference nameReference = (SingleNameReference) defaultValue;
  822. fieldBinding = (FieldBinding) nameReference.binding;
  823. } else {
  824. throw new MissingImplementationException(
  825. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  826. + defaultValue + "]");
  827. }
  828. if (fieldBinding != null) {
  829. String sig = new String(fieldBinding.type.signature());
  830. AnnotationValue enumValue = new EnumAnnotationValue(sig, new String(fieldBinding.name));
  831. return enumValue;
  832. }
  833. throw new MissingImplementationException(
  834. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  835. + "]");
  836. } else if (defaultValue instanceof ClassLiteralAccess) {
  837. ClassLiteralAccess cla = (ClassLiteralAccess)defaultValue;
  838. TypeBinding claTargetType = cla.targetType;
  839. // ResolvedType classLiteralType = factory.fromTypeBindingToRTX(defaultValueBinding);
  840. String classLiteralSig = new String(claTargetType.signature());
  841. AnnotationValue classValue = new ClassAnnotationValue(classLiteralSig);
  842. return classValue;
  843. } else if (defaultValueBinding.isAnnotationType()) {
  844. if (defaultValue instanceof MarkerAnnotation) {
  845. ResolvedType ajAnnotationType = factory.fromTypeBindingToRTX(defaultValueBinding);
  846. StandardAnnotation ajAnnotation = new StandardAnnotation(ajAnnotationType,
  847. ajAnnotationType.isAnnotationWithRuntimeRetention());
  848. AnnotationValue av = new AnnotationAnnotationValue(ajAnnotation);
  849. return av;
  850. } else if (defaultValue instanceof NormalAnnotation) {
  851. NormalAnnotation normalAnnotation = (NormalAnnotation) defaultValue;
  852. ResolvedType ajAnnotationType = factory.fromTypeBindingToRTX(defaultValueBinding);
  853. StandardAnnotation ajAnnotation = new StandardAnnotation(ajAnnotationType,
  854. ajAnnotationType.isAnnotationWithRuntimeRetention());
  855. MemberValuePair[] pairs = normalAnnotation.memberValuePairs;
  856. if (pairs != null) {
  857. for (int p = 0; p < pairs.length; p++) {
  858. MemberValuePair pair = pairs[p];
  859. Expression valueEx = pair.value;
  860. AnnotationValue pairValue = null;
  861. if (valueEx instanceof Literal) {
  862. pairValue = generateElementValue(valueEx, ((Literal) valueEx).resolvedType);
  863. } else {
  864. pairValue = generateElementValue(pair.value, pair.binding.returnType);
  865. }
  866. ajAnnotation.addNameValuePair(new AnnotationNameValuePair(new String(pair.name), pairValue));
  867. }
  868. }
  869. AnnotationValue av = new AnnotationAnnotationValue(ajAnnotation);
  870. return av;
  871. } else {
  872. throw new MissingImplementationException(
  873. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  874. + defaultValue + "]");
  875. }
  876. } else if (defaultValueBinding.isArrayType()) {
  877. // array type
  878. if (defaultValue instanceof ArrayInitializer) {
  879. ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
  880. int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0;
  881. AnnotationValue[] values = new AnnotationValue[arrayLength];
  882. for (int i = 0; i < arrayLength; i++) {
  883. values[i] = generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType());// ,
  884. // attributeOffset
  885. // )
  886. // ;
  887. }
  888. ArrayAnnotationValue aav = new ArrayAnnotationValue(values);
  889. return aav;
  890. } else {
  891. throw new MissingImplementationException(
  892. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  893. + defaultValue + "]");
  894. }
  895. // } else if (defaultValue instanceof MagicLiteral) {
  896. // if (defaultValue instanceof FalseLiteral) {
  897. // new AnnotationValue
  898. // } else if (defaultValue instanceof TrueLiteral) {
  899. //
  900. // } else {
  901. // throw new MissingImplementationException(
  902. // "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value ["
  903. // +defaultValue+"]");
  904. // }
  905. } else {
  906. // class type
  907. throw new MissingImplementationException(
  908. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  909. + "]");
  910. // if (contentsOffset + 3 >= this.contents.length) {
  911. // resizeContents(3);
  912. // }
  913. // contents[contentsOffset++] = (byte) 'c';
  914. // if (defaultValue instanceof ClassLiteralAccess) {
  915. // ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess)
  916. // defaultValue;
  917. // final int classInfoIndex =
  918. // constantPool.literalIndex(classLiteralAccess
  919. // .targetType.signature());
  920. // contents[contentsOffset++] = (byte) (classInfoIndex >> 8);
  921. // contents[contentsOffset++] = (byte) classInfoIndex;
  922. // } else {
  923. // contentsOffset = attributeOffset;
  924. // }
  925. }
  926. } else {
  927. throw new MissingImplementationException(
  928. "Please raise an AspectJ bug. AspectJ does not know how to convert this annotation value [" + defaultValue
  929. + "]");
  930. // contentsOffset = attributeOffset;
  931. }
  932. }
  933. public ResolvedType[] getAnnotationTypes() {
  934. ensureAnnotationTypesResolved();
  935. return annotationTypes;
  936. }
  937. public PerClause getPerClause() {
  938. // should probably be: ((AspectDeclaration)declaration).perClause;
  939. // but we don't need this level of detail, and working with real per
  940. // clauses
  941. // at this stage of compilation is not worth the trouble
  942. if (!isAnnotationStyleAspect()) {
  943. if (declaration instanceof AspectDeclaration) {
  944. PerClause pc = ((AspectDeclaration) declaration).perClause;
  945. if (pc != null) {
  946. return pc;
  947. }
  948. }
  949. return new PerSingleton();
  950. } else {
  951. // for @Aspect, we do need the real kind though we don't need the
  952. // real perClause
  953. // at least try to get the right perclause
  954. PerClause pc = null;
  955. if (declaration instanceof AspectDeclaration) {
  956. pc = ((AspectDeclaration) declaration).perClause;
  957. }
  958. if (pc == null) {
  959. PerClause.Kind kind = getPerClauseForTypeDeclaration(declaration);
  960. // returning a perFromSuper is enough to get the correct kind..
  961. // (that's really a hack - AV)
  962. return new PerFromSuper(kind);
  963. }
  964. return pc;
  965. }
  966. }
  967. PerClause.Kind getPerClauseForTypeDeclaration(TypeDeclaration typeDeclaration) {
  968. Annotation[] annotations = typeDeclaration.annotations;
  969. if (annotations == null) {
  970. // Can happen if an aspect is extending a regular class
  971. return null;
  972. }
  973. for (int i = 0; i < annotations.length; i++) {
  974. Annotation annotation = annotations[i];
  975. if (annotation != null && annotation.resolvedType != null
  976. && CharOperation.equals(aspectSig, annotation.resolvedType.signature())) {
  977. // found @Aspect(...)
  978. if (annotation.memberValuePairs() == null || annotation.memberValuePairs().length == 0) {
  979. // it is an @Aspect or @Aspect()
  980. // needs to use PerFromSuper if declaration extends a super
  981. // aspect
  982. PerClause.Kind kind = lookupPerClauseKind(typeDeclaration.binding.superclass);
  983. // if no super aspect, we have a @Aspect() means singleton
  984. if (kind == null) {
  985. return PerClause.SINGLETON;
  986. } else {
  987. return kind;
  988. }
  989. } else if (annotation instanceof SingleMemberAnnotation) {
  990. // it is an @Aspect(...something...)
  991. SingleMemberAnnotation theAnnotation = (SingleMemberAnnotation) annotation;
  992. String clause = new String(((StringLiteral) theAnnotation.memberValue).source());// TODO
  993. // cast
  994. // safe
  995. // ?
  996. return determinePerClause(typeDeclaration, clause);
  997. } else if (annotation instanceof NormalAnnotation) {
  998. // this kind if it was added by the visitor!
  999. // it is an @Aspect(...something...)
  1000. NormalAnnotation theAnnotation = (NormalAnnotation) annotation;
  1001. if (theAnnotation.memberValuePairs == null || theAnnotation.memberValuePairs.length < 1) {
  1002. return PerClause.SINGLETON;
  1003. }
  1004. String clause = new String(((StringLiteral) theAnnotation.memberValuePairs[0].value).source());// TODO
  1005. // cast
  1006. // safe
  1007. // ?
  1008. return determinePerClause(typeDeclaration, clause);
  1009. } else {
  1010. eclipseWorld().showMessage(
  1011. IMessage.ABORT,
  1012. "@Aspect annotation is expected to be SingleMemberAnnotation with 'String value()' as unique element",
  1013. new EclipseSourceLocation(typeDeclaration.compilationResult, typeDeclaration.sourceStart,
  1014. typeDeclaration.sourceEnd), null);
  1015. return PerClause.SINGLETON;// fallback strategy just to avoid NPE
  1016. }
  1017. }
  1018. }
  1019. return null;// no @Aspect annotation at all (not as aspect)
  1020. }
  1021. private PerClause.Kind determinePerClause(TypeDeclaration typeDeclaration, String clause) {
  1022. if (clause.startsWith("perthis(")) {
  1023. return PerClause.PEROBJECT;
  1024. } else if (clause.startsWith("pertarget(")) {
  1025. return PerClause.PEROBJECT;
  1026. } else if (clause.startsWith("percflow(")) {
  1027. return PerClause.PERCFLOW;
  1028. } else if (clause.startsWith("percflowbelow(")) {
  1029. return PerClause.PERCFLOW;
  1030. } else if (clause.startsWith("pertypewithin(")) {
  1031. return PerClause.PERTYPEWITHIN;
  1032. } else if (clause.startsWith("issingleton(")) {
  1033. return PerClause.SINGLETON;
  1034. } else {
  1035. eclipseWorld().showMessage(
  1036. IMessage.ABORT,
  1037. "cannot determine perClause '" + clause + "'",
  1038. new EclipseSourceLocation(typeDeclaration.compilationResult, typeDeclaration.sourceStart,
  1039. typeDeclaration.sourceEnd), null);
  1040. return PerClause.SINGLETON;// fallback strategy just to avoid NPE
  1041. }
  1042. }
  1043. // adapted from AspectDeclaration
  1044. private PerClause.Kind lookupPerClauseKind(ReferenceBinding binding) {
  1045. final PerClause.Kind kind;
  1046. if (binding instanceof BinaryTypeBinding) {
  1047. ResolvedType superTypeX = factory.fromEclipse(binding);
  1048. PerClause perClause = superTypeX.getPerClause();
  1049. // clause is null for non aspect classes since coming from BCEL
  1050. // attributes
  1051. if (perClause != null) {
  1052. kind = superTypeX.getPerClause().getKind();
  1053. } else {
  1054. kind = null;
  1055. }
  1056. } else if (binding instanceof SourceTypeBinding) {
  1057. SourceTypeBinding sourceSc = (SourceTypeBinding) binding;
  1058. if (sourceSc.scope.referenceContext instanceof AspectDeclaration) {
  1059. // code style
  1060. kind = ((AspectDeclaration) sourceSc.scope.referenceContext).perClause.getKind();
  1061. } else { // if (sourceSc.scope.referenceContext instanceof
  1062. // TypeDeclaration) {
  1063. // if @Aspect: perFromSuper, else if @Aspect(..) get from anno
  1064. // value, else null
  1065. kind = getPerClauseForTypeDeclaration((sourceSc.scope.referenceContext));
  1066. }
  1067. } else {
  1068. // XXX need to handle this too
  1069. kind = null;
  1070. }
  1071. return kind;
  1072. }
  1073. public Collection getDeclares() {
  1074. return declares;
  1075. }
  1076. public Collection getPrivilegedAccesses() {
  1077. return Collections.EMPTY_LIST;
  1078. }
  1079. public Collection getTypeMungers() {
  1080. return typeMungers;
  1081. }
  1082. public boolean doesNotExposeShadowMungers() {
  1083. return true;
  1084. }
  1085. public String getDeclaredGenericSignature() {
  1086. return CharOperation.charToString(binding.genericSignature());
  1087. }
  1088. public boolean isGeneric() {
  1089. return binding.isGenericType();
  1090. }
  1091. public TypeVariable[] getTypeVariables() {
  1092. if (declaration.typeParameters == null) {
  1093. return new TypeVariable[0];
  1094. }
  1095. TypeVariable[] typeVariables = new TypeVariable[declaration.typeParameters.length];
  1096. for (int i = 0; i < typeVariables.length; i++) {
  1097. typeVariables[i] = typeParameter2TypeVariable(declaration.typeParameters[i]);
  1098. }
  1099. return typeVariables;
  1100. }
  1101. private TypeVariable typeParameter2TypeVariable(TypeParameter typeParameter) {
  1102. String name = new String(typeParameter.name);
  1103. ReferenceBinding superclassBinding = typeParameter.binding.superclass;
  1104. UnresolvedType superclass = UnresolvedType.forSignature(new String(superclassBinding.signature()));
  1105. UnresolvedType[] superinterfaces = null;
  1106. ReferenceBinding[] superInterfaceBindings = typeParameter.binding.superInterfaces;
  1107. if (superInterfaceBindings != null) {
  1108. superinterfaces = new UnresolvedType[superInterfaceBindings.length];
  1109. for (int i = 0; i < superInterfaceBindings.length; i++) {
  1110. superinterfaces[i] = UnresolvedType.forSignature(new String(superInterfaceBindings[i].signature()));
  1111. }
  1112. }
  1113. // XXX what about lower binding?
  1114. TypeVariable tv = new TypeVariable(name, superclass, superinterfaces);
  1115. tv.setDeclaringElement(factory.fromBinding(typeParameter.binding.declaringElement));
  1116. tv.setRank(typeParameter.binding.rank);
  1117. return tv;
  1118. }
  1119. }