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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. /* *******************************************************************
  2. * Copyright (c) 2003,2010 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License 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. * Mik Kersten initial implementation
  11. * Andy Clement, IBM, SpringSource 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.IProgramElement;
  23. import org.aspectj.bridge.IMessage;
  24. import org.aspectj.bridge.ISourceLocation;
  25. /**
  26. * @author Mik Kersten
  27. * @author Andy Clement
  28. */
  29. public class ProgramElement implements IProgramElement {
  30. public transient AsmManager asm; // which structure model is this node part of
  31. private static final long serialVersionUID = 171673495267384449L;
  32. public static boolean shortITDNames = true;
  33. private final static String UNDEFINED = "<undefined>";
  34. private final static int AccPublic = 0x0001;
  35. private final static int AccPrivate = 0x0002;
  36. private final static int AccProtected = 0x0004;
  37. private final static int AccPrivileged = 0x0006; // XXX is this right?
  38. private final static int AccStatic = 0x0008;
  39. private final static int AccFinal = 0x0010;
  40. private final static int AccSynchronized = 0x0020;
  41. private final static int AccVolatile = 0x0040;
  42. private final static int AccTransient = 0x0080;
  43. private final static int AccNative = 0x0100;
  44. // private final static int AccInterface = 0x0200;
  45. private final static int AccAbstract = 0x0400;
  46. // private final static int AccStrictfp = 0x0800;
  47. protected String name;
  48. private Kind kind;
  49. protected IProgramElement parent = null;
  50. protected List<IProgramElement> children = Collections.emptyList();
  51. public Map<String, Object> kvpairs = Collections.emptyMap();
  52. protected ISourceLocation sourceLocation = null;
  53. public int modifiers;
  54. private String handle = null;
  55. public AsmManager getModel() {
  56. return asm;
  57. }
  58. /** Used during deserialization */
  59. public ProgramElement() {
  60. }
  61. /** Use to create program element nodes that do not correspond to source locations */
  62. public ProgramElement(AsmManager asm, String name, Kind kind, List<IProgramElement> children) {
  63. this.asm = asm;
  64. if (asm == null && !name.equals("<build to view structure>")) {
  65. throw new RuntimeException();
  66. }
  67. this.name = name;
  68. this.kind = kind;
  69. if (children != null) {
  70. setChildren(children);
  71. }
  72. }
  73. public ProgramElement(AsmManager asm, String name, IProgramElement.Kind kind, ISourceLocation sourceLocation, int modifiers,
  74. String comment, List<IProgramElement> children) {
  75. this(asm, name, kind, children);
  76. this.sourceLocation = sourceLocation;
  77. setFormalComment(comment);
  78. // if (comment!=null && comment.length()>0) formalComment = comment;
  79. this.modifiers = modifiers;
  80. }
  81. public int getRawModifiers() {
  82. return this.modifiers;
  83. }
  84. public List<IProgramElement.Modifiers> getModifiers() {
  85. return genModifiers(this.modifiers);
  86. }
  87. public Accessibility getAccessibility() {
  88. return genAccessibility(this.modifiers);
  89. }
  90. public void setDeclaringType(String t) {
  91. if (t != null && t.length() > 0) {
  92. fixMap();
  93. kvpairs.put("declaringType", t);
  94. }
  95. }
  96. public String getDeclaringType() {
  97. String dt = (String) kvpairs.get("declaringType");
  98. if (dt == null) {
  99. return ""; // assumption that not having one means "" is at HtmlDecorator line 111
  100. }
  101. return dt;
  102. }
  103. public String getPackageName() {
  104. if (kind == Kind.PACKAGE) {
  105. return getName();
  106. }
  107. if (getParent() == null) {
  108. return "";
  109. }
  110. return getParent().getPackageName();
  111. }
  112. public Kind getKind() {
  113. return kind;
  114. }
  115. public boolean isCode() {
  116. return kind.equals(Kind.CODE);
  117. }
  118. public ISourceLocation getSourceLocation() {
  119. return sourceLocation;
  120. }
  121. // not really sure why we have this setter ... how can we be in the situation where we didn't
  122. // know the location when we built the node but we learned it later on?
  123. public void setSourceLocation(ISourceLocation sourceLocation) {
  124. // this.sourceLocation = sourceLocation;
  125. }
  126. public IMessage getMessage() {
  127. return (IMessage) kvpairs.get("message");
  128. // return message;
  129. }
  130. public void setMessage(IMessage message) {
  131. fixMap();
  132. kvpairs.put("message", message);
  133. // this.message = message;
  134. }
  135. public IProgramElement getParent() {
  136. return parent;
  137. }
  138. public void setParent(IProgramElement parent) {
  139. this.parent = parent;
  140. }
  141. public boolean isMemberKind() {
  142. return kind.isMember();
  143. }
  144. public void setRunnable(boolean value) {
  145. fixMap();
  146. if (value) {
  147. kvpairs.put("isRunnable", "true");
  148. } else {
  149. kvpairs.remove("isRunnable");
  150. // this.runnable = value;
  151. }
  152. }
  153. public boolean isRunnable() {
  154. return kvpairs.get("isRunnable") != null;
  155. // return runnable;
  156. }
  157. public boolean isImplementor() {
  158. return kvpairs.get("isImplementor") != null;
  159. // return implementor;
  160. }
  161. public void setImplementor(boolean value) {
  162. fixMap();
  163. if (value) {
  164. kvpairs.put("isImplementor", "true");
  165. } else {
  166. kvpairs.remove("isImplementor");
  167. // this.implementor = value;
  168. }
  169. }
  170. public boolean isOverrider() {
  171. return kvpairs.get("isOverrider") != null;
  172. // return overrider;
  173. }
  174. public void setOverrider(boolean value) {
  175. fixMap();
  176. if (value) {
  177. kvpairs.put("isOverrider", "true");
  178. } else {
  179. kvpairs.remove("isOverrider");
  180. // this.overrider = value;
  181. }
  182. }
  183. public String getFormalComment() {
  184. return (String) kvpairs.get("formalComment");
  185. // return formalComment;
  186. }
  187. public String toString() {
  188. return toLabelString();
  189. }
  190. private static List<IProgramElement.Modifiers> genModifiers(int modifiers) {
  191. List<IProgramElement.Modifiers> modifiersList = new ArrayList<>();
  192. if ((modifiers & AccStatic) != 0) {
  193. modifiersList.add(IProgramElement.Modifiers.STATIC);
  194. }
  195. if ((modifiers & AccFinal) != 0) {
  196. modifiersList.add(IProgramElement.Modifiers.FINAL);
  197. }
  198. if ((modifiers & AccSynchronized) != 0) {
  199. modifiersList.add(IProgramElement.Modifiers.SYNCHRONIZED);
  200. }
  201. if ((modifiers & AccVolatile) != 0) {
  202. modifiersList.add(IProgramElement.Modifiers.VOLATILE);
  203. }
  204. if ((modifiers & AccTransient) != 0) {
  205. modifiersList.add(IProgramElement.Modifiers.TRANSIENT);
  206. }
  207. if ((modifiers & AccNative) != 0) {
  208. modifiersList.add(IProgramElement.Modifiers.NATIVE);
  209. }
  210. if ((modifiers & AccAbstract) != 0) {
  211. modifiersList.add(IProgramElement.Modifiers.ABSTRACT);
  212. }
  213. return modifiersList;
  214. }
  215. public static IProgramElement.Accessibility genAccessibility(int modifiers) {
  216. if ((modifiers & AccPublic) != 0) {
  217. return IProgramElement.Accessibility.PUBLIC;
  218. }
  219. if ((modifiers & AccPrivate) != 0) {
  220. return IProgramElement.Accessibility.PRIVATE;
  221. }
  222. if ((modifiers & AccProtected) != 0) {
  223. return IProgramElement.Accessibility.PROTECTED;
  224. }
  225. if ((modifiers & AccPrivileged) != 0) {
  226. return IProgramElement.Accessibility.PRIVILEGED;
  227. } else {
  228. return IProgramElement.Accessibility.PACKAGE;
  229. }
  230. }
  231. public String getBytecodeName() {
  232. String s = (String) kvpairs.get("bytecodeName");
  233. if (s == null) {
  234. return UNDEFINED;
  235. }
  236. return s;
  237. }
  238. public void setBytecodeName(String s) {
  239. fixMap();
  240. kvpairs.put("bytecodeName", s);
  241. }
  242. public void setBytecodeSignature(String s) {
  243. fixMap();
  244. // Different kinds of format here. The one worth compressing starts with a '(':
  245. // (La/b/c/D;Le/f/g/G;)Ljava/lang/String;
  246. // maybe want to avoid generics initially.
  247. // boolean worthCompressing = s.charAt(0) == '(' && s.indexOf('<') == -1 && s.indexOf('P') == -1; // starts parentheses and
  248. // no
  249. // // generics
  250. // if (worthCompressing) {
  251. // kvpairs.put("bytecodeSignatureCompressed", asm.compress(s));
  252. // } else {
  253. kvpairs.put("bytecodeSignature", s);
  254. // }
  255. }
  256. public String getBytecodeSignature() {
  257. String s = (String) kvpairs.get("bytecodeSignature");
  258. // if (s == null) {
  259. // List compressed = (List) kvpairs.get("bytecodeSignatureCompressed");
  260. // if (compressed != null) {
  261. // return asm.decompress(compressed, '/');
  262. // }
  263. // }
  264. // if (s==null) return UNDEFINED;
  265. return s;
  266. }
  267. public String getSourceSignature() {
  268. return (String) kvpairs.get("sourceSignature");
  269. }
  270. public void setSourceSignature(String string) {
  271. fixMap();
  272. // System.err.println(name+" SourceSig=>"+string);
  273. kvpairs.put("sourceSignature", string);
  274. // sourceSignature = string;
  275. }
  276. public void setKind(Kind kind) {
  277. this.kind = kind;
  278. }
  279. public void setCorrespondingType(String s) {
  280. fixMap();
  281. kvpairs.put("returnType", s);
  282. // this.returnType = s;
  283. }
  284. public void setParentTypes(List<String> ps) {
  285. fixMap();
  286. kvpairs.put("parentTypes", ps);
  287. }
  288. @SuppressWarnings("unchecked")
  289. public List<String> getParentTypes() {
  290. return (List<String>) (kvpairs == null ? null : kvpairs.get("parentTypes"));
  291. }
  292. /**
  293. * {@inheritDoc}
  294. */
  295. public void setAnnotationType(String fullyQualifiedAnnotationType) {
  296. fixMap();
  297. kvpairs.put("annotationType", fullyQualifiedAnnotationType);
  298. }
  299. public void setAnnotationRemover(boolean isRemover) {
  300. fixMap();
  301. kvpairs.put("annotationRemover", isRemover);
  302. }
  303. public String getAnnotationType() {
  304. if (isAnnotationRemover()) {
  305. return null;
  306. }
  307. return (String) (kvpairs == null ? null : kvpairs.get("annotationType"));
  308. }
  309. public boolean isAnnotationRemover() {
  310. if (kvpairs == null) {
  311. return false;
  312. }
  313. Boolean b = (Boolean) kvpairs.get("annotationRemover");
  314. if (b == null) {
  315. return false;
  316. }
  317. return b;
  318. }
  319. public String[] getRemovedAnnotationTypes() {
  320. if (!isAnnotationRemover()) {
  321. return null;
  322. }
  323. String annotype = (String) (kvpairs == null ? null : kvpairs.get("annotationType"));
  324. if (annotype == null) {
  325. return null;
  326. } else {
  327. return new String[] { annotype };
  328. }
  329. }
  330. public String getCorrespondingType() {
  331. return getCorrespondingType(false);
  332. }
  333. public String getCorrespondingTypeSignature() {
  334. String typename = (String) kvpairs.get("returnType");
  335. if (typename == null) {
  336. return null;
  337. }
  338. return nameToSignature(typename);
  339. }
  340. public static String nameToSignature(String name) {
  341. int len = name.length();
  342. if (len < 8) {
  343. if (name.equals("byte")) {
  344. return "B";
  345. }
  346. if (name.equals("char")) {
  347. return "C";
  348. }
  349. if (name.equals("double")) {
  350. return "D";
  351. }
  352. if (name.equals("float")) {
  353. return "F";
  354. }
  355. if (name.equals("int")) {
  356. return "I";
  357. }
  358. if (name.equals("long")) {
  359. return "J";
  360. }
  361. if (name.equals("short")) {
  362. return "S";
  363. }
  364. if (name.equals("boolean")) {
  365. return "Z";
  366. }
  367. if (name.equals("void")) {
  368. return "V";
  369. }
  370. if (name.equals("?")) {
  371. return name;
  372. }
  373. }
  374. if (name.endsWith("[]")) {
  375. return "[" + nameToSignature(name.substring(0, name.length() - 2));
  376. }
  377. if (len != 0) {
  378. // check if someone is calling us with something that is a signature already
  379. assert name.charAt(0) != '[';
  380. if (!name.contains("<")) {
  381. // not parameterized
  382. return new StringBuilder("L").append(name.replace('.', '/')).append(';').toString();
  383. } else {
  384. StringBuilder nameBuff = new StringBuilder();
  385. int nestLevel = 0;
  386. nameBuff.append("L");
  387. for (int i = 0; i < name.length(); i++) {
  388. char c = name.charAt(i);
  389. switch (c) {
  390. case '.':
  391. nameBuff.append('/');
  392. break;
  393. case '<':
  394. nameBuff.append("<");
  395. nestLevel++;
  396. StringBuilder innerBuff = new StringBuilder();
  397. while (nestLevel > 0) {
  398. c = name.charAt(++i);
  399. if (c == '<') {
  400. nestLevel++;
  401. }
  402. if (c == '>') {
  403. nestLevel--;
  404. }
  405. if (c == ',' && nestLevel == 1) {
  406. nameBuff.append(nameToSignature(innerBuff.toString()));
  407. innerBuff = new StringBuilder();
  408. } else {
  409. if (nestLevel > 0) {
  410. innerBuff.append(c);
  411. }
  412. }
  413. }
  414. nameBuff.append(nameToSignature(innerBuff.toString()));
  415. nameBuff.append('>');
  416. break;
  417. case '>':
  418. throw new IllegalStateException("Should by matched by <");
  419. case ',':
  420. throw new IllegalStateException("Should only happen inside <...>");
  421. default:
  422. nameBuff.append(c);
  423. }
  424. }
  425. nameBuff.append(";");
  426. return nameBuff.toString();
  427. }
  428. } else {
  429. throw new IllegalArgumentException("Bad type name: " + name);
  430. }
  431. }
  432. public String getCorrespondingType(boolean getFullyQualifiedType) {
  433. String returnType = (String) kvpairs.get("returnType");
  434. if (returnType == null) {
  435. returnType = "";
  436. }
  437. if (getFullyQualifiedType) {
  438. return returnType;
  439. }
  440. return trim(returnType);
  441. }
  442. /**
  443. * Trim down fully qualified types to their short form (e.g., a.b.c.D&lt;e.f.G&gt; becomes D&lt;G&gt;)
  444. */
  445. public static String trim(String fqname) {
  446. int i = fqname.indexOf("<");
  447. if (i == -1) {
  448. int lastdot = fqname.lastIndexOf('.');
  449. if (lastdot == -1) {
  450. return fqname;
  451. } else {
  452. return fqname.substring(lastdot + 1);
  453. }
  454. }
  455. char[] charArray = fqname.toCharArray();
  456. StringBuilder candidate = new StringBuilder(charArray.length);
  457. StringBuilder complete = new StringBuilder(charArray.length);
  458. for (char c : charArray) {
  459. switch (c) {
  460. case '.':
  461. candidate.setLength(0);
  462. break;
  463. case '<':
  464. case ',':
  465. case '>':
  466. complete.append(candidate).append(c);
  467. candidate.setLength(0);
  468. break;
  469. default:
  470. candidate.append(c);
  471. }
  472. }
  473. complete.append(candidate);
  474. return complete.toString();
  475. }
  476. public String getName() {
  477. return name;
  478. }
  479. public List<IProgramElement> getChildren() {
  480. return children;
  481. }
  482. public void setChildren(List<IProgramElement> children) {
  483. this.children = children;
  484. if (children == null) {
  485. return;
  486. }
  487. for (IProgramElement child : children) {
  488. child.setParent(this);
  489. }
  490. }
  491. public void addChild(IProgramElement child) {
  492. if (children == null || children == Collections.EMPTY_LIST) {
  493. children = new ArrayList<>();
  494. }
  495. children.add(child);
  496. child.setParent(this);
  497. }
  498. public void addChild(int position, IProgramElement child) {
  499. if (children == null || children == Collections.EMPTY_LIST) {
  500. children = new ArrayList<>();
  501. }
  502. children.add(position, child);
  503. child.setParent(this);
  504. }
  505. public boolean removeChild(IProgramElement child) {
  506. child.setParent(null);
  507. return children.remove(child);
  508. }
  509. public void setName(String string) {
  510. name = string;
  511. }
  512. public IProgramElement walk(HierarchyWalker walker) {
  513. if (children != null) {
  514. for (IProgramElement child : children) {
  515. walker.process(child);
  516. }
  517. }
  518. return this;
  519. }
  520. public String toLongString() {
  521. final StringBuffer buffer = new StringBuffer();
  522. HierarchyWalker walker = new HierarchyWalker() {
  523. private int depth = 0;
  524. public void preProcess(IProgramElement node) {
  525. for (int i = 0; i < depth; i++) {
  526. buffer.append(' ');
  527. }
  528. buffer.append(node.toString());
  529. buffer.append('\n');
  530. depth += 2;
  531. }
  532. public void postProcess(IProgramElement node) {
  533. depth -= 2;
  534. }
  535. };
  536. walker.process(this);
  537. return buffer.toString();
  538. }
  539. public void setModifiers(int i) {
  540. this.modifiers = i;
  541. }
  542. /**
  543. * Convenience mechanism for setting new modifiers which do not require knowledge of the private internal representation
  544. *
  545. * @param newModifier
  546. */
  547. public void addModifiers(IProgramElement.Modifiers newModifier) {
  548. modifiers |= newModifier.getBit();
  549. }
  550. public String toSignatureString() {
  551. return toSignatureString(true);
  552. }
  553. public String toSignatureString(boolean getFullyQualifiedArgTypes) {
  554. StringBuilder sb = new StringBuilder();
  555. sb.append(name);
  556. List<char[]> ptypes = getParameterTypes();
  557. if (ptypes != null && (!ptypes.isEmpty() || this.kind.equals(IProgramElement.Kind.METHOD))
  558. || this.kind.equals(IProgramElement.Kind.CONSTRUCTOR) || this.kind.equals(IProgramElement.Kind.ADVICE)
  559. || this.kind.equals(IProgramElement.Kind.POINTCUT) || this.kind.equals(IProgramElement.Kind.INTER_TYPE_METHOD)
  560. || this.kind.equals(IProgramElement.Kind.INTER_TYPE_CONSTRUCTOR)) {
  561. sb.append('(');
  562. for (Iterator<char[]> it = ptypes.iterator(); it.hasNext();) {
  563. char[] arg = it.next();
  564. if (getFullyQualifiedArgTypes) {
  565. sb.append(arg);
  566. } else {
  567. int index = CharOperation.lastIndexOf('.', arg);
  568. if (index != -1) {
  569. sb.append(CharOperation.subarray(arg, index + 1, arg.length));
  570. } else {
  571. sb.append(arg);
  572. }
  573. }
  574. if (it.hasNext()) {
  575. sb.append(",");
  576. }
  577. }
  578. sb.append(')');
  579. }
  580. return sb.toString();
  581. }
  582. /**
  583. * TODO: move the "parent != null"&rarr;injar heuristic to more explicit
  584. */
  585. public String toLinkLabelString() {
  586. return toLinkLabelString(true);
  587. }
  588. public String toLinkLabelString(boolean getFullyQualifiedArgTypes) {
  589. String label;
  590. if (kind == Kind.CODE || kind == Kind.INITIALIZER) {
  591. label = parent.getParent().getName() + ": ";
  592. } else if (kind.isInterTypeMember()) {
  593. if (shortITDNames) {
  594. // if (name.indexOf('.')!=-1) return toLabelString().substring(name.indexOf('.')+1);
  595. label = "";
  596. } else {
  597. int dotIndex = name.indexOf('.');
  598. if (dotIndex != -1) {
  599. return parent.getName() + ": " + toLabelString().substring(dotIndex + 1);
  600. } else {
  601. label = parent.getName() + '.';
  602. }
  603. }
  604. } else if (kind == Kind.CLASS || kind == Kind.ASPECT || kind == Kind.INTERFACE) {
  605. label = "";
  606. } else if (kind.equals(Kind.DECLARE_PARENTS)) {
  607. label = "";
  608. } else {
  609. if (parent != null) {
  610. label = parent.getName() + '.';
  611. } else {
  612. label = "injar aspect: ";
  613. }
  614. }
  615. label += toLabelString(getFullyQualifiedArgTypes);
  616. return label;
  617. }
  618. public String toLabelString() {
  619. return toLabelString(true);
  620. }
  621. public String toLabelString(boolean getFullyQualifiedArgTypes) {
  622. String label = toSignatureString(getFullyQualifiedArgTypes);
  623. String details = getDetails();
  624. if (details != null) {
  625. label += ": " + details;
  626. }
  627. return label;
  628. }
  629. public String getHandleIdentifier() {
  630. return getHandleIdentifier(true);
  631. }
  632. public String getHandleIdentifier(boolean create) {
  633. String h = handle;
  634. if (null == handle && create) {
  635. if (asm == null && name.equals("<build to view structure>")) {
  636. h = "<build to view structure>";
  637. } else {
  638. try {
  639. h = asm.getHandleProvider().createHandleIdentifier(this);
  640. } catch (ArrayIndexOutOfBoundsException aioobe) {
  641. throw new RuntimeException("AIOOBE whilst building handle for " + this, aioobe);
  642. }
  643. }
  644. }
  645. setHandleIdentifier(h);
  646. return h;
  647. }
  648. public void setHandleIdentifier(String handle) {
  649. this.handle = handle;
  650. }
  651. @SuppressWarnings("unchecked")
  652. public List<String> getParameterNames() {
  653. List<String> parameterNames = (List<String>) kvpairs.get("parameterNames");
  654. return parameterNames;
  655. }
  656. public void setParameterNames(List<String> list) {
  657. if (list == null || list.size() == 0) {
  658. return;
  659. }
  660. fixMap();
  661. kvpairs.put("parameterNames", list);
  662. // parameterNames = list;
  663. }
  664. public List<char[]> getParameterTypes() {
  665. List<char[]> l = getParameterSignatures();
  666. if (l == null || l.isEmpty()) {
  667. return Collections.emptyList();
  668. }
  669. List<char[]> params = new ArrayList<>();
  670. for (char[] param : l) {
  671. params.add(NameConvertor.convertFromSignature(param));
  672. }
  673. return params;
  674. }
  675. @SuppressWarnings("unchecked")
  676. public List<char[]> getParameterSignatures() {
  677. List<char[]> parameters = (List<char[]>) kvpairs.get("parameterSigs");
  678. return parameters;
  679. }
  680. @SuppressWarnings("unchecked")
  681. public List<String> getParameterSignaturesSourceRefs() {
  682. List<String> parameters = (List<String>) kvpairs.get("parameterSigsSourceRefs");
  683. return parameters;
  684. }
  685. /**
  686. * Set the parameter signatures for this method/constructor. The bit flags tell us if any were not singletypereferences in the
  687. * the source. A singletypereference would be 'String' - whilst a qualifiedtypereference would be 'java.lang.String' - this has
  688. * an effect on the handles.
  689. */
  690. public void setParameterSignatures(List<char[]> list, List<String> sourceRefs) {
  691. fixMap();
  692. if (list == null || list.size() == 0) {
  693. kvpairs.put("parameterSigs", Collections.EMPTY_LIST);
  694. } else {
  695. kvpairs.put("parameterSigs", list);
  696. }
  697. if (sourceRefs != null && sourceRefs.size() != 0) {
  698. kvpairs.put("parameterSigsSourceRefs", sourceRefs);
  699. }
  700. }
  701. public String getDetails() {
  702. String details = (String) kvpairs.get("details");
  703. return details;
  704. }
  705. public void setDetails(String string) {
  706. fixMap();
  707. kvpairs.put("details", string);
  708. }
  709. public void setFormalComment(String txt) {
  710. if (txt != null && txt.length() > 0) {
  711. fixMap();
  712. kvpairs.put("formalComment", txt);
  713. }
  714. }
  715. private void fixMap() {
  716. if (kvpairs == Collections.EMPTY_MAP) {
  717. kvpairs = new HashMap<>();
  718. }
  719. }
  720. public void setExtraInfo(ExtraInformation info) {
  721. fixMap();
  722. kvpairs.put("ExtraInformation", info);
  723. }
  724. public ExtraInformation getExtraInfo() {
  725. return (ExtraInformation) kvpairs.get("ExtraInformation");
  726. }
  727. public boolean isAnnotationStyleDeclaration() {
  728. return kvpairs.get("annotationStyleDeclaration") != null;
  729. }
  730. public void setAnnotationStyleDeclaration(boolean b) {
  731. if (b) {
  732. fixMap();
  733. kvpairs.put("annotationStyleDeclaration", "true");
  734. }
  735. }
  736. @SuppressWarnings("unchecked")
  737. public Map<String, List<String>> getDeclareParentsMap() {
  738. Map<String, List<String>> s = (Map<String, List<String>>) kvpairs.get("declareparentsmap");
  739. return s;
  740. }
  741. public void setDeclareParentsMap(Map<String, List<String>> newmap) {
  742. fixMap();
  743. kvpairs.put("declareparentsmap", newmap);
  744. }
  745. public void addFullyQualifiedName(String fqname) {
  746. fixMap();
  747. kvpairs.put("itdfqname", fqname);
  748. }
  749. public String getFullyQualifiedName() {
  750. return (String) kvpairs.get("itdfqname");
  751. }
  752. }