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.

ProgramElement.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. /* *******************************************************************
  2. * Copyright (c) 2003 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Mik Kersten initial implementation
  11. * Andy Clement Extensions for better IDE representation
  12. * ******************************************************************/
  13. package org.aspectj.asm.internal;
  14. import java.util.ArrayList;
  15. import java.util.Collections;
  16. import java.util.HashMap;
  17. import java.util.Iterator;
  18. import java.util.List;
  19. import java.util.Map;
  20. import org.aspectj.asm.AsmManager;
  21. import org.aspectj.asm.HierarchyWalker;
  22. import org.aspectj.asm.INameConvertor;
  23. import org.aspectj.asm.IProgramElement;
  24. import org.aspectj.bridge.IMessage;
  25. import org.aspectj.bridge.ISourceLocation;
  26. import org.aspectj.util.CharOperation;
  27. /**
  28. * @author Mik Kersten
  29. */
  30. public class ProgramElement implements IProgramElement {
  31. private static final long serialVersionUID = 171673495267384449L;
  32. public static boolean shortITDNames = true;
  33. private final static String UNDEFINED = "<undefined>";
  34. private static int AccPublic = 0x0001;
  35. private static int AccPrivate = 0x0002;
  36. private static int AccProtected = 0x0004;
  37. private static int AccPrivileged = 0x0006; // XXX is this right?
  38. private static int AccStatic = 0x0008;
  39. private static int AccFinal = 0x0010;
  40. private static int AccSynchronized = 0x0020;
  41. private static int AccVolatile = 0x0040;
  42. private static int AccTransient = 0x0080;
  43. private static int AccNative = 0x0100;
  44. private static int AccInterface = 0x0200;
  45. private static int AccAbstract = 0x0400;
  46. private static int AccStrictfp = 0x0800;
  47. protected String name;
  48. private Kind kind;
  49. protected IProgramElement parent = null;
  50. protected List children = Collections.EMPTY_LIST;
  51. private Map kvpairs = Collections.EMPTY_MAP;
  52. protected ISourceLocation sourceLocation = null;
  53. private int modifiers;
  54. private String handle = null;
  55. // --- ctors
  56. /** Used during de-externalization */
  57. public ProgramElement() { }
  58. /** Use to create program element nodes that do not correspond to source locations */
  59. public ProgramElement (String name,Kind kind,List children) {
  60. this.name = name;
  61. this.kind = kind;
  62. if (children!=null) setChildren(children);
  63. }
  64. public ProgramElement (String name, IProgramElement.Kind kind, ISourceLocation sourceLocation,
  65. int modifiers, String comment, List children) {
  66. this(name, kind, children);
  67. this.sourceLocation = sourceLocation;
  68. setFormalComment(comment);
  69. // if (comment!=null && comment.length()>0) formalComment = comment;
  70. this.modifiers = modifiers;
  71. // this.accessibility = genAccessibility(modifiers);
  72. }
  73. /**
  74. * Use to create program element nodes that correspond to source locations.
  75. */
  76. public ProgramElement(
  77. String name,
  78. Kind kind,
  79. int modifiers,
  80. //Accessibility accessibility,
  81. String declaringType,
  82. String packageName,
  83. String comment,
  84. ISourceLocation sourceLocation,
  85. List relations,
  86. List children,
  87. boolean member) {
  88. this(name, kind, children);
  89. this.sourceLocation = sourceLocation;
  90. this.kind = kind;
  91. this.modifiers = modifiers;
  92. // this.accessibility = accessibility;
  93. setDeclaringType(declaringType);//this.declaringType = declaringType;
  94. //this.packageName = packageName;
  95. setFormalComment(comment);
  96. // if (comment!=null && comment.length()>0) formalComment = comment;
  97. if (relations!=null && relations.size()!=0) setRelations(relations);
  98. // this.relations = relations;
  99. }
  100. public List getModifiers() {
  101. return genModifiers(modifiers);
  102. }
  103. public Accessibility getAccessibility() {
  104. return genAccessibility(modifiers); // accessibility
  105. }
  106. // public void setAccessibility(Accessibility a) {
  107. //
  108. // //accessibility=a;
  109. // }
  110. public void setDeclaringType(String t) {
  111. if (t!=null && t.length()>0) {
  112. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  113. kvpairs.put("declaringType",t);
  114. }
  115. }
  116. public String getDeclaringType() {
  117. String dt = (String)kvpairs.get("declaringType");
  118. if (dt==null) return ""; // assumption that not having one means "" is at HtmlDecorator line 111
  119. return dt;
  120. }
  121. public String getPackageName() {
  122. if (kind == Kind.PACKAGE) return getName();
  123. if (getParent() == null || !(getParent() instanceof IProgramElement)) {
  124. return "";
  125. }
  126. return ((IProgramElement)getParent()).getPackageName();
  127. }
  128. public Kind getKind() {
  129. return kind;
  130. }
  131. public boolean isCode() {
  132. return kind.equals(Kind.CODE);
  133. }
  134. public ISourceLocation getSourceLocation() {
  135. return sourceLocation;
  136. }
  137. public void setSourceLocation(ISourceLocation sourceLocation) {
  138. //this.sourceLocation = sourceLocation;
  139. }
  140. public IMessage getMessage() {
  141. return (IMessage)kvpairs.get("message");
  142. // return message;
  143. }
  144. public void setMessage(IMessage message) {
  145. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  146. kvpairs.put("message",message);
  147. // this.message = message;
  148. }
  149. public IProgramElement getParent() {
  150. return parent;
  151. }
  152. public void setParent(IProgramElement parent) {
  153. this.parent = parent;
  154. }
  155. public boolean isMemberKind() {
  156. return kind.isMember();
  157. }
  158. public void setRunnable(boolean value) {
  159. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  160. if (value) kvpairs.put("isRunnable","true");
  161. else kvpairs.remove("isRunnable");
  162. // this.runnable = value;
  163. }
  164. public boolean isRunnable() {
  165. return kvpairs.get("isRunnable")!=null;
  166. // return runnable;
  167. }
  168. public boolean isImplementor() {
  169. return kvpairs.get("isImplementor")!=null;
  170. // return implementor;
  171. }
  172. public void setImplementor(boolean value) {
  173. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  174. if (value) kvpairs.put("isImplementor","true");
  175. else kvpairs.remove("isImplementor");
  176. // this.implementor = value;
  177. }
  178. public boolean isOverrider() {
  179. return kvpairs.get("isOverrider")!=null;
  180. // return overrider;
  181. }
  182. public void setOverrider(boolean value) {
  183. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  184. if (value) kvpairs.put("isOverrider","true");
  185. else kvpairs.remove("isOverrider");
  186. // this.overrider = value;
  187. }
  188. public List getRelations() {
  189. return (List)kvpairs.get("relations");
  190. // return relations;
  191. }
  192. public void setRelations(List relations) {
  193. if (relations.size() > 0) {
  194. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  195. kvpairs.put("relations",relations);
  196. // this.relations = relations;
  197. }
  198. }
  199. public String getFormalComment() {
  200. return (String)kvpairs.get("formalComment");
  201. // return formalComment;
  202. }
  203. public String toString() {
  204. return toLabelString();
  205. }
  206. private static List genModifiers(int modifiers) {
  207. List modifiersList = new ArrayList();
  208. if ((modifiers & AccStatic) != 0) modifiersList.add(IProgramElement.Modifiers.STATIC);
  209. if ((modifiers & AccFinal) != 0) modifiersList.add(IProgramElement.Modifiers.FINAL);
  210. if ((modifiers & AccSynchronized) != 0) modifiersList.add(IProgramElement.Modifiers.SYNCHRONIZED);
  211. if ((modifiers & AccVolatile) != 0) modifiersList.add(IProgramElement.Modifiers.VOLATILE);
  212. if ((modifiers & AccTransient) != 0) modifiersList.add(IProgramElement.Modifiers.TRANSIENT);
  213. if ((modifiers & AccNative) != 0) modifiersList.add(IProgramElement.Modifiers.NATIVE);
  214. if ((modifiers & AccAbstract) != 0) modifiersList.add(IProgramElement.Modifiers.ABSTRACT);
  215. return modifiersList;
  216. }
  217. public static IProgramElement.Accessibility genAccessibility(int modifiers) {
  218. if ((modifiers & AccPublic) != 0) return IProgramElement.Accessibility.PUBLIC;
  219. if ((modifiers & AccPrivate) != 0) return IProgramElement.Accessibility.PRIVATE;
  220. if ((modifiers & AccProtected) != 0) return IProgramElement.Accessibility.PROTECTED;
  221. if ((modifiers & AccPrivileged) != 0) return IProgramElement.Accessibility.PRIVILEGED;
  222. else return IProgramElement.Accessibility.PACKAGE;
  223. }
  224. public String getBytecodeName() {
  225. String s = (String)kvpairs.get("bytecodeName");
  226. if (s==null) return UNDEFINED;
  227. return s;
  228. }
  229. public String getBytecodeSignature() {
  230. String s = (String)kvpairs.get("bytecodeSignature");
  231. // if (s==null) return UNDEFINED;
  232. return s;
  233. }
  234. public void setBytecodeName(String s) {
  235. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  236. kvpairs.put("bytecodeName",s);
  237. }
  238. public void setBytecodeSignature(String s) {
  239. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  240. kvpairs.put("bytecodeSignature",s);
  241. }
  242. public String getSourceSignature() {
  243. return (String)kvpairs.get("sourceSignature");
  244. }
  245. public void setSourceSignature(String string) {
  246. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  247. // System.err.println(name+" SourceSig=>"+string);
  248. kvpairs.put("sourceSignature",string);
  249. // sourceSignature = string;
  250. }
  251. public void setKind(Kind kind) {
  252. this.kind = kind;
  253. }
  254. public void setCorrespondingType(String s) {
  255. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  256. kvpairs.put("returnType",s);
  257. // this.returnType = s;
  258. }
  259. public String getCorrespondingType() {
  260. return getCorrespondingType(false);
  261. }
  262. public String getCorrespondingType(boolean getFullyQualifiedType) {
  263. String returnType = (String)kvpairs.get("returnType");
  264. if (returnType==null) returnType="";
  265. if (getFullyQualifiedType) {
  266. return returnType;
  267. }
  268. int index = returnType.lastIndexOf(".");
  269. if (index != -1) {
  270. return returnType.substring(index);
  271. }
  272. return returnType;
  273. }
  274. public String getName() {
  275. return name;
  276. }
  277. public List getChildren() {
  278. return children;
  279. }
  280. public void setChildren(List children) {
  281. this.children = children;
  282. if (children == null) return;
  283. for (Iterator it = children.iterator(); it.hasNext(); ) {
  284. ((IProgramElement)it.next()).setParent(this);
  285. }
  286. }
  287. public void addChild(IProgramElement child) {
  288. if (children == null || children==Collections.EMPTY_LIST) children = new ArrayList();
  289. children.add(child);
  290. child.setParent(this);
  291. }
  292. public void addChild(int position, IProgramElement child) {
  293. if (children == null || children==Collections.EMPTY_LIST) children = new ArrayList();
  294. children.add(position, child);
  295. child.setParent(this);
  296. }
  297. public boolean removeChild(IProgramElement child) {
  298. child.setParent(null);
  299. return children.remove(child);
  300. }
  301. public void setName(String string) {
  302. name = string;
  303. }
  304. public IProgramElement walk(HierarchyWalker walker) {
  305. if (children!=null) {
  306. for (Iterator it = children.iterator(); it.hasNext(); ) {
  307. IProgramElement child = (IProgramElement)it.next();
  308. walker.process(child);
  309. }
  310. }
  311. return this;
  312. }
  313. public String toLongString() {
  314. final StringBuffer buffer = new StringBuffer();
  315. HierarchyWalker walker = new HierarchyWalker() {
  316. private int depth = 0;
  317. public void preProcess(IProgramElement node) {
  318. for (int i = 0; i < depth; i++) buffer.append(' ');
  319. buffer.append(node.toString());
  320. buffer.append('\n');
  321. depth += 2;
  322. }
  323. public void postProcess(IProgramElement node) {
  324. depth -= 2;
  325. }
  326. };
  327. walker.process(this);
  328. return buffer.toString();
  329. }
  330. public void setModifiers(int i) {
  331. this.modifiers = i;
  332. }
  333. public String toSignatureString() {
  334. return toSignatureString(true);
  335. }
  336. public String toSignatureString(boolean getFullyQualifiedArgTypes) {
  337. StringBuffer sb = new StringBuffer();
  338. sb.append(name);
  339. List ptypes = getParameterTypes();
  340. if (ptypes != null && (!ptypes.isEmpty()
  341. || this.kind.equals(IProgramElement.Kind.METHOD))
  342. || this.kind.equals(IProgramElement.Kind.CONSTRUCTOR)
  343. || this.kind.equals(IProgramElement.Kind.ADVICE)
  344. || this.kind.equals(IProgramElement.Kind.POINTCUT)
  345. || this.kind.equals(IProgramElement.Kind.INTER_TYPE_METHOD)
  346. || this.kind.equals(IProgramElement.Kind.INTER_TYPE_CONSTRUCTOR)) {
  347. sb.append('(');
  348. for (Iterator it = ptypes.iterator(); it.hasNext(); ) {
  349. char[] arg = (char[])it.next();
  350. if (getFullyQualifiedArgTypes) {
  351. sb.append(arg);
  352. } else {
  353. int index = CharOperation.lastIndexOf('.',arg);
  354. if (index != -1) {
  355. sb.append(CharOperation.subarray(arg,index+1,arg.length));
  356. } else {
  357. sb.append(arg);
  358. }
  359. }
  360. if (it.hasNext()) sb.append(",");
  361. }
  362. sb.append(')');
  363. }
  364. return sb.toString();
  365. }
  366. /**
  367. * TODO: move the "parent != null"==>injar heuristic to more explicit
  368. */
  369. public String toLinkLabelString() {
  370. return toLinkLabelString(true);
  371. }
  372. public String toLinkLabelString(boolean getFullyQualifiedArgTypes) {
  373. String label;
  374. if (kind == Kind.CODE || kind == Kind.INITIALIZER) {
  375. label = parent.getParent().getName() + ": ";
  376. } else if (kind.isInterTypeMember()) {
  377. if (shortITDNames) {
  378. // if (name.indexOf('.')!=-1) return toLabelString().substring(name.indexOf('.')+1);
  379. label="";
  380. } else {
  381. int dotIndex = name.indexOf('.');
  382. if (dotIndex != -1) {
  383. return parent.getName() + ": " + toLabelString().substring(dotIndex+1);
  384. } else {
  385. label = parent.getName() + '.';
  386. }
  387. }
  388. } else if (kind == Kind.CLASS || kind == Kind.ASPECT || kind == Kind.INTERFACE) {
  389. label = "";
  390. } else if (kind.equals(Kind.DECLARE_PARENTS)) {
  391. label = "";
  392. } else {
  393. if (parent != null) {
  394. label = parent.getName() + '.';
  395. } else {
  396. label = "injar aspect: ";
  397. }
  398. }
  399. label += toLabelString(getFullyQualifiedArgTypes);
  400. return label;
  401. }
  402. public String toLabelString() {
  403. return toLabelString(true);
  404. }
  405. public String toLabelString(boolean getFullyQualifiedArgTypes) {
  406. String label = toSignatureString(getFullyQualifiedArgTypes);
  407. String details = getDetails();
  408. if (details != null) {
  409. label += ": " + details;
  410. }
  411. return label;
  412. }
  413. public String getHandleIdentifier() {
  414. if (null == handle) {
  415. if (sourceLocation != null) {
  416. handle = AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceLocation);
  417. // return genHandleIdentifier(sourceLocation);
  418. }
  419. }
  420. return handle;
  421. }
  422. public List getParameterNames() {
  423. List parameterNames = (List)kvpairs.get("parameterNames");
  424. return parameterNames;
  425. }
  426. public void setParameterNames(List list) {
  427. if (list==null || list.size()==0) return;
  428. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  429. kvpairs.put("parameterNames",list);
  430. //parameterNames = list;
  431. }
  432. public List getParameterTypes() {
  433. List l = getParameterSignatures();
  434. if (l == null || l.isEmpty()) {
  435. return Collections.EMPTY_LIST;
  436. }
  437. List params = new ArrayList();
  438. for (Iterator iter = l.iterator(); iter.hasNext();) {
  439. char[] param = (char[])iter.next();
  440. INameConvertor convertor = AsmManager.getDefault().getHierarchy().getNameConvertor();
  441. if (convertor != null) {
  442. params.add(convertor.convertName(param));
  443. } else {
  444. params.add(param);
  445. }
  446. }
  447. return params;
  448. }
  449. public List getParameterSignatures() {
  450. List parameters = (List)kvpairs.get("parameterSigs");
  451. return parameters;
  452. }
  453. public void setParameterSignatures(List list) {
  454. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  455. if (list==null || list.size()==0) kvpairs.put("parameterSigs",Collections.EMPTY_LIST);
  456. else kvpairs.put("parameterSigs",list);
  457. }
  458. public String getDetails() {
  459. String details = (String)kvpairs.get("details");
  460. return details;
  461. }
  462. public void setDetails(String string) {
  463. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  464. kvpairs.put("details",string);
  465. }
  466. public void setFormalComment(String txt) {
  467. if (txt!=null && txt.length()>0) {
  468. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  469. kvpairs.put("formalComment",txt);
  470. }
  471. }
  472. /** AMC added to speed up findByHandle lookups in AspectJElementHierarchy */
  473. private void cacheByHandle() {
  474. String handle = getHandleIdentifier();
  475. if (handle != null) {
  476. AspectJElementHierarchy hierarchy = (AspectJElementHierarchy)
  477. AsmManager.getDefault().getHierarchy();
  478. hierarchy.cache(handle,this);
  479. //System.err.println("Cache size now "+hierarchy.handleMap.size());
  480. }
  481. }
  482. public void setExtraInfo(ExtraInformation info) {
  483. if (kvpairs==Collections.EMPTY_MAP) kvpairs = new HashMap();
  484. kvpairs.put("ExtraInformation",info);
  485. }
  486. public ExtraInformation getExtraInfo() {
  487. return (ExtraInformation)kvpairs.get("ExtraInformation");
  488. }
  489. }