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.

SymbolManager.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Common Public License v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/cpl-v10.html
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * Mik Kersten port to AspectJ 1.1+ code base
  13. * ******************************************************************/
  14. package org.aspectj.tools.ajdoc;
  15. import java.util.*;
  16. import org.aspectj.asm.*;
  17. /**
  18. * @author Mik Kersten
  19. */
  20. public class SymbolManager {
  21. private static SymbolManager INSTANCE = new SymbolManager();
  22. public static SymbolManager getDefault() {
  23. return INSTANCE;
  24. }
  25. /**
  26. * TODO: only works for one class
  27. */
  28. public Declaration[] getDeclarations(String filename) {
  29. IProgramElement file = (IProgramElement)AsmManager.getDefault().getHierarchy().findElementForSourceFile(filename);
  30. IProgramElement node = (IProgramElement)file.getChildren().get(0);
  31. // Declaration[] decls = new Declaration[node.getChildren().size()+1];
  32. final List nodes = new ArrayList();
  33. HierarchyWalker walker = new HierarchyWalker() {
  34. public void preProcess(IProgramElement node) {
  35. IProgramElement p = (IProgramElement)node;
  36. if (accept(node)) nodes.add(buildDecl(p));
  37. }
  38. };
  39. file.walk(walker);
  40. return (Declaration[])nodes.toArray(new Declaration[nodes.size()]);
  41. }
  42. /**
  43. * Rejects anonymous kinds by checking if their name is an integer
  44. */
  45. private boolean accept(IProgramElement node) {
  46. if (node.getKind().isType()) {
  47. boolean isAnonymous = StructureUtil.isAnonymous(node);
  48. return !node.getParent().getKind().equals(IProgramElement.Kind.METHOD)
  49. && !isAnonymous;
  50. } else {
  51. return !node.getKind().equals(IProgramElement.Kind.IMPORT_REFERENCE);
  52. }
  53. // && !(node.getKind().isType() &&
  54. // node.getParent().getKind().equals(IProgramElement.Kind.METHOD));
  55. }
  56. private Declaration buildDecl(IProgramElement node) {
  57. String signature = "";
  58. String accessibility = node.getAccessibility().toString();
  59. if (!accessibility.equals("package")) signature = accessibility.toString() + " ";
  60. String modifiers = "";
  61. if (!node.getAccessibility().equals(IProgramElement.Accessibility.PACKAGE)) modifiers += node.getAccessibility() + " ";
  62. for (Iterator modIt = node.getModifiers().iterator(); modIt.hasNext(); ) {
  63. modifiers += modIt.next() + " ";
  64. }
  65. if (node.getKind().equals(IProgramElement.Kind.METHOD) ||
  66. node.getKind().equals(IProgramElement.Kind.FIELD)) {
  67. signature += node.getCorrespondingType() + " ";
  68. }
  69. if (node.getKind().equals(IProgramElement.Kind.CLASS) ||
  70. node.getKind().equals(IProgramElement.Kind.METHOD)) {
  71. signature += "class ";
  72. } else if (node.getKind().equals(IProgramElement.Kind.INTERFACE) ||
  73. node.getKind().equals(IProgramElement.Kind.METHOD)) {
  74. signature += "interface ";
  75. }
  76. signature += node.toSignatureString();
  77. String name = node.getName();
  78. if (node.getKind().isType()) {
  79. name = genPartiallyQualifiedName(node, node.getName());
  80. }
  81. String declaringType = node.getParent().getName();
  82. // if (!node.getKind().isType()) {
  83. // declaringType = node.getParent().getName();
  84. // }
  85. Declaration dec = new Declaration(
  86. node.getSourceLocation().getLine(),
  87. node.getSourceLocation().getEndLine(),
  88. node.getSourceLocation().getColumn(),
  89. -1,
  90. modifiers,
  91. name,
  92. signature,
  93. "", // crosscut designator
  94. node.getDeclaringType(),
  95. node.getKind().toString(),
  96. node.getSourceLocation().getSourceFile().getAbsolutePath(),
  97. node.getFormalComment(),
  98. node.getPackageName(),
  99. node
  100. );
  101. return dec;
  102. }
  103. // // In the unusual case that there are multiple declarations on a single line
  104. // // This will return a random one
  105. // public Declaration getDeclarationAtLine(String filename, int line) {
  106. // return getDeclarationAtPoint(filename, line, -1);
  107. // }
  108. private String genPartiallyQualifiedName(IProgramElement node, String name) {
  109. // if (node.getParent() != null) System.err.println("%%% " + node.getParent());
  110. if (node.getParent() != null && node.getParent().getKind().isType()) {
  111. name = node.getParent().getName() + '.' + name;
  112. genPartiallyQualifiedName(node.getParent(), name);
  113. }
  114. return name;
  115. }
  116. public Declaration getDeclarationAtPoint(String filename, int line, int column) {
  117. Declaration[] declarations = lookupDeclarations(filename);
  118. //System.out.println("getting "+filename+", "+line+":"+column);
  119. //System.out.println("decs: "+declarations);
  120. return getDeclarationAtPoint(declarations, line, column);
  121. }
  122. public Declaration getDeclarationAtPoint(Declaration[] declarations, int line, int column) {
  123. //!!! when we care about the performance of this method
  124. //!!! these should be guaranteed to be sorted and a binary search used here
  125. //!!! for now we use the simple (and reliable) linear search
  126. if (declarations == null) return null;
  127. for(int i=0; i<declarations.length; i++) {
  128. Declaration dec = declarations[i];
  129. if (dec.getBeginLine() == line) { // && dec.getEndLine() >= line) {
  130. if (column == -1) return dec;
  131. if (dec.getBeginColumn() == column) { // && dec.getEndColumn() >= column) {
  132. return dec;
  133. }
  134. }
  135. Declaration[] enclosedDecs = dec.getDeclarations();
  136. if (enclosedDecs.length == 0) continue;
  137. Declaration dec1 = getDeclarationAtPoint(enclosedDecs, line, column);
  138. if (dec1 != null) return dec1;
  139. }
  140. //??? what should be returned for no declaration found
  141. return null;
  142. }
  143. // private Hashtable symbolFileEntryCache = new Hashtable();
  144. private Declaration[] lookupDeclarations(String filename) {
  145. System.err.println("> looking up: " + filename);
  146. return null;
  147. // CorrFileEntry entry = lookup(filename, mapFilenameToSymbolFile(filename),
  148. // symbolFileEntryCache);
  149. // return (Declaration[])entry.data;
  150. }
  151. // private Hashtable sourceToOutputCache = new Hashtable();
  152. // private Hashtable outputToSourceCache = new Hashtable();
  153. // private Map lookupSourceToOutput(String filename) {
  154. // CorrFileEntry entry = lookup(filename,
  155. // getSourceToOutputFile(new File(filename).getParent()),
  156. // sourceToOutputCache);
  157. // return (Map)entry.data;
  158. // }
  159. // private Map lookupOutputToSource(String filename) {
  160. // CorrFileEntry entry = lookup(filename,
  161. // getOutputToSourceFile(new File(filename).getParent()),
  162. // outputToSourceCache);
  163. // return (Map)entry.data;
  164. // }
  165. /* generic code for dealing with correlation files, serialization, and caching */
  166. // private static class CorrFileEntry {
  167. // public long lastModified;
  168. // public Object data;
  169. //
  170. // public CorrFileEntry(long lastModified, Object data) {
  171. // this.lastModified = lastModified;
  172. // this.data = data;
  173. // }
  174. // }
  175. // private CorrFileEntry lookup(String filename, File file, Hashtable cache) {
  176. // CorrFileEntry entry = (CorrFileEntry)cache.get(filename);
  177. // if (entry != null && entry.lastModified == file.lastModified()) {
  178. // return entry;
  179. // }
  180. //
  181. // entry = createCorrFileEntry(file);
  182. // cache.put(filename, entry);
  183. // return entry;
  184. // }
  185. // private CorrFileEntry createCorrFileEntry(File file) {
  186. // if (!file.exists()) {
  187. // return new CorrFileEntry(0l, null);
  188. // }
  189. //
  190. // try {
  191. // long lastModified = file.lastModified();
  192. // ObjectInputStream stream =
  193. // new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
  194. // Object data = stream.readObject();
  195. // stream.close();
  196. // return new CorrFileEntry(lastModified, data);
  197. // } catch (IOException ioe) {
  198. // //System.err.println("ERROR!!!");
  199. // //ioe.printStackTrace();
  200. // return new CorrFileEntry(0l, null);
  201. // } catch (ClassNotFoundException cce) {
  202. // //System.err.println("ERROR!!!");
  203. // //cce.printStackTrace();
  204. // return new CorrFileEntry(0l, null);
  205. // }
  206. // }
  207. /**
  208. * @param methodName method name without type or parameter list
  209. * @return method name with ajc-specific name mangling removed,
  210. * unchanged if there's not ajc name mangling present
  211. */
  212. public static String translateMethodName(String methodName) {
  213. int firstDollar = methodName.indexOf('$');
  214. if (firstDollar == -1) return methodName;
  215. String baseName = methodName.substring(firstDollar);
  216. if (methodName.indexOf("ajc") != -1) {
  217. return "<" + baseName + " advice>";
  218. } else {
  219. return baseName;
  220. }
  221. }
  222. /************************************************************************
  223. The rest of the code in this file is just for testing purposes
  224. ************************************************************************/
  225. // private static final void printIndentation(int indent, String prefix) {
  226. // for(int i=0; i< indent; i++) System.out.print(" ");
  227. // System.out.print(prefix);
  228. // }
  229. //
  230. //
  231. // private static final void printDeclaration(Declaration dec, int indent, String prefix) {
  232. // printIndentation(indent, prefix);
  233. // if (dec == null) {
  234. // System.out.println("null");
  235. // return;
  236. // }
  237. //
  238. // System.out.println(dec.getKind()+": "+dec.getDeclaringType()+": "+
  239. // dec.getModifiers()+": "+dec.getSignature()+": " +
  240. // //dec.getFullSignature()+": "+
  241. // dec.getCrosscutDesignator()+
  242. // ": "+dec.isIntroduced()+": "+dec.getPackageName()+": "+dec.getBeginLine()+":"+dec.getBeginColumn()
  243. // );
  244. //
  245. // //printIndentation(indent, "\"\"\"");
  246. // //System.out.println(dec.getFormalComment());
  247. // /*
  248. // if (dec.getParentDeclaration() != null) {
  249. // printDeclaration(dec.getParentDeclaration(), indent+INDENT, "PARENT ");
  250. // }
  251. // if (dec.getCrosscutDeclaration() != null) {
  252. // printDeclaration(dec.getCrosscutDeclaration(), indent+INDENT, "XC ");
  253. // }
  254. // */
  255. // if (prefix.equals("")) {
  256. // printDeclarations(dec.getTargets(), indent+INDENT, "T> ");
  257. // printDeclarations(dec.getPointsTo(), indent+INDENT, ">> ");
  258. // printDeclarations(dec.getPointedToBy(), indent+INDENT, "<< ");
  259. // printDeclarations(dec.getDeclarations(), indent+INDENT, "");
  260. // }
  261. // }
  262. // private static final void printDeclarations(Declaration[] decs, int indent, String prefix) {
  263. // for(int i=0; i<decs.length; i++) {
  264. // printDeclaration(decs[i], indent, prefix);
  265. // }
  266. // }
  267. // private static final int INDENT = 2;
  268. // static void printLines(String filename, Map baseMap) throws IOException {
  269. // if (baseMap == null) return;
  270. //
  271. // String fullName = new File(filename).getCanonicalPath();
  272. // java.util.TreeMap map = new java.util.TreeMap();
  273. //
  274. // for (Iterator i = baseMap.entrySet().iterator(); i.hasNext(); ) {
  275. // Map.Entry entry = (Map.Entry)i.next();
  276. // SourceLine keyLine = (SourceLine)entry.getKey();
  277. // if (!keyLine.filename.equals(fullName)) continue;
  278. //
  279. // map.put(new Integer(keyLine.line), entry.getValue());
  280. // }
  281. //
  282. // for (java.util.Iterator j = map.entrySet().iterator(); j.hasNext(); ) {
  283. // java.util.Map.Entry entry = (java.util.Map.Entry)j.next();
  284. //
  285. // System.out.println(entry.getKey() + ":\t" + entry.getValue());
  286. // }
  287. // }
  288. // public static void main(String[] args) throws IOException {
  289. // for(int i=0; i<args.length; i++) {
  290. // String filename = args[i];
  291. // System.out.println(filename);
  292. //
  293. // System.out.println("declaration mappings");
  294. // System.out.println("kind: declaringType: modifiers: signature: fullSignature: crosscutDesignator: isIntroduced: packageName: parentDeclaration");
  295. //
  296. // Declaration[] declarations = getSymbolManager().getDeclarations(filename);
  297. // if (declarations != null) {
  298. // printDeclarations(declarations, INDENT, "");
  299. // }
  300. //
  301. // System.out.println("source to output");
  302. // printLines(filename, getSymbolManager().lookupSourceToOutput(filename));
  303. // System.out.println("output to source");
  304. // printLines(filename, getSymbolManager().lookupOutputToSource(filename));
  305. // }
  306. // }
  307. }