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

21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  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 Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.internal.core.builder;
  13. import java.io.*;
  14. import java.util.*;
  15. import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
  16. import org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration;
  17. import org.aspectj.ajdt.internal.compiler.ast.InterTypeDeclaration;
  18. import org.aspectj.ajdt.internal.compiler.ast.InterTypeFieldDeclaration;
  19. import org.aspectj.ajdt.internal.compiler.ast.InterTypeMethodDeclaration;
  20. import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
  21. import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
  22. import org.aspectj.asm.*;
  23. import org.aspectj.asm.internal.ProgramElement;
  24. import org.aspectj.bridge.*;
  25. import org.aspectj.util.LangUtil;
  26. import org.aspectj.weaver.Member;
  27. import org.aspectj.weaver.ResolvedMember;
  28. import org.eclipse.jdt.internal.compiler.*;
  29. import org.eclipse.jdt.internal.compiler.ast.*;
  30. import org.eclipse.jdt.internal.compiler.lookup.*;
  31. import org.eclipse.jdt.internal.compiler.problem.ProblemHandler;
  32. /**
  33. * At each iteration of <CODE>processCompilationUnit</CODE> the declarations for a
  34. * particular compilation unit are added to the hierarchy passed as a a parameter.
  35. *
  36. * Clients who extend this class need to ensure that they do not override any of the existing
  37. * behavior. If they do, the structure model will not be built properly and tools such as IDE
  38. * structure views and ajdoc will fail.
  39. *
  40. * @author Mik Kersten
  41. */
  42. public class AsmHierarchyBuilder extends ASTVisitor {
  43. // public static void build(
  44. // CompilationUnitDeclaration unit,
  45. // IHierarchy structureModel, AjBuildConfig buildConfig) {
  46. // LangUtil.throwIaxIfNull(unit, "unit");
  47. // new AsmHierarchyBuilder(unit., ).;
  48. // }
  49. protected AsmElementFormatter formatter = new AsmElementFormatter();
  50. /**
  51. * Reset for every compilation unit.
  52. */
  53. protected AjBuildConfig buildConfig;
  54. /**
  55. * Reset for every compilation unit.
  56. */
  57. protected Stack stack;
  58. /**
  59. * Reset for every compilation unit.
  60. */
  61. private CompilationResult currCompilationResult;
  62. /**
  63. *
  64. * @param cuDeclaration
  65. * @param buildConfig
  66. * @param structureModel hiearchy to add this unit's declarations to
  67. */
  68. public void buildStructureForCompilationUnit(CompilationUnitDeclaration cuDeclaration, IHierarchy structureModel, AjBuildConfig buildConfig) {
  69. currCompilationResult = cuDeclaration.compilationResult();
  70. LangUtil.throwIaxIfNull(currCompilationResult, "result");
  71. stack = new Stack();
  72. this.buildConfig = buildConfig;
  73. internalBuild(cuDeclaration, structureModel);
  74. // throw new RuntimeException("not implemented");
  75. }
  76. private void internalBuild(CompilationUnitDeclaration unit, IHierarchy structureModel) {
  77. LangUtil.throwIaxIfNull(structureModel, "structureModel");
  78. if (!currCompilationResult.equals(unit.compilationResult())) {
  79. throw new IllegalArgumentException("invalid unit: " + unit);
  80. }
  81. // ---- summary
  82. // add unit to package (or root if no package),
  83. // first removing any duplicate (XXX? removes children if 3 classes in same file?)
  84. // push the node on the stack
  85. // and traverse
  86. // -- create node to add
  87. final File file = new File(new String(unit.getFileName()));
  88. final IProgramElement cuNode;
  89. {
  90. // AMC - use the source start and end from the compilation unit decl
  91. int startLine = getStartLine(unit);
  92. int endLine = getEndLine(unit);
  93. ISourceLocation sourceLocation
  94. = new SourceLocation(file, startLine, endLine);
  95. cuNode = new ProgramElement(
  96. new String(file.getName()),
  97. IProgramElement.Kind.FILE_JAVA,
  98. sourceLocation,
  99. 0,
  100. "",
  101. new ArrayList());
  102. }
  103. cuNode.addChild(new ProgramElement(
  104. "import declarations",
  105. IProgramElement.Kind.IMPORT_REFERENCE,
  106. null,
  107. 0,
  108. "",
  109. new ArrayList()));
  110. final IProgramElement addToNode = genAddToNode(unit, structureModel);
  111. // -- remove duplicates before adding (XXX use them instead?)
  112. if (addToNode!=null && addToNode.getChildren()!=null) {
  113. for (ListIterator itt = addToNode.getChildren().listIterator(); itt.hasNext(); ) {
  114. IProgramElement child = (IProgramElement)itt.next();
  115. ISourceLocation childLoc = child.getSourceLocation();
  116. if (null == childLoc) {
  117. // XXX ok, packages have null source locations
  118. // signal others?
  119. } else if (childLoc.getSourceFile().equals(file)) {
  120. itt.remove();
  121. }
  122. }
  123. }
  124. // -- add and traverse
  125. addToNode.addChild(cuNode);
  126. stack.push(cuNode);
  127. unit.traverse(this, unit.scope);
  128. // -- update file map (XXX do this before traversal?)
  129. try {
  130. structureModel.addToFileMap(file.getCanonicalPath(), cuNode);
  131. } catch (IOException e) {
  132. System.err.println("IOException " + e.getMessage()
  133. + " creating path for " + file );
  134. // XXX signal IOException when canonicalizing file path
  135. }
  136. }
  137. /**
  138. * Get/create the node (package or root) to add to.
  139. */
  140. private IProgramElement genAddToNode(
  141. CompilationUnitDeclaration unit,
  142. IHierarchy structureModel) {
  143. final IProgramElement addToNode;
  144. {
  145. ImportReference currentPackage = unit.currentPackage;
  146. if (null == currentPackage) {
  147. addToNode = structureModel.getRoot();
  148. } else {
  149. String pkgName;
  150. {
  151. StringBuffer nameBuffer = new StringBuffer();
  152. final char[][] importName = currentPackage.getImportName();
  153. final int last = importName.length-1;
  154. for (int i = 0; i < importName.length; i++) {
  155. nameBuffer.append(new String(importName[i]));
  156. if (i < last) {
  157. nameBuffer.append('.');
  158. }
  159. }
  160. pkgName = nameBuffer.toString();
  161. }
  162. IProgramElement pkgNode = null;
  163. if (structureModel!=null && structureModel.getRoot()!=null && structureModel.getRoot().getChildren()!=null) {
  164. for (Iterator it = structureModel.getRoot().getChildren().iterator();
  165. it.hasNext(); ) {
  166. IProgramElement currNode = (IProgramElement)it.next();
  167. if (pkgName.equals(currNode.getName())) {
  168. pkgNode = currNode;
  169. break;
  170. }
  171. }
  172. }
  173. if (pkgNode == null) {
  174. // note packages themselves have no source location
  175. pkgNode = new ProgramElement(
  176. pkgName,
  177. IProgramElement.Kind.PACKAGE,
  178. new ArrayList()
  179. );
  180. structureModel.getRoot().addChild(pkgNode);
  181. }
  182. addToNode = pkgNode;
  183. }
  184. }
  185. return addToNode;
  186. }
  187. public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
  188. String name = new String(typeDeclaration.name);
  189. IProgramElement.Kind kind = IProgramElement.Kind.CLASS;
  190. if (typeDeclaration instanceof AspectDeclaration) kind = IProgramElement.Kind.ASPECT;
  191. else if (typeDeclaration.isInterface()) kind = IProgramElement.Kind.INTERFACE;
  192. IProgramElement peNode = new ProgramElement(
  193. name,
  194. kind,
  195. makeLocation(typeDeclaration),
  196. typeDeclaration.modifiers,
  197. "",
  198. new ArrayList());
  199. peNode.setSourceSignature(genSourceSignature(typeDeclaration));
  200. peNode.setFormalComment(generateJavadocComment(typeDeclaration));
  201. ((IProgramElement)stack.peek()).addChild(peNode);
  202. stack.push(peNode);
  203. return true;
  204. }
  205. public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
  206. stack.pop();
  207. }
  208. // ??? share impl with visit(TypeDeclaration, ..) ?
  209. public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
  210. String name = new String(memberTypeDeclaration.name);
  211. //System.err.println("member type with name: " + name);
  212. IProgramElement.Kind kind = IProgramElement.Kind.CLASS;
  213. if (memberTypeDeclaration instanceof AspectDeclaration) kind = IProgramElement.Kind.ASPECT;
  214. else if (memberTypeDeclaration.isInterface()) kind = IProgramElement.Kind.INTERFACE;
  215. IProgramElement peNode = new ProgramElement(
  216. name,
  217. kind,
  218. makeLocation(memberTypeDeclaration),
  219. memberTypeDeclaration.modifiers,
  220. "",
  221. new ArrayList());
  222. peNode.setSourceSignature(genSourceSignature(memberTypeDeclaration));
  223. peNode.setFormalComment(generateJavadocComment(memberTypeDeclaration));
  224. ((IProgramElement)stack.peek()).addChild(peNode);
  225. stack.push(peNode);
  226. return true;
  227. }
  228. public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
  229. stack.pop();
  230. }
  231. public boolean visit(TypeDeclaration memberTypeDeclaration, BlockScope scope) {
  232. // String name = new String(memberTypeDeclaration.name);
  233. String fullName = "<undefined>";
  234. if (memberTypeDeclaration.binding != null
  235. && memberTypeDeclaration.binding.constantPoolName() != null) {
  236. fullName = new String(memberTypeDeclaration.binding.constantPoolName());
  237. }
  238. int dollar = fullName.indexOf('$');
  239. fullName = fullName.substring(dollar+1);
  240. IProgramElement.Kind kind = IProgramElement.Kind.CLASS;
  241. if (memberTypeDeclaration.isInterface()) kind = IProgramElement.Kind.INTERFACE;
  242. IProgramElement peNode = new ProgramElement(
  243. fullName,
  244. kind,
  245. makeLocation(memberTypeDeclaration),
  246. memberTypeDeclaration.modifiers,
  247. "",
  248. new ArrayList());
  249. peNode.setSourceSignature(genSourceSignature(memberTypeDeclaration));
  250. peNode.setFormalComment(generateJavadocComment(memberTypeDeclaration));
  251. //??? we add this to the compilation unit
  252. findEnclosingClass(stack).addChild(peNode);
  253. stack.push(peNode);
  254. return true;
  255. }
  256. public void endVisit(TypeDeclaration memberTypeDeclaration, BlockScope scope) {
  257. stack.pop();
  258. }
  259. private String genSourceSignature(TypeDeclaration typeDeclaration) {
  260. StringBuffer output = new StringBuffer();
  261. typeDeclaration.printHeader(0, output);
  262. return output.toString();
  263. }
  264. private IProgramElement findEnclosingClass(Stack stack) {
  265. for (int i = stack.size()-1; i >= 0; i--) {
  266. IProgramElement pe = (IProgramElement)stack.get(i);
  267. if (pe.getKind() == IProgramElement.Kind.CLASS) {
  268. return pe;
  269. }
  270. }
  271. return (IProgramElement)stack.peek();
  272. }
  273. public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
  274. IProgramElement peNode = null;
  275. // For intertype decls, use the modifiers from the original signature, not the generated method
  276. if (methodDeclaration instanceof InterTypeDeclaration) {
  277. InterTypeDeclaration itd = (InterTypeDeclaration) methodDeclaration;
  278. ResolvedMember sig = itd.getSignature();
  279. peNode = new ProgramElement(
  280. "",
  281. IProgramElement.Kind.ERROR,
  282. makeLocation(methodDeclaration),
  283. (sig!=null?sig.getModifiers():0),
  284. "",
  285. new ArrayList());
  286. } else {
  287. peNode = new ProgramElement(
  288. "",
  289. IProgramElement.Kind.ERROR,
  290. makeLocation(methodDeclaration),
  291. methodDeclaration.modifiers,
  292. "",
  293. new ArrayList());
  294. }
  295. formatter.genLabelAndKind(methodDeclaration, peNode);
  296. genBytecodeInfo(methodDeclaration, peNode);
  297. if (methodDeclaration.returnType!=null) {
  298. peNode.setCorrespondingType(methodDeclaration.returnType.toString());
  299. } else {
  300. peNode.setCorrespondingType(null);
  301. }
  302. peNode.setSourceSignature(genSourceSignature(methodDeclaration));
  303. peNode.setFormalComment(generateJavadocComment(methodDeclaration));
  304. // TODO: add return type test
  305. if (peNode.getKind().equals(IProgramElement.Kind.METHOD)) {
  306. if (peNode.toLabelString().equals("main(String[])")
  307. && peNode.getModifiers().contains(IProgramElement.Modifiers.STATIC)
  308. && peNode.getAccessibility().equals(IProgramElement.Accessibility.PUBLIC)) {
  309. ((IProgramElement)stack.peek()).setRunnable(true);
  310. }
  311. }
  312. stack.push(peNode);
  313. return true;
  314. }
  315. private String genSourceSignature(MethodDeclaration methodDeclaration) {
  316. StringBuffer output = new StringBuffer();
  317. ASTNode.printModifiers(methodDeclaration.modifiers, output);
  318. methodDeclaration.printReturnType(0, output).append(methodDeclaration.selector).append('(');
  319. if (methodDeclaration.arguments != null) {
  320. for (int i = 0; i < methodDeclaration.arguments.length; i++) {
  321. if (i > 0) output.append(", "); //$NON-NLS-1$
  322. methodDeclaration.arguments[i].print(0, output);
  323. }
  324. }
  325. output.append(')');
  326. if (methodDeclaration.thrownExceptions != null) {
  327. output.append(" throws "); //$NON-NLS-1$
  328. for (int i = 0; i < methodDeclaration.thrownExceptions.length; i++) {
  329. if (i > 0) output.append(", "); //$NON-NLS-1$
  330. methodDeclaration.thrownExceptions[i].print(0, output);
  331. }
  332. }
  333. return output.toString();
  334. }
  335. private void genBytecodeInfo(MethodDeclaration methodDeclaration, IProgramElement peNode) {
  336. if (methodDeclaration.binding != null) {
  337. String memberName = "";
  338. String memberBytecodeSignature = "";
  339. try {
  340. Member member = EclipseFactory.makeResolvedMember(methodDeclaration.binding);
  341. memberName = member.getName();
  342. memberBytecodeSignature = member.getSignature();
  343. } catch (NullPointerException npe) {
  344. memberName = "<undefined>";
  345. }
  346. peNode.setBytecodeName(memberName);
  347. peNode.setBytecodeSignature(memberBytecodeSignature);
  348. }
  349. ((IProgramElement)stack.peek()).addChild(peNode);
  350. }
  351. public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
  352. stack.pop();
  353. }
  354. public boolean visit(ImportReference importRef, CompilationUnitScope scope) {
  355. int dotIndex = importRef.toString().lastIndexOf('.');
  356. String currPackageImport = "";
  357. if (dotIndex != -1) {
  358. currPackageImport = importRef.toString().substring(0, dotIndex);
  359. }
  360. if (!((ProgramElement)stack.peek()).getPackageName().equals(currPackageImport)) {
  361. IProgramElement peNode = new ProgramElement(
  362. new String(importRef.toString()),
  363. IProgramElement.Kind.IMPORT_REFERENCE,
  364. makeLocation(importRef),
  365. 0,
  366. "",
  367. new ArrayList());
  368. ProgramElement imports = (ProgramElement)((ProgramElement)stack.peek()).getChildren().get(0);
  369. imports.addChild(0, peNode);
  370. stack.push(peNode);
  371. }
  372. return true;
  373. }
  374. public void endVisit(ImportReference importRef, CompilationUnitScope scope) {
  375. int dotIndex = importRef.toString().lastIndexOf('.');
  376. String currPackageImport = "";
  377. if (dotIndex != -1) {
  378. currPackageImport = importRef.toString().substring(0, dotIndex);
  379. }
  380. if (!((ProgramElement)stack.peek()).getPackageName().equals(currPackageImport)) {
  381. stack.pop();
  382. }
  383. }
  384. public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
  385. IProgramElement peNode = new ProgramElement(
  386. new String(fieldDeclaration.name),
  387. IProgramElement.Kind.FIELD,
  388. makeLocation(fieldDeclaration),
  389. fieldDeclaration.modifiers,
  390. "",
  391. new ArrayList());
  392. peNode.setCorrespondingType(fieldDeclaration.type.toString());
  393. peNode.setSourceSignature(genSourceSignature(fieldDeclaration));
  394. peNode.setFormalComment(generateJavadocComment(fieldDeclaration));
  395. ((IProgramElement)stack.peek()).addChild(peNode);
  396. stack.push(peNode);
  397. return true;
  398. }
  399. public void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope) {
  400. stack.pop();
  401. }
  402. /**
  403. * Checks if comments should be added to the model before generating.
  404. */
  405. private String generateJavadocComment(ASTNode astNode) {
  406. if (buildConfig != null && !buildConfig.isGenerateJavadocsInModelMode()) return null;
  407. StringBuffer sb = new StringBuffer(); // !!! specify length?
  408. boolean completed = false;
  409. int startIndex = -1;
  410. if (astNode instanceof MethodDeclaration) {
  411. startIndex = ((MethodDeclaration)astNode).declarationSourceStart;
  412. } else if (astNode instanceof FieldDeclaration) {
  413. startIndex = ((FieldDeclaration)astNode).declarationSourceStart;
  414. } else if (astNode instanceof TypeDeclaration) {
  415. startIndex = ((TypeDeclaration)astNode).declarationSourceStart;
  416. }
  417. if (startIndex == -1) {
  418. return null;
  419. } else if (currCompilationResult.compilationUnit.getContents()[startIndex] == '/' // look for /**
  420. && currCompilationResult.compilationUnit.getContents()[startIndex+1] == '*'
  421. && currCompilationResult.compilationUnit.getContents()[startIndex+2] == '*') {
  422. for (int i = startIndex; i < astNode.sourceStart && !completed; i++) {
  423. char curr = currCompilationResult.compilationUnit.getContents()[i];
  424. if (curr == '/' && sb.length() > 2 && sb.charAt(sb.length()-1) == '*') completed = true; // found */
  425. sb.append(currCompilationResult.compilationUnit.getContents()[i]);
  426. }
  427. // System.err.println(">> " + sb.toString());
  428. return sb.toString();
  429. } else {
  430. return null;
  431. }
  432. }
  433. /**
  434. * Doesn't print qualified allocation expressions.
  435. */
  436. private String genSourceSignature(FieldDeclaration fieldDeclaration) {
  437. StringBuffer output = new StringBuffer();
  438. FieldDeclaration.printModifiers(fieldDeclaration.modifiers, output);
  439. fieldDeclaration.type.print(0, output).append(' ').append(fieldDeclaration.name);
  440. if (fieldDeclaration.initialization != null
  441. && !(fieldDeclaration.initialization instanceof QualifiedAllocationExpression)) {
  442. output.append(" = "); //$NON-NLS-1$
  443. if (fieldDeclaration.initialization instanceof ExtendedStringLiteral) {
  444. output.append("\"<extended string literal>\"");
  445. } else {
  446. fieldDeclaration.initialization.printExpression(0, output);
  447. }
  448. }
  449. output.append(';');
  450. return output.toString();
  451. }
  452. // public boolean visit(ImportReference importRef, CompilationUnitScope scope) {
  453. // ProgramElementNode peNode = new ProgramElementNode(
  454. // new String(importRef.toString()),
  455. // ProgramElementNode.Kind.,
  456. // makeLocation(importRef),
  457. // 0,
  458. // "",
  459. // new ArrayList());
  460. // ((IProgramElement)stack.peek()).addChild(0, peNode);
  461. // stack.push(peNode);
  462. // return true;
  463. // }
  464. // public void endVisit(ImportReference importRef,CompilationUnitScope scope) {
  465. // stack.pop();
  466. // }
  467. public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
  468. if (constructorDeclaration.isDefaultConstructor) {
  469. stack.push(null); // a little wierd but does the job
  470. return true;
  471. }
  472. StringBuffer argumentsSignature = new StringBuffer();
  473. argumentsSignature.append("(");
  474. if (constructorDeclaration.arguments!=null) {
  475. for (int i = 0;i<constructorDeclaration.arguments.length;i++) {
  476. argumentsSignature.append(constructorDeclaration.arguments[i]);
  477. if (i+1<constructorDeclaration.arguments.length) argumentsSignature.append(",");
  478. }
  479. }
  480. argumentsSignature.append(")");
  481. IProgramElement peNode = new ProgramElement(
  482. new String(constructorDeclaration.selector)+argumentsSignature,
  483. IProgramElement.Kind.CONSTRUCTOR,
  484. makeLocation(constructorDeclaration),
  485. constructorDeclaration.modifiers,
  486. "",
  487. new ArrayList());
  488. peNode.setModifiers(constructorDeclaration.modifiers);
  489. peNode.setSourceSignature(genSourceSignature(constructorDeclaration));
  490. // Fix to enable us to anchor things from ctor nodes
  491. if (constructorDeclaration.binding != null) {
  492. String memberName = "";
  493. String memberBytecodeSignature = "";
  494. try {
  495. Member member = EclipseFactory.makeResolvedMember(constructorDeclaration.binding);
  496. memberName = member.getName();
  497. memberBytecodeSignature = member.getSignature();
  498. } catch (NullPointerException npe) {
  499. memberName = "<undefined>";
  500. }
  501. peNode.setBytecodeName(memberName);
  502. peNode.setBytecodeSignature(memberBytecodeSignature);
  503. }
  504. ((IProgramElement)stack.peek()).addChild(peNode);
  505. stack.push(peNode);
  506. return true;
  507. }
  508. public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
  509. stack.pop();
  510. }
  511. private String genSourceSignature(ConstructorDeclaration constructorDeclaration) {
  512. StringBuffer output = new StringBuffer();
  513. ASTNode.printModifiers(constructorDeclaration.modifiers, output);
  514. output.append(constructorDeclaration.selector).append('(');
  515. if (constructorDeclaration.arguments != null) {
  516. for (int i = 0; i < constructorDeclaration.arguments.length; i++) {
  517. if (i > 0) output.append(", "); //$NON-NLS-1$
  518. constructorDeclaration.arguments[i].print(0, output);
  519. }
  520. }
  521. output.append(')');
  522. if (constructorDeclaration.thrownExceptions != null) {
  523. output.append(" throws "); //$NON-NLS-1$
  524. for (int i = 0; i < constructorDeclaration.thrownExceptions.length; i++) {
  525. if (i > 0) output.append(", "); //$NON-NLS-1$
  526. constructorDeclaration.thrownExceptions[i].print(0, output);
  527. }
  528. }
  529. return output.toString();
  530. }
  531. // public boolean visit(Clinit clinit, ClassScope scope) {
  532. // ProgramElementNode peNode = new ProgramElementNode(
  533. // "<clinit>",
  534. // ProgramElementNode.Kind.INITIALIZER,
  535. // makeLocation(clinit),
  536. // clinit.modifiers,
  537. // "",
  538. // new ArrayList());
  539. // ((IProgramElement)stack.peek()).addChild(peNode);
  540. // stack.push(peNode);
  541. // return false;
  542. // }
  543. // public void endVisit(Clinit clinit, ClassScope scope) {
  544. // stack.pop();
  545. // }
  546. /** This method works-around an odd traverse implementation on Initializer
  547. */
  548. private Initializer inInitializer = null;
  549. public boolean visit(Initializer initializer, MethodScope scope) {
  550. if (initializer == inInitializer) return false;
  551. inInitializer = initializer;
  552. IProgramElement peNode = new ProgramElement(
  553. "...",
  554. IProgramElement.Kind.INITIALIZER,
  555. makeLocation(initializer),
  556. initializer.modifiers,
  557. "",
  558. new ArrayList());
  559. ((IProgramElement)stack.peek()).addChild(peNode);
  560. stack.push(peNode);
  561. initializer.block.traverse(this, scope);
  562. stack.pop();
  563. return false;
  564. }
  565. // ??? handle non-existant files
  566. private ISourceLocation makeLocation(ASTNode node) {
  567. String fileName = "";
  568. if (currCompilationResult.getFileName() != null) {
  569. fileName = new String(currCompilationResult.getFileName());
  570. }
  571. // AMC - different strategies based on node kind
  572. int startLine = getStartLine(node);
  573. int endLine = getEndLine(node);
  574. ISourceLocation loc = null;
  575. if ( startLine <= endLine ) {
  576. // found a valid end line for this node...
  577. loc = new SourceLocation(new File(fileName), startLine, endLine);
  578. } else {
  579. loc = new SourceLocation(new File(fileName), startLine);
  580. }
  581. return loc;
  582. }
  583. // AMC - overloaded set of methods to get start and end lines for
  584. // various ASTNode types. They have no common ancestor in the
  585. // hierarchy!!
  586. private int getStartLine( ASTNode n){
  587. // if ( n instanceof AbstractVariableDeclaration ) return getStartLine( (AbstractVariableDeclaration)n);
  588. // if ( n instanceof AbstractMethodDeclaration ) return getStartLine( (AbstractMethodDeclaration)n);
  589. // if ( n instanceof TypeDeclaration ) return getStartLine( (TypeDeclaration)n);
  590. return ProblemHandler.searchLineNumber(
  591. currCompilationResult.lineSeparatorPositions,
  592. n.sourceStart);
  593. }
  594. // AMC - overloaded set of methods to get start and end lines for
  595. // various ASTNode types. They have no common ancestor in the
  596. // hierarchy!!
  597. private int getEndLine( ASTNode n){
  598. if ( n instanceof AbstractVariableDeclaration ) return getEndLine( (AbstractVariableDeclaration)n);
  599. if ( n instanceof AbstractMethodDeclaration ) return getEndLine( (AbstractMethodDeclaration)n);
  600. if ( n instanceof TypeDeclaration ) return getEndLine( (TypeDeclaration)n);
  601. return ProblemHandler.searchLineNumber(
  602. currCompilationResult.lineSeparatorPositions,
  603. n.sourceEnd);
  604. }
  605. // AMC - overloaded set of methods to get start and end lines for
  606. // various ASTNode types. They have no common ancestor in the
  607. // hierarchy!!
  608. // private int getStartLine( AbstractVariableDeclaration avd ) {
  609. // return ProblemHandler.searchLineNumber(
  610. // currCompilationResult.lineSeparatorPositions,
  611. // avd.declarationSourceStart);
  612. // }
  613. // AMC - overloaded set of methods to get start and end lines for
  614. // various ASTNode types. They have no common ancestor in the
  615. // hierarchy!!
  616. private int getEndLine( AbstractVariableDeclaration avd ){
  617. return ProblemHandler.searchLineNumber(
  618. currCompilationResult.lineSeparatorPositions,
  619. avd.declarationSourceEnd);
  620. }
  621. // AMC - overloaded set of methods to get start and end lines for
  622. // various ASTNode types. They have no common ancestor in the
  623. // hierarchy!!
  624. // private int getStartLine( AbstractMethodDeclaration amd ){
  625. // return ProblemHandler.searchLineNumber(
  626. // currCompilationResult.lineSeparatorPositions,
  627. // amd.declarationSourceStart);
  628. // }
  629. // AMC - overloaded set of methods to get start and end lines for
  630. // various ASTNode types. They have no common ancestor in the
  631. // hierarchy!!
  632. private int getEndLine( AbstractMethodDeclaration amd) {
  633. return ProblemHandler.searchLineNumber(
  634. currCompilationResult.lineSeparatorPositions,
  635. amd.declarationSourceEnd);
  636. }
  637. // AMC - overloaded set of methods to get start and end lines for
  638. // various ASTNode types. They have no common ancestor in the
  639. // hierarchy!!
  640. // private int getStartLine( TypeDeclaration td ){
  641. // return ProblemHandler.searchLineNumber(
  642. // currCompilationResult.lineSeparatorPositions,
  643. // td.declarationSourceStart);
  644. // }
  645. // AMC - overloaded set of methods to get start and end lines for
  646. // various ASTNode types. They have no common ancestor in the
  647. // hierarchy!!
  648. private int getEndLine( TypeDeclaration td){
  649. return ProblemHandler.searchLineNumber(
  650. currCompilationResult.lineSeparatorPositions,
  651. td.declarationSourceEnd);
  652. }
  653. }