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.

AsmHierarchyBuilder.java 46KB

21 years ago
21 years ago
16 years ago
21 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
16 years ago
21 years ago
21 years ago
13 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
15 years ago
15 years ago
15 years ago
21 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
15 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
13 years ago
14 years ago
14 years ago
12 years ago
12 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
14 years ago
13 years ago
13 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
21 years ago
21 years ago
21 years ago
14 years ago
14 years ago
14 years ago
14 years ago
21 years ago
21 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  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. * Mik Kersten revisions, added additional relationships
  12. * Alexandre Vasseur support for @AJ style
  13. * ******************************************************************/
  14. package org.aspectj.ajdt.internal.core.builder;
  15. import java.io.File;
  16. import java.io.IOException;
  17. import java.util.ArrayList;
  18. import java.util.Arrays;
  19. import java.util.List;
  20. import java.util.ListIterator;
  21. import java.util.Stack;
  22. import java.util.StringTokenizer;
  23. import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager;
  24. import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
  25. import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
  26. import org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration;
  27. import org.aspectj.ajdt.internal.compiler.ast.InterTypeDeclaration;
  28. import org.aspectj.ajdt.internal.compiler.ast.InterTypeFieldDeclaration;
  29. import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
  30. import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
  31. import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
  32. import org.aspectj.asm.AsmManager;
  33. import org.aspectj.asm.IProgramElement;
  34. import org.aspectj.asm.internal.CharOperation;
  35. import org.aspectj.asm.internal.ProgramElement;
  36. import org.aspectj.bridge.ISourceLocation;
  37. import org.aspectj.bridge.SourceLocation;
  38. import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor;
  39. import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
  40. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
  41. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  42. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
  43. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
  44. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
  45. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
  46. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
  47. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ImportReference;
  48. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Initializer;
  49. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Literal;
  50. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
  51. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.OperatorExpression;
  52. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Reference;
  53. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  54. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeParameter;
  55. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
  56. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
  57. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
  58. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodScope;
  59. import org.aspectj.org.eclipse.jdt.internal.compiler.util.Util;
  60. import org.aspectj.util.LangUtil;
  61. import org.aspectj.weaver.BCException;
  62. import org.aspectj.weaver.Member;
  63. import org.aspectj.weaver.ResolvedMember;
  64. import org.aspectj.weaver.ResolvedType;
  65. import org.aspectj.weaver.UnresolvedType;
  66. import org.aspectj.weaver.World;
  67. import org.aspectj.weaver.patterns.AndPointcut;
  68. import org.aspectj.weaver.patterns.Declare;
  69. import org.aspectj.weaver.patterns.DeclareAnnotation;
  70. import org.aspectj.weaver.patterns.DeclareParents;
  71. import org.aspectj.weaver.patterns.OrPointcut;
  72. import org.aspectj.weaver.patterns.Pointcut;
  73. import org.aspectj.weaver.patterns.ReferencePointcut;
  74. import org.aspectj.weaver.patterns.TypePatternList;
  75. /**
  76. * At each iteration of <CODE>processCompilationUnit</CODE> the declarations for a particular compilation unit are added to the
  77. * hierarchy passed as a a parameter.
  78. * <p>
  79. * Clients who extend this class need to ensure that they do not override any of the existing behavior. If they do, the structure
  80. * model will not be built properly and tools such as IDE structure views and ajdoc will fail.
  81. * <p>
  82. * <b>Note:</b> this class is not considered public API and the overridable methods are subject to change.
  83. *
  84. * @author Mik Kersten
  85. */
  86. public class AsmHierarchyBuilder extends ASTVisitor {
  87. protected AsmElementFormatter formatter = new AsmElementFormatter();
  88. // pr148027 - stop generating uses pointcut/pointcut used by relationship
  89. // until we do it in the same way as other relationships.
  90. // public static boolean shouldAddUsesPointcut = false;
  91. /**
  92. * Reset for every compilation unit.
  93. */
  94. protected AjBuildConfig buildConfig;
  95. /**
  96. * Reset for every compilation unit.
  97. */
  98. protected Stack<IProgramElement> stack;
  99. protected ImportReference packageDecl = null;
  100. /**
  101. * Reset for every compilation unit.
  102. */
  103. private CompilationResult currCompilationResult;
  104. private String filename;
  105. int[] lineseps;
  106. /**
  107. *
  108. * @param cuDeclaration
  109. * @param buildConfig
  110. * @param structureModel
  111. * hiearchy to add this unit's declarations to
  112. */
  113. public void buildStructureForCompilationUnit(CompilationUnitDeclaration cuDeclaration, AsmManager structureModel,
  114. AjBuildConfig buildConfig) {
  115. currCompilationResult = cuDeclaration.compilationResult();
  116. filename = new String(currCompilationResult.fileName);
  117. lineseps = currCompilationResult.lineSeparatorPositions;
  118. LangUtil.throwIaxIfNull(currCompilationResult, "result");
  119. stack = new Stack();
  120. packageDecl = null;
  121. this.buildConfig = buildConfig;
  122. internalBuild(cuDeclaration, structureModel);
  123. this.buildConfig = null; // clear reference since this structure is
  124. // anchored in static
  125. currCompilationResult = null;
  126. stack.clear();
  127. // throw new RuntimeException("not implemented");
  128. }
  129. private void internalBuild(CompilationUnitDeclaration unit, AsmManager structureModel) {
  130. LangUtil.throwIaxIfNull(structureModel, "structureModel");
  131. try {
  132. activeStructureModel = structureModel;
  133. // if (!currCompilationResult.equals(unit.compilationResult())) {
  134. // throw new IllegalArgumentException("invalid unit: " + unit);
  135. // }
  136. // ---- summary
  137. // add unit to package (or root if no package),
  138. // first removing any duplicate (XXX? removes children if 3 classes in
  139. // same file?)
  140. // push the node on the stack
  141. // and traverse
  142. // -- create node to add
  143. final File file = new File(new String(unit.getFileName()));
  144. final IProgramElement cuNode;
  145. {
  146. // AMC - use the source start and end from the compilation unit decl
  147. int startLine = getStartLine(unit);
  148. int endLine = getEndLine(unit);
  149. SourceLocation sourceLocation = new SourceLocation(file, startLine, endLine);
  150. sourceLocation.setOffset(unit.sourceStart);
  151. cuNode = new ProgramElement(structureModel, new String(file.getName()), IProgramElement.Kind.FILE_JAVA,
  152. sourceLocation, 0, null, null);
  153. }
  154. // container for import declarations - this may move to position 1 in the child list, if there
  155. // is a package declaration
  156. cuNode.addChild(new ProgramElement(structureModel, "", IProgramElement.Kind.IMPORT_REFERENCE, null, 0, null, null));
  157. final IProgramElement addToNode = genAddToNode(file, unit, structureModel);
  158. // -- remove duplicates before adding (XXX use them instead?)
  159. if (addToNode != null && addToNode.getChildren() != null) {
  160. for (ListIterator itt = addToNode.getChildren().listIterator(); itt.hasNext();) {
  161. IProgramElement child = (IProgramElement) itt.next();
  162. ISourceLocation childLoc = child.getSourceLocation();
  163. if (null == childLoc) {
  164. // XXX ok, packages have null source locations
  165. // signal others?
  166. } else if (childLoc.getSourceFile().equals(file)) {
  167. itt.remove();
  168. }
  169. }
  170. }
  171. // -- add and traverse
  172. addToNode.addChild(cuNode);
  173. stack.push(cuNode);
  174. unit.traverse(this, unit.scope);
  175. // -- update file map (XXX do this before traversal?)
  176. try {
  177. structureModel.getHierarchy().addToFileMap(file.getCanonicalPath(), cuNode);
  178. } catch (IOException e) {
  179. System.err.println("IOException " + e.getMessage() + " creating path for " + file);
  180. // XXX signal IOException when canonicalizing file path
  181. }
  182. } finally {
  183. activeStructureModel = null;
  184. }
  185. }
  186. private AsmManager activeStructureModel = null;
  187. private IProgramElement findOrCreateChildSourceFolder(String sourceFolder, AsmManager structureModel) {
  188. IProgramElement root = structureModel.getHierarchy().getRoot();
  189. // Check if already there
  190. IProgramElement sourceFolderNode = null;
  191. List<IProgramElement> kids = root.getChildren();
  192. for (IProgramElement child : kids) {
  193. if (child.getKind() == IProgramElement.Kind.SOURCE_FOLDER && child.getName().equals(sourceFolder)) {
  194. sourceFolderNode = child;
  195. break;
  196. }
  197. }
  198. if (sourceFolderNode == null) {
  199. sourceFolderNode = new ProgramElement(structureModel, sourceFolder, IProgramElement.Kind.SOURCE_FOLDER, new ArrayList());
  200. root.addChild(sourceFolderNode);
  201. }
  202. return sourceFolderNode;
  203. }
  204. /**
  205. * Get/create the node (package or root) to add to.
  206. */
  207. private IProgramElement genAddToNode(File sourceFile, CompilationUnitDeclaration unit, AsmManager structureModel) {
  208. final IProgramElement addToNode;
  209. {
  210. CompilationResultDestinationManager manager = buildConfig.getCompilationResultDestinationManager();
  211. String sourceFolder = (manager == null ? null : manager.getSourceFolderForFile(sourceFile));
  212. ImportReference unitPackage = unit.currentPackage;
  213. // if (null == unitPackage) {
  214. // // Is there a sourceFolder to stick in?
  215. // if (sourceFolder == null) {
  216. // addToNode = structureModel.getRoot();
  217. // } else {
  218. // addToNode = findOrCreateChildSourceFolder(sourceFolder, structureModel);
  219. // }
  220. // } else {
  221. IProgramElement rootForSource = structureModel.getHierarchy().getRoot();
  222. if (sourceFolder != null) {
  223. rootForSource = findOrCreateChildSourceFolder(sourceFolder, structureModel);
  224. }
  225. String pkgName;
  226. if (unitPackage == null) {
  227. pkgName = "";
  228. } else {
  229. StringBuilder nameBuffer = new StringBuilder();
  230. final char[][] importName = unitPackage.getImportName();
  231. final int last = importName.length - 1;
  232. for (int i = 0; i < importName.length; i++) {
  233. nameBuffer.append(new String(importName[i]));
  234. if (i < last) {
  235. nameBuffer.append('.');
  236. }
  237. }
  238. pkgName = nameBuffer.toString();
  239. }
  240. IProgramElement pkgNode = null;
  241. if (structureModel != null && structureModel.getHierarchy().getRoot() != null && rootForSource.getChildren() != null) {
  242. for (IProgramElement currNode : rootForSource.getChildren()) {
  243. if (pkgName.equals(currNode.getName())) {
  244. pkgNode = currNode;
  245. break;
  246. }
  247. }
  248. }
  249. if (pkgNode == null) {
  250. // note packages themselves have no source location
  251. pkgNode = new ProgramElement(activeStructureModel, pkgName, IProgramElement.Kind.PACKAGE, new ArrayList());
  252. rootForSource.addChild(pkgNode);
  253. }
  254. addToNode = pkgNode;
  255. // }
  256. }
  257. return addToNode;
  258. }
  259. public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
  260. String name = new String(typeDeclaration.name);
  261. IProgramElement.Kind kind = IProgramElement.Kind.CLASS;
  262. if (typeDeclaration instanceof AspectDeclaration) {
  263. kind = IProgramElement.Kind.ASPECT;
  264. } else if (TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.INTERFACE_DECL) {
  265. kind = IProgramElement.Kind.INTERFACE;
  266. } else if (TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ENUM_DECL) {
  267. kind = IProgramElement.Kind.ENUM;
  268. } else if (TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
  269. kind = IProgramElement.Kind.ANNOTATION;
  270. }
  271. boolean isAnnotationStyleAspect = false;
  272. // @AJ support
  273. if (typeDeclaration.annotations != null) {
  274. for (int i = 0; i < typeDeclaration.annotations.length; i++) {
  275. Annotation annotation = typeDeclaration.annotations[i];
  276. if (Arrays.equals(annotation.type.getTypeBindingPublic(scope).signature(),
  277. "Lorg/aspectj/lang/annotation/Aspect;".toCharArray())) {
  278. kind = IProgramElement.Kind.ASPECT;
  279. if (!(typeDeclaration instanceof AspectDeclaration)) {
  280. isAnnotationStyleAspect = true;
  281. }
  282. } else if (annotation.resolvedType != null) {
  283. // Fix for the case where in a privileged aspect a parent declaration :
  284. // declare parents: (@A C+) implements (B);
  285. // is causing the resolvedType to be null when it shouldn't
  286. // for the aspect and privileged annotation of that aspect.
  287. // Creating the char[][] needed for ImportReference
  288. String[] temp = (new String(annotation.resolvedType.constantPoolName())).split("/");
  289. if (temp.length > 1) {
  290. char[][] path = new char[temp.length][];
  291. for (int k = 0; k < temp.length; k++) {
  292. path[k] = temp[k].toCharArray();
  293. }
  294. // Create the ImportReference needed to add a
  295. // ProgramElement
  296. ImportReference importRef = new ImportReference(path, new long[] { 0 }, false, 0);
  297. IProgramElement ceNode = new ProgramElement(activeStructureModel, importRef.toString(),
  298. IProgramElement.Kind.IMPORT_REFERENCE, makeLocation(importRef), 0, null, null);
  299. ceNode.setSourceSignature(genSourceSignature(importRef));
  300. // Add Element to Imports of Current Class
  301. ProgramElement imports = getImportReferencesRoot();// (ProgramElement) ((IProgramElement)
  302. // stack.peek()).getChildren().get(0);
  303. imports.addChild(0, ceNode);
  304. }
  305. }
  306. }
  307. }
  308. int typeModifiers = typeDeclaration.modifiers;
  309. if (typeDeclaration instanceof AspectDeclaration) {
  310. typeModifiers = ((AspectDeclaration) typeDeclaration).getDeclaredModifiers();
  311. }
  312. IProgramElement peNode = new ProgramElement(activeStructureModel, name, kind, makeLocation(typeDeclaration), typeModifiers,
  313. null, null);
  314. peNode.setSourceSignature(genSourceSignature(typeDeclaration));
  315. peNode.setFormalComment(generateJavadocComment(typeDeclaration));
  316. peNode.setAnnotationStyleDeclaration(isAnnotationStyleAspect);
  317. stack.peek().addChild(peNode);
  318. stack.push(peNode);
  319. return true;
  320. }
  321. public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
  322. // Is there a package declaration to insert into the model?
  323. if (packageDecl != null) {
  324. int dotIndex = packageDecl.toString().lastIndexOf('.');
  325. String packageString = packageDecl.toString();
  326. ProgramElement packageDeclaration = new ProgramElement(activeStructureModel, packageString,
  327. IProgramElement.Kind.PACKAGE_DECLARATION, makeLocation(packageDecl), 0, null, null);
  328. StringBuilder packageSourceDeclaration = new StringBuilder();
  329. packageSourceDeclaration.append("package ");
  330. packageSourceDeclaration.append(packageString);
  331. packageSourceDeclaration.append(";");
  332. packageDeclaration.setSourceSignature(packageSourceDeclaration.toString());
  333. stack.pop();
  334. ProgramElement containingTypeElement = (ProgramElement) stack.peek();
  335. containingTypeElement.addChild(0, packageDeclaration);
  336. packageDecl = null;
  337. } else {
  338. stack.pop();
  339. }
  340. }
  341. // ??? share impl with visit(TypeDeclaration, ..) ?
  342. public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
  343. String name = new String(memberTypeDeclaration.name);
  344. IProgramElement.Kind kind = IProgramElement.Kind.CLASS;
  345. int typeDeclarationKind = TypeDeclaration.kind(memberTypeDeclaration.modifiers);
  346. if (memberTypeDeclaration instanceof AspectDeclaration) {
  347. kind = IProgramElement.Kind.ASPECT;
  348. } else if (typeDeclarationKind == TypeDeclaration.INTERFACE_DECL) {
  349. kind = IProgramElement.Kind.INTERFACE;
  350. } else if (typeDeclarationKind == TypeDeclaration.ENUM_DECL) {
  351. kind = IProgramElement.Kind.ENUM;
  352. } else if (typeDeclarationKind == TypeDeclaration.ANNOTATION_TYPE_DECL) {
  353. kind = IProgramElement.Kind.ANNOTATION;
  354. }
  355. boolean isAnnotationStyleAspect = false;
  356. // @AJ support
  357. if (memberTypeDeclaration.annotations != null) {
  358. for (int i = 0; i < memberTypeDeclaration.annotations.length; i++) {
  359. Annotation annotation = memberTypeDeclaration.annotations[i];
  360. if (Arrays.equals(annotation.type.getTypeBindingPublic(scope).signature(),
  361. "Lorg/aspectj/lang/annotation/Aspect;".toCharArray())) {
  362. kind = IProgramElement.Kind.ASPECT;
  363. if (!(memberTypeDeclaration instanceof AspectDeclaration)) {
  364. isAnnotationStyleAspect = true;
  365. }
  366. }
  367. }
  368. }
  369. int typeModifiers = memberTypeDeclaration.modifiers;
  370. if (memberTypeDeclaration instanceof AspectDeclaration) {
  371. typeModifiers = ((AspectDeclaration) memberTypeDeclaration).getDeclaredModifiers();
  372. }
  373. IProgramElement peNode = new ProgramElement(activeStructureModel, name, kind, makeLocation(memberTypeDeclaration),
  374. typeModifiers, null, null);
  375. peNode.setSourceSignature(genSourceSignature(memberTypeDeclaration));
  376. peNode.setFormalComment(generateJavadocComment(memberTypeDeclaration));
  377. peNode.setAnnotationStyleDeclaration(isAnnotationStyleAspect);
  378. ((IProgramElement) stack.peek()).addChild(peNode);
  379. stack.push(peNode);
  380. return true;
  381. }
  382. public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
  383. stack.pop();
  384. }
  385. public boolean visit(TypeDeclaration memberTypeDeclaration, BlockScope scope) {
  386. String fullName = "<undefined>";
  387. if (memberTypeDeclaration.allocation != null && memberTypeDeclaration.allocation.type != null) {
  388. // Create a name something like 'new Runnable() {..}'
  389. fullName = "new " + memberTypeDeclaration.allocation.type.toString() + "() {..}";
  390. } else if (memberTypeDeclaration.binding != null && memberTypeDeclaration.binding.constantPoolName() != null) {
  391. // If we couldn't find a nice name like 'new Runnable() {..}' then
  392. // use the number after the $
  393. fullName = new String(memberTypeDeclaration.name);
  394. // fullName = new String(memberTypeDeclaration.binding
  395. // .constantPoolName());
  396. int dollar = fullName.indexOf('$');
  397. fullName = fullName.substring(dollar + 1);
  398. }
  399. IProgramElement.Kind kind = IProgramElement.Kind.CLASS;
  400. if (TypeDeclaration.kind(memberTypeDeclaration.modifiers) == TypeDeclaration.INTERFACE_DECL) {
  401. kind = IProgramElement.Kind.INTERFACE;
  402. } else if (TypeDeclaration.kind(memberTypeDeclaration.modifiers) == TypeDeclaration.ENUM_DECL) {
  403. kind = IProgramElement.Kind.ENUM;
  404. } else if (TypeDeclaration.kind(memberTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
  405. kind = IProgramElement.Kind.ANNOTATION;
  406. }
  407. // @AJ support
  408. boolean isAnnotationStyleAspect = false;
  409. if (memberTypeDeclaration.annotations != null) {
  410. for (int i = 0; i < memberTypeDeclaration.annotations.length; i++) {
  411. Annotation annotation = memberTypeDeclaration.annotations[i];
  412. if (Arrays.equals(annotation.type.getTypeBindingPublic(scope).signature(),
  413. "Lorg/aspectj/lang/annotation/Aspect;".toCharArray())) {
  414. kind = IProgramElement.Kind.ASPECT;
  415. if (!(memberTypeDeclaration instanceof AspectDeclaration)) {
  416. isAnnotationStyleAspect = true;
  417. }
  418. break;
  419. }
  420. }
  421. }
  422. IProgramElement peNode = new ProgramElement(activeStructureModel, fullName, kind, makeLocation(memberTypeDeclaration),
  423. memberTypeDeclaration.modifiers, null, null);
  424. peNode.setSourceSignature(genSourceSignature(memberTypeDeclaration));
  425. peNode.setFormalComment(generateJavadocComment(memberTypeDeclaration));
  426. peNode.setAnnotationStyleDeclaration(isAnnotationStyleAspect);
  427. // if we're something like 'new Runnable(){..}' then set the
  428. // bytecodeSignature to be the typename so we can match it later
  429. // when creating the structure model
  430. if (peNode.getBytecodeSignature() == null && memberTypeDeclaration.binding != null
  431. && memberTypeDeclaration.binding.constantPoolName() != null) {
  432. StringTokenizer st = new StringTokenizer(new String(memberTypeDeclaration.binding.constantPoolName()), "/");
  433. while (st.hasMoreTokens()) {
  434. String s = st.nextToken();
  435. if (!st.hasMoreTokens()) {
  436. peNode.setBytecodeSignature(s);
  437. }
  438. }
  439. }
  440. IProgramElement ipe = (IProgramElement)stack.peek();
  441. if (ipe!=null) {
  442. // With AspectJ 1.8.9 the type structure must be slightly different as the guard
  443. // is required (the null is due to a default constructor).
  444. ((IProgramElement) stack.peek()).addChild(peNode);
  445. }
  446. stack.push(peNode);
  447. return true;
  448. }
  449. public void endVisit(TypeDeclaration memberTypeDeclaration, BlockScope scope) {
  450. stack.pop();
  451. }
  452. private String genSourceSignature(TypeDeclaration typeDeclaration) {
  453. StringBuffer output = new StringBuffer();
  454. typeDeclaration.printHeader(0, output);
  455. return output.toString();
  456. }
  457. // private IProgramElement findEnclosingClass(Stack stack) {
  458. // for (int i = stack.size() - 1; i >= 0; i--) {
  459. // IProgramElement pe = (IProgramElement) stack.get(i);
  460. // if (pe.getKind() == IProgramElement.Kind.CLASS) {
  461. // return pe;
  462. // }
  463. //
  464. // }
  465. // return (IProgramElement) stack.peek();
  466. // }
  467. public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
  468. IProgramElement peNode = null;
  469. // For intertype decls, use the modifiers from the original signature,
  470. // not the generated method
  471. if (methodDeclaration instanceof InterTypeDeclaration) {
  472. InterTypeDeclaration itd = (InterTypeDeclaration) methodDeclaration;
  473. ResolvedMember sig = itd.getSignature();
  474. peNode = new ProgramElement(activeStructureModel, null, IProgramElement.Kind.ERROR, makeLocation(methodDeclaration),
  475. (sig != null ? sig.getModifiers() : 0), null, null);
  476. } else {
  477. peNode = new ProgramElement(activeStructureModel, null, IProgramElement.Kind.ERROR, makeLocation(methodDeclaration),
  478. methodDeclaration.modifiers, null, null);
  479. }
  480. formatter.genLabelAndKind(methodDeclaration, peNode); // will set the
  481. // name
  482. genBytecodeInfo(methodDeclaration, peNode);
  483. List namedPointcuts = genNamedPointcuts(methodDeclaration);
  484. // if (shouldAddUsesPointcut)
  485. // addUsesPointcutRelationsForNode(peNode, namedPointcuts, methodDeclaration);
  486. if (methodDeclaration instanceof DeclareDeclaration) {
  487. DeclareDeclaration dDeclaration = (DeclareDeclaration) methodDeclaration;
  488. Declare decl = dDeclaration.declareDecl;
  489. if (decl instanceof DeclareParents) {
  490. TypePatternList tpl = ((DeclareParents) decl).getParents();
  491. List<String> parents = new ArrayList<>();
  492. for (int i = 0; i < tpl.size(); i++) {
  493. parents.add(tpl.get(i).getExactType().getName().replaceAll("\\$", "."));
  494. }
  495. peNode.setParentTypes(parents);
  496. }
  497. if (decl instanceof DeclareAnnotation) {
  498. DeclareAnnotation da = (DeclareAnnotation) decl;
  499. ResolvedType annotationType = da.getAnnotationType();
  500. if (annotationType == null) {
  501. String s = ((DeclareAnnotation) decl).getAnnotationString();
  502. if (s != null && s.length() > 0) {
  503. s = s.substring(1);
  504. }
  505. peNode.setAnnotationType(s);
  506. } else {
  507. peNode.setAnnotationType(annotationType.getName());
  508. }
  509. if (da.isRemover()) {
  510. peNode.setAnnotationRemover(true);
  511. }
  512. }
  513. }
  514. if (methodDeclaration.returnType != null) {
  515. // if we don't make the distinction between ITD fields and other
  516. // methods, then we loose the type, for example int, for the field
  517. // and instead get "void".
  518. if (peNode.getKind().equals(IProgramElement.Kind.INTER_TYPE_FIELD)) {
  519. InterTypeFieldDeclaration itfd = (InterTypeFieldDeclaration) methodDeclaration;
  520. if (itfd.getRealFieldType() != null) {
  521. peNode.setCorrespondingType(new String(itfd.getRealFieldType().readableName()));
  522. } else {
  523. peNode.setCorrespondingType(null);
  524. }
  525. // was peNode.setCorrespondingType(methodDeclaration.returnType.toString());
  526. } else {
  527. if (methodDeclaration.returnType.resolvedType != null) {
  528. peNode.setCorrespondingType(new String(methodDeclaration.returnType.resolvedType.readableName()));
  529. } else {
  530. peNode.setCorrespondingType(null);
  531. }
  532. }
  533. } else {
  534. peNode.setCorrespondingType(null);
  535. }
  536. peNode.setSourceSignature(genSourceSignature(methodDeclaration));
  537. peNode.setFormalComment(generateJavadocComment(methodDeclaration));
  538. // TODO: add return type test
  539. if (peNode.getKind().equals(IProgramElement.Kind.METHOD)) {
  540. if ((peNode.getName().charAt(0) == 'm')
  541. && (peNode.toLabelString().equals("main(String[])") || peNode.toLabelString()
  542. .equals("main(java.lang.String[])"))
  543. && peNode.getModifiers().contains(IProgramElement.Modifiers.STATIC)
  544. && peNode.getAccessibility().equals(IProgramElement.Accessibility.PUBLIC)) {
  545. ((IProgramElement) stack.peek()).setRunnable(true);
  546. }
  547. }
  548. stack.push(peNode);
  549. return true;
  550. }
  551. // private void addUsesPointcutRelationsForNode(IProgramElement peNode, List namedPointcuts, MethodDeclaration declaration) {
  552. // for (Iterator it = namedPointcuts.iterator(); it.hasNext();) {
  553. // ReferencePointcut rp = (ReferencePointcut) it.next();
  554. // ResolvedMember member = getPointcutDeclaration(rp, declaration);
  555. // if (member != null) {
  556. // IRelationship foreward = AsmManager.getDefault().getRelationshipMap().get(peNode.getHandleIdentifier(),
  557. // IRelationship.Kind.USES_POINTCUT, "uses pointcut", false, true);
  558. // IProgramElement forwardIPE = AsmManager.getDefault().getHierarchy().findElementForSourceLine(
  559. // member.getSourceLocation());
  560. // foreward.addTarget(AsmManager.getDefault().getHandleProvider().createHandleIdentifier(forwardIPE));
  561. //
  562. // IRelationship back = AsmManager.getDefault().getRelationshipMap().get(
  563. // AsmManager.getDefault().getHandleProvider().createHandleIdentifier(forwardIPE),
  564. // IRelationship.Kind.USES_POINTCUT, "pointcut used by", false, true);
  565. // back.addTarget(peNode.getHandleIdentifier());
  566. // }
  567. // }
  568. // }
  569. private ResolvedMember getPointcutDeclaration(ReferencePointcut rp, MethodDeclaration declaration) {
  570. EclipseFactory factory = ((AjLookupEnvironment) declaration.scope.environment()).factory;
  571. World world = factory.getWorld();
  572. UnresolvedType onType = rp.onType;
  573. if (onType == null) {
  574. if (declaration.binding != null) {
  575. Member member = factory.makeResolvedMember(declaration.binding);
  576. onType = member.getDeclaringType();
  577. } else {
  578. return null;
  579. }
  580. }
  581. ResolvedMember[] members = onType.resolve(world).getDeclaredPointcuts();
  582. if (members != null) {
  583. for (ResolvedMember member : members) {
  584. if (member.getName().equals(rp.name)) {
  585. return member;
  586. }
  587. }
  588. }
  589. return null;
  590. }
  591. /**
  592. * @param methodDeclaration
  593. * @return all of the named pointcuts referenced by the PCD of this declaration
  594. */
  595. private List genNamedPointcuts(MethodDeclaration methodDeclaration) {
  596. List pointcuts = new ArrayList();
  597. if (methodDeclaration instanceof AdviceDeclaration) {
  598. if (((AdviceDeclaration) methodDeclaration).pointcutDesignator != null) {
  599. addAllNamed(((AdviceDeclaration) methodDeclaration).pointcutDesignator.getPointcut(), pointcuts);
  600. }
  601. } else if (methodDeclaration instanceof PointcutDeclaration) {
  602. if (((PointcutDeclaration) methodDeclaration).pointcutDesignator != null) {
  603. addAllNamed(((PointcutDeclaration) methodDeclaration).pointcutDesignator.getPointcut(), pointcuts);
  604. }
  605. }
  606. return pointcuts;
  607. }
  608. /**
  609. * @param left
  610. * @param pointcuts
  611. * accumulator for named pointcuts
  612. */
  613. private void addAllNamed(Pointcut pointcut, List pointcuts) {
  614. if (pointcut == null) {
  615. return;
  616. }
  617. if (pointcut instanceof ReferencePointcut) {
  618. ReferencePointcut rp = (ReferencePointcut) pointcut;
  619. pointcuts.add(rp);
  620. } else if (pointcut instanceof AndPointcut) {
  621. AndPointcut ap = (AndPointcut) pointcut;
  622. addAllNamed(ap.getLeft(), pointcuts);
  623. addAllNamed(ap.getRight(), pointcuts);
  624. } else if (pointcut instanceof OrPointcut) {
  625. OrPointcut op = (OrPointcut) pointcut;
  626. addAllNamed(op.getLeft(), pointcuts);
  627. addAllNamed(op.getRight(), pointcuts);
  628. }
  629. }
  630. private String genSourceSignature(MethodDeclaration methodDeclaration) {
  631. StringBuffer output = new StringBuffer();
  632. ASTNode.printModifiers(methodDeclaration.modifiers, output);
  633. // Append Type Parameters if any
  634. TypeParameter types[] = methodDeclaration.typeParameters();
  635. if (types != null && types.length != 0) {
  636. output.append("<");
  637. for (int i = 0; i < types.length; i++) {
  638. if (i > 0) {
  639. output.append(", ");
  640. }
  641. types[i].printStatement(0, output);
  642. }
  643. output.append("> ");
  644. }
  645. String methodName = methodDeclaration.selector==null?"null":new String(methodDeclaration.selector);
  646. methodDeclaration.printReturnType(0, output).append(methodName).append('(');
  647. if (methodDeclaration.arguments != null) {
  648. for (int i = 0; i < methodDeclaration.arguments.length; i++) {
  649. if (i > 0) {
  650. output.append(", "); //$NON-NLS-1$
  651. }
  652. methodDeclaration.arguments[i].print(0, output);
  653. }
  654. }
  655. output.append(')');
  656. if (methodDeclaration.thrownExceptions != null) {
  657. output.append(" throws "); //$NON-NLS-1$
  658. for (int i = 0; i < methodDeclaration.thrownExceptions.length; i++) {
  659. if (i > 0) {
  660. output.append(", "); //$NON-NLS-1$
  661. }
  662. methodDeclaration.thrownExceptions[i].print(0, output);
  663. }
  664. }
  665. return output.toString();
  666. }
  667. // protected void genBytecodeInfo(MethodDeclaration methodDeclaration,
  668. // IProgramElement peNode) {
  669. // if (methodDeclaration.binding != null) {
  670. // String memberName = "";
  671. // String memberBytecodeSignature = "";
  672. // try {
  673. // EclipseFactory factory =
  674. // ((AjLookupEnvironment)methodDeclaration.scope.environment()).factory;
  675. // Member member = factory.makeResolvedMember(methodDeclaration.binding);
  676. // memberName = member.getName();
  677. // memberBytecodeSignature = member.getSignature();
  678. // } catch (BCException bce) { // bad type name
  679. // memberName = "<undefined>";
  680. // } catch (NullPointerException npe) {
  681. // memberName = "<undefined>";
  682. // }
  683. //
  684. // peNode.setBytecodeName(memberName);
  685. // peNode.setBytecodeSignature(memberBytecodeSignature);
  686. // }
  687. // ((IProgramElement)stack.peek()).addChild(peNode);
  688. // }
  689. protected void genBytecodeInfo(MethodDeclaration methodDeclaration, IProgramElement peNode) {
  690. if (methodDeclaration.binding != null) {
  691. try {
  692. EclipseFactory factory = ((AjLookupEnvironment) methodDeclaration.scope.environment()).factory;
  693. Member member = factory.makeResolvedMember(methodDeclaration.binding);
  694. peNode.setBytecodeName(member.getName());
  695. peNode.setBytecodeSignature(member.getSignature());
  696. } catch (BCException bce) { // bad type name
  697. bce.printStackTrace();
  698. } catch (NullPointerException npe) {
  699. npe.printStackTrace();
  700. }
  701. }
  702. ((IProgramElement) stack.peek()).addChild(peNode);
  703. }
  704. public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
  705. stack.pop();
  706. }
  707. public boolean visit(ImportReference importRef, CompilationUnitScope scope) {
  708. // 3.3 compiler used to represent the package statement in such a way that toString() would return 'foo.*' for 'package foo;'
  709. // 3.7 compiler doesn't create an 'ondemand' import reference so it is purely toString()'d as 'foo'
  710. String currPackageImport = importRef.toString();
  711. String stackPackageName = stack.peek().getPackageName();
  712. if (stackPackageName.equals(currPackageImport)) {
  713. packageDecl = importRef;
  714. } else {
  715. ProgramElement peNode = new ProgramElement(activeStructureModel, new String(importRef.toString()),
  716. IProgramElement.Kind.IMPORT_REFERENCE, makeLocation(importRef), 0,// could set static here, but for
  717. // some reason the info is
  718. // private
  719. null, null);
  720. // set it here instead
  721. if (importRef.isStatic()) {
  722. peNode.addModifiers(IProgramElement.Modifiers.STATIC);
  723. }
  724. // create Source signature for import
  725. peNode.setSourceSignature(genSourceSignature(importRef));
  726. IProgramElement containingTypeElement = (IProgramElement) stack.peek();
  727. ProgramElement imports = getImportReferencesRoot();
  728. imports.addChild(0, peNode);
  729. stack.push(peNode);
  730. }
  731. return true;
  732. }
  733. private ProgramElement getImportReferencesRoot() {
  734. IProgramElement element = (IProgramElement) stack.peek();
  735. boolean hasPackageDeclaration = (element.getChildren().get(0)).getKind().isPackageDeclaration();
  736. return (ProgramElement) element.getChildren().get(hasPackageDeclaration ? 1 : 0);
  737. }
  738. public void endVisit(ImportReference importRef, CompilationUnitScope scope) {
  739. // 3.3 compiler used to represent the package statement in such a way that toString() would return 'foo.*' for 'package foo;'
  740. // 3.7 compiler doesn't create an 'ondemand' import reference so it is purely toString()'d as 'foo'
  741. String currPackageImport = importRef.toString();
  742. if (!stack.peek().getPackageName().equals(currPackageImport)) {
  743. stack.pop();
  744. }
  745. }
  746. private String genSourceSignature(ImportReference importreference) {
  747. StringBuffer output = new StringBuffer();
  748. output.append("import ");
  749. ASTNode.printModifiers(importreference.modifiers, output);
  750. output.append(importreference);
  751. output.append(";");
  752. return output.toString();
  753. }
  754. public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
  755. IProgramElement peNode = null;
  756. if (fieldDeclaration.type == null) { // The field represents an enum
  757. // value
  758. peNode = new ProgramElement(activeStructureModel, new String(fieldDeclaration.name), IProgramElement.Kind.ENUM_VALUE,
  759. makeLocation(fieldDeclaration), fieldDeclaration.modifiers, null, null);
  760. String type = null;
  761. boolean isOk = true;
  762. if (fieldDeclaration.binding == null) {
  763. type="fieldDeclaration_binding_is_null";
  764. System.err.println("DebugFor402832: null fieldDeclaration.binding for "+fieldDeclaration);
  765. isOk=false;
  766. } else {
  767. if (fieldDeclaration.binding.type==null) {
  768. System.err.println("DebugFor402832: null fieldDeclaration.binding.type for "+fieldDeclaration);
  769. type="fieldDeclaration_binding_type_is_null";
  770. isOk=false;
  771. } else {
  772. type=fieldDeclaration.binding.type.debugName();
  773. }
  774. }
  775. if (!isOk) {
  776. if (fieldDeclaration.type!=null && fieldDeclaration.type.resolvedType!=null) {
  777. type = fieldDeclaration.type.resolvedType.debugName();
  778. System.err.println("DebugFor402832: used secondary route to compute name for "+fieldDeclaration+", set to "+type);
  779. isOk=true;
  780. }
  781. }
  782. peNode.setCorrespondingType(type);
  783. // peNode.setCorrespondingType(fieldDeclaration.binding.type.debugName());
  784. } else {
  785. peNode = new ProgramElement(activeStructureModel, new String(fieldDeclaration.name), IProgramElement.Kind.FIELD,
  786. makeLocation(fieldDeclaration), fieldDeclaration.modifiers, null, null);
  787. if (fieldDeclaration.type.resolvedType != null) {
  788. char[] cs = fieldDeclaration.type.resolvedType.readableName();
  789. // fieldDeclaration.type.resolvedType.genericTypeSignature()
  790. peNode.setCorrespondingType(new String(cs));
  791. } else {
  792. // peNode.setCorrespondingType(null);
  793. peNode.setCorrespondingType(fieldDeclaration.type.toString());
  794. }
  795. }
  796. peNode.setSourceSignature(genSourceSignature(fieldDeclaration));
  797. peNode.setFormalComment(generateJavadocComment(fieldDeclaration));
  798. // peNode.setBytecodeSignature(new String(fieldDeclaration.binding.type.signature()));
  799. ((IProgramElement) stack.peek()).addChild(peNode);
  800. stack.push(peNode);
  801. return true;
  802. }
  803. public void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope) {
  804. stack.pop();
  805. }
  806. /**
  807. * Checks if comments should be added to the model before generating.
  808. */
  809. protected String generateJavadocComment(ASTNode astNode) {
  810. if (buildConfig != null && !buildConfig.isGenerateJavadocsInModelMode()) {
  811. return null;
  812. }
  813. // StringBuffer sb = new StringBuffer(); // !!! specify length?
  814. // boolean completed = false;
  815. int startIndex = -1;
  816. if (astNode instanceof MethodDeclaration) {
  817. startIndex = ((MethodDeclaration) astNode).declarationSourceStart;
  818. } else if (astNode instanceof FieldDeclaration) {
  819. startIndex = ((FieldDeclaration) astNode).declarationSourceStart;
  820. } else if (astNode instanceof TypeDeclaration) {
  821. startIndex = ((TypeDeclaration) astNode).declarationSourceStart;
  822. } else if (astNode instanceof ConstructorDeclaration) {
  823. startIndex = ((ConstructorDeclaration) astNode).declarationSourceStart;
  824. }
  825. if (startIndex == -1) {
  826. return null;
  827. } else if (currCompilationResult.compilationUnit.getContents()[startIndex] == '/') {
  828. char[] comment = CharOperation.subarray(currCompilationResult.compilationUnit.getContents(), startIndex,
  829. astNode.sourceStart);
  830. while (comment.length > 2) {
  831. int star = CharOperation.indexOf('*', comment);
  832. if (star == -1) {
  833. return null;
  834. }
  835. // looking for '/**' and not '//' or '//*'
  836. if (star != 0 && (comment[star - 1] == '/') && (comment[star + 1] == '*')
  837. && (star - 2 < 0 || comment[star - 2] != '/')) {
  838. boolean completed = false;
  839. StringBuilder sb = new StringBuilder();
  840. for (int i = 0; i < comment.length && !completed; i++) {
  841. char curr = comment[i];
  842. if (curr == '/' && sb.length() > 2 && sb.charAt(sb.length() - 1) == '*') {
  843. completed = true; // found */
  844. }
  845. sb.append(comment[i]);
  846. }
  847. // The following will remove any non-javadoc comments
  848. // preceeding a javadoc comment in this block
  849. if (sb.toString().indexOf("/**") != 0) {
  850. return sb.toString().substring(sb.toString().indexOf("/**"));
  851. }
  852. return sb.toString();
  853. }
  854. comment = CharOperation.subarray(comment, star + 1, comment.length);
  855. }
  856. }
  857. return null;
  858. }
  859. /**
  860. *
  861. */
  862. protected String genSourceSignature(FieldDeclaration fieldDeclaration) {
  863. StringBuffer output = new StringBuffer();
  864. if (fieldDeclaration.type == null) { // This is an enum value
  865. output.append(fieldDeclaration.name); // the "," or ";" has to be
  866. // put on by whatever uses
  867. // the sourceSignature
  868. return output.toString();
  869. } else {
  870. FieldDeclaration.printModifiers(fieldDeclaration.modifiers, output);
  871. fieldDeclaration.type.print(0, output).append(' ').append(fieldDeclaration.name);
  872. }
  873. output.append(" = ");
  874. if (fieldDeclaration.initialization != null
  875. && (fieldDeclaration.initialization instanceof Literal
  876. || fieldDeclaration.initialization instanceof OperatorExpression || fieldDeclaration.initialization instanceof Reference)) {
  877. fieldDeclaration.initialization.printExpression(0, output);
  878. } else {
  879. output.append("null");
  880. }
  881. output.append(";\n");
  882. return output.toString();
  883. }
  884. // public boolean visit(ImportReference importRef, CompilationUnitScope
  885. // scope) {
  886. // ProgramElementNode peNode = new ProgramElementNode(
  887. // new String(importRef.toString()),
  888. // ProgramElementNode.Kind.,
  889. // makeLocation(importRef),
  890. // 0,
  891. // "",
  892. // new ArrayList());
  893. // ((IProgramElement)stack.peek()).addChild(0, peNode);
  894. // stack.push(peNode);
  895. // return true;
  896. // }
  897. // public void endVisit(ImportReference importRef,CompilationUnitScope
  898. // scope) {
  899. // stack.pop();
  900. // }
  901. public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
  902. if ((constructorDeclaration.bits & ASTNode.IsDefaultConstructor) != 0) {
  903. stack.push(null); // a little weird but does the job
  904. return true;
  905. }
  906. StringBuilder argumentsSignature = new StringBuilder();
  907. argumentsSignature.append("(");
  908. if (constructorDeclaration.arguments != null) {
  909. for (int i = 0; i < constructorDeclaration.arguments.length; i++) {
  910. argumentsSignature.append(constructorDeclaration.arguments[i].type);
  911. if (i + 1 < constructorDeclaration.arguments.length) {
  912. argumentsSignature.append(",");
  913. }
  914. }
  915. }
  916. argumentsSignature.append(")");
  917. IProgramElement peNode = new ProgramElement(activeStructureModel, new String(constructorDeclaration.selector),
  918. IProgramElement.Kind.CONSTRUCTOR, makeLocation(constructorDeclaration), constructorDeclaration.modifiers, null,
  919. null);
  920. formatter.setParameters(constructorDeclaration, peNode);
  921. peNode.setModifiers(constructorDeclaration.modifiers);
  922. peNode.setSourceSignature(genSourceSignature(constructorDeclaration));
  923. peNode.setFormalComment(generateJavadocComment(constructorDeclaration));
  924. // Fix to enable us to anchor things from ctor nodes
  925. if (constructorDeclaration.binding != null) {
  926. String memberName = "";
  927. String memberBytecodeSignature = "";
  928. try {
  929. EclipseFactory factory = ((AjLookupEnvironment) constructorDeclaration.scope.environment()).factory;
  930. Member member = factory.makeResolvedMember(constructorDeclaration.binding);
  931. memberName = member.getName();
  932. memberBytecodeSignature = member.getSignature();
  933. } catch (BCException bce) { // bad type name
  934. memberName = "<undefined>";
  935. } catch (NullPointerException npe) {
  936. memberName = "<undefined>";
  937. }
  938. peNode.setBytecodeName(memberName);
  939. peNode.setBytecodeSignature(memberBytecodeSignature);
  940. }
  941. ((IProgramElement) stack.peek()).addChild(peNode);
  942. stack.push(peNode);
  943. return true;
  944. }
  945. public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
  946. stack.pop();
  947. }
  948. private String genSourceSignature(ConstructorDeclaration constructorDeclaration) {
  949. StringBuffer output = new StringBuffer();
  950. ASTNode.printModifiers(constructorDeclaration.modifiers, output);
  951. // Append Type Parameters if any
  952. TypeParameter types[] = constructorDeclaration.typeParameters();
  953. if (types != null && types.length != 0) {
  954. output.append("<");
  955. for (int i = 0; i < types.length; i++) {
  956. if (i > 0) {
  957. output.append(", ");
  958. }
  959. types[i].printStatement(0, output);
  960. }
  961. output.append("> ");
  962. }
  963. output.append(constructorDeclaration.selector).append('(');
  964. if (constructorDeclaration.arguments != null) {
  965. for (int i = 0; i < constructorDeclaration.arguments.length; i++) {
  966. if (i > 0) {
  967. output.append(", "); //$NON-NLS-1$
  968. }
  969. constructorDeclaration.arguments[i].print(0, output);
  970. }
  971. }
  972. output.append(')');
  973. if (constructorDeclaration.thrownExceptions != null) {
  974. output.append(" throws "); //$NON-NLS-1$
  975. for (int i = 0; i < constructorDeclaration.thrownExceptions.length; i++) {
  976. if (i > 0) {
  977. output.append(", "); //$NON-NLS-1$
  978. }
  979. constructorDeclaration.thrownExceptions[i].print(0, output);
  980. }
  981. }
  982. return output.toString();
  983. }
  984. // public boolean visit(Clinit clinit, ClassScope scope) {
  985. // ProgramElementNode peNode = new ProgramElementNode(
  986. // "<clinit>",
  987. // ProgramElementNode.Kind.INITIALIZER,
  988. // makeLocation(clinit),
  989. // clinit.modifiers,
  990. // "",
  991. // new ArrayList());
  992. // ((IProgramElement)stack.peek()).addChild(peNode);
  993. // stack.push(peNode);
  994. // return false;
  995. // }
  996. // public void endVisit(Clinit clinit, ClassScope scope) {
  997. // stack.pop();
  998. // }
  999. /**
  1000. * This method works-around an odd traverse implementation on Initializer
  1001. */
  1002. private Initializer inInitializer = null;
  1003. public boolean visit(Initializer initializer, MethodScope scope) {
  1004. if (initializer == inInitializer) {
  1005. return false;
  1006. }
  1007. inInitializer = initializer;
  1008. IProgramElement peNode = new ProgramElement(activeStructureModel, "...", IProgramElement.Kind.INITIALIZER,
  1009. makeLocation(initializer), initializer.modifiers, null, null);
  1010. // "",
  1011. // new ArrayList());
  1012. ((IProgramElement) stack.peek()).addChild(peNode);
  1013. stack.push(peNode);
  1014. initializer.block.traverse(this, scope);
  1015. stack.pop();
  1016. inInitializer = null;
  1017. return false;
  1018. }
  1019. // ??? handle non-existant files
  1020. protected ISourceLocation makeLocation(ASTNode node) {
  1021. String fileName = "";
  1022. if (filename != null) {
  1023. fileName = filename;
  1024. }
  1025. // AMC - different strategies based on node kind
  1026. int startLine = getStartLine(node);
  1027. int endLine = getEndLine(node);
  1028. SourceLocation loc = null;
  1029. if (startLine <= endLine) {
  1030. // found a valid end line for this node...
  1031. loc = new SourceLocation(new File(fileName), startLine, endLine);
  1032. loc.setOffset(node.sourceStart);
  1033. } else {
  1034. loc = new SourceLocation(new File(fileName), startLine);
  1035. loc.setOffset(node.sourceStart);
  1036. }
  1037. return loc;
  1038. }
  1039. // AMC - overloaded set of methods to get start and end lines for
  1040. // various ASTNode types. They have no common ancestor in the
  1041. // hierarchy!!
  1042. protected int getStartLine(ASTNode n) {
  1043. // if ( n instanceof AbstractVariableDeclaration ) return getStartLine(
  1044. // (AbstractVariableDeclaration)n);
  1045. // if ( n instanceof AbstractMethodDeclaration ) return getStartLine(
  1046. // (AbstractMethodDeclaration)n);
  1047. // if ( n instanceof TypeDeclaration ) return getStartLine(
  1048. // (TypeDeclaration)n);
  1049. return Util.getLineNumber(n.sourceStart, lineseps, 0, lineseps.length - 1);
  1050. // return ProblemHandler.searchLineNumber(lineseps,
  1051. // currCompilationResult.lineSeparatorPositions,
  1052. // n.sourceStart);
  1053. }
  1054. // AMC - overloaded set of methods to get start and end lines for
  1055. // various ASTNode types. They have no common ancestor in the
  1056. // hierarchy!!
  1057. protected int getEndLine(ASTNode n) {
  1058. if (n instanceof AbstractVariableDeclaration) {
  1059. return getEndLine((AbstractVariableDeclaration) n);
  1060. }
  1061. if (n instanceof AbstractMethodDeclaration) {
  1062. return getEndLine((AbstractMethodDeclaration) n);
  1063. }
  1064. if (n instanceof TypeDeclaration) {
  1065. return getEndLine((TypeDeclaration) n);
  1066. }
  1067. return Util.getLineNumber(n.sourceEnd, lineseps, 0, lineseps.length - 1);
  1068. // return ProblemHandler.searchLineNumber(lineseps,
  1069. // currCompilationResult.lineSeparatorPositions,
  1070. // n.sourceEnd);
  1071. }
  1072. // AMC - overloaded set of methods to get start and end lines for
  1073. // various ASTNode types. They have no common ancestor in the
  1074. // hierarchy!!
  1075. // private int getStartLine( AbstractVariableDeclaration avd ) {
  1076. // return ProblemHandler.searchLineNumber(
  1077. // currCompilationResult.lineSeparatorPositions,
  1078. // avd.declarationSourceStart);
  1079. // }
  1080. // AMC - overloaded set of methods to get start and end lines for
  1081. // various ASTNode types. They have no common ancestor in the
  1082. // hierarchy!!
  1083. private int getEndLine(AbstractVariableDeclaration avd) {
  1084. return Util.getLineNumber(avd.declarationSourceEnd, lineseps, 0, lineseps.length - 1);
  1085. }
  1086. // AMC - overloaded set of methods to get start and end lines for
  1087. // various ASTNode types. They have no common ancestor in the
  1088. // hierarchy!!
  1089. // private int getStartLine( AbstractMethodDeclaration amd ){
  1090. // return ProblemHandler.searchLineNumber(
  1091. // currCompilationResult.lineSeparatorPositions,
  1092. // amd.declarationSourceStart);
  1093. // }
  1094. // AMC - overloaded set of methods to get start and end lines for
  1095. // various ASTNode types. They have no common ancestor in the
  1096. // hierarchy!!
  1097. private int getEndLine(AbstractMethodDeclaration amd) {
  1098. return Util.getLineNumber(amd.declarationSourceEnd, lineseps, 0, lineseps.length - 1);
  1099. }
  1100. // AMC - overloaded set of methods to get start and end lines for
  1101. // various ASTNode types. They have no common ancestor in the
  1102. // hierarchy!!
  1103. // private int getStartLine( TypeDeclaration td ){
  1104. // return ProblemHandler.searchLineNumber(
  1105. // currCompilationResult.lineSeparatorPositions,
  1106. // td.declarationSourceStart);
  1107. // }
  1108. // AMC - overloaded set of methods to get start and end lines for
  1109. // various ASTNode types. They have no common ancestor in the
  1110. // hierarchy!!
  1111. private int getEndLine(TypeDeclaration td) {
  1112. return Util.getLineNumber(td.declarationSourceEnd, lineseps, 0, lineseps.length - 1);
  1113. }
  1114. }