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.

ClassUseMapper.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. *
  3. * This file is part of the debugger and core tools for the AspectJ(tm)
  4. * programming language; see http://aspectj.org
  5. *
  6. * The contents of this file are subject to the Mozilla Public License
  7. * Version 1.1 (the "License"); you may not use this file except in
  8. * compliance with the License. You may obtain a copy of the License at
  9. * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. *
  16. * The Original Code is AspectJ.
  17. *
  18. * The Initial Developer of the Original Code is Xerox Corporation. Portions
  19. * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
  20. * All Rights Reserved.
  21. */
  22. package org.aspectj.tools.doclets.standard;
  23. import org.aspectj.ajdoc.AdviceDoc;
  24. import org.aspectj.ajdoc.AspectDoc;
  25. import org.aspectj.ajdoc.IntroducedDoc;
  26. import org.aspectj.ajdoc.IntroducedSuperDoc;
  27. import org.aspectj.ajdoc.IntroductionDoc;
  28. import org.aspectj.ajdoc.PointcutDoc;
  29. import org.aspectj.tools.ajdoc.Util;
  30. import com.sun.javadoc.ClassDoc;
  31. import com.sun.javadoc.ExecutableMemberDoc;
  32. import com.sun.javadoc.FieldDoc;
  33. import com.sun.javadoc.MemberDoc;
  34. import com.sun.javadoc.PackageDoc;
  35. import com.sun.javadoc.Parameter;
  36. import com.sun.javadoc.ProgramElementDoc;
  37. import com.sun.javadoc.RootDoc;
  38. import com.sun.javadoc.Type;
  39. import com.sun.tools.doclets.ClassTree;
  40. import com.sun.tools.doclets.DocletAbortException;
  41. import java.lang.reflect.Constructor;
  42. import java.util.ArrayList;
  43. import java.util.Collection;
  44. import java.util.HashMap;
  45. import java.util.HashSet;
  46. import java.util.Iterator;
  47. import java.util.List;
  48. import java.util.Map;
  49. /**
  50. * Provides support for aspects.
  51. *
  52. * @author Jeff Palm
  53. */
  54. public class ClassUseMapper {
  55. /**
  56. * Maps a ClassDoc to advice that return its type.
  57. */
  58. public final Map classToAdviceReturn = new HashMap();
  59. /**
  60. * Maps a ClassDoc to advice that have its type
  61. * are arguments.
  62. */
  63. public final Map classToAdviceArgs = new HashMap();
  64. /**
  65. * Maps a ClassDoc to pointcuts that return its type.
  66. */
  67. public final Map classToPointcutReturn = new HashMap();
  68. /**
  69. * Maps a ClassDoc to pointcuts that have its type
  70. * as arguments.
  71. */
  72. public final Map classToPointcutArgs = new HashMap();
  73. /**
  74. * Maps a ClassDoc to field introductions that
  75. * are its type.
  76. */
  77. public final Map classToFieldIntroductions = new HashMap();
  78. /**
  79. * Maps a ClassDoc to class introductions that
  80. * are its type.
  81. */
  82. public final Map classToClassIntroductions = new HashMap();
  83. /**
  84. * Maps a ClassDoc to interface introductions that
  85. * are its type.
  86. */
  87. public final Map classToInterfaceIntroductions = new HashMap();
  88. /**
  89. * Maps a ClassDoc to aspects that advise it.
  90. */
  91. public final Map classToAdvisors = new HashMap();
  92. /**
  93. * Maps a ClassDoc to aspects that it dominates.
  94. */
  95. public final Map classToDominatees = new HashMap();
  96. /**
  97. * Maps a ClassDoc to aspects that dominate it..
  98. */
  99. public final Map classToDominators = new HashMap();
  100. public static void generate(RootDoc root, ClassTree classtree)
  101. throws DocletAbortException {
  102. try {
  103. ClassUseMapper mapper = new ClassUseMapper(root, classtree);
  104. ClassDoc[] classes = root.classes();
  105. for (int i = 0; i < classes.length; i++) {
  106. ClassUseWriter.generate(mapper, classes[i]);
  107. }
  108. PackageDoc[] pkgs = Standard.configuration().packages;
  109. for (int i = 0; i < pkgs.length; i++) {
  110. com.sun.tools.doclets.standard.PackageUseWriter.
  111. generate(mapper.mapper, pkgs[i]);
  112. }
  113. } catch (Exception e) {
  114. e.printStackTrace();
  115. Standard.configuration().standardmessage.
  116. error("doclet.exception", e+"",
  117. "creating class use tree");
  118. throw new DocletAbortException();
  119. }
  120. }
  121. protected final com.sun.tools.doclets.standard.ClassUseMapper mapper;
  122. public ClassUseMapper(RootDoc root, ClassTree classtree)
  123. throws Exception {
  124. Constructor constr =
  125. com.sun.tools.doclets.standard.ClassUseMapper.class.
  126. getDeclaredConstructor(new Class[] {
  127. com.sun.javadoc.RootDoc.class,
  128. com.sun.tools.doclets.ClassTree.class,
  129. });
  130. constr.setAccessible(true);
  131. mapper = (com.sun.tools.doclets.standard.ClassUseMapper)constr.
  132. newInstance(new Object[]{root, classtree});
  133. classToPackageSave = new HashMap();
  134. for (Iterator i = mapper.classToPackage.keySet().iterator(); i.hasNext();) {
  135. Object key = i.next();
  136. classToPackageSave.put(key, new HashSet((Collection)
  137. mapper.classToPackage.
  138. get(key)));
  139. }
  140. finish(root, classtree);
  141. }
  142. protected Object saved;
  143. protected final Map classToPackageSave;
  144. protected final com.sun.tools.doclets.standard.ClassUseMapper mapper
  145. (ClassDoc classdoc)
  146. {
  147. Object noaspects = classToPackageSave.get(classdoc);
  148. saved = mapper.classToPackage.get(classdoc);
  149. mapper.classToPackage.put(classdoc, noaspects);
  150. return mapper;
  151. }
  152. protected void restore(ClassDoc classdoc) {
  153. mapper.classToPackage.put(classdoc, saved);
  154. }
  155. protected void finish(RootDoc root, ClassTree classtree) {
  156. ClassDoc[] classes = root.classes();
  157. for (int i = 0; i < classes.length; i++) {
  158. ClassDoc cd = classes[i];
  159. if (cd instanceof org.aspectj.ajdoc.ClassDoc) {
  160. org.aspectj.ajdoc.ClassDoc acd = (org.aspectj.ajdoc.ClassDoc)cd;
  161. PointcutDoc[] pcs = acd.pointcuts();
  162. for (int j = 0; j < pcs.length; j++) {
  163. PointcutDoc pd = pcs[j];
  164. mapExecutable(pd);
  165. Type result = pd.resultType();
  166. if (result != null) {
  167. ClassDoc tcd = result.asClassDoc();
  168. if (tcd != null) {
  169. add(classToPointcutReturn, tcd, pd);
  170. }
  171. }
  172. }
  173. }
  174. if (cd instanceof AspectDoc) {
  175. AspectDoc ad = (AspectDoc)cd;
  176. AdviceDoc[] adocs = ad.advice();
  177. for (int j = 0; j < adocs.length; j++) {
  178. AdviceDoc adoc = adocs[j];
  179. mapExecutable(adoc);
  180. Type result = adoc.returnType();
  181. if (result != null) {
  182. ClassDoc tcd = result.asClassDoc();
  183. if (tcd != null) {
  184. add(classToAdviceReturn, tcd, adoc);
  185. }
  186. }
  187. ExecutableMemberDoc[] emds = adoc.crosscuts();
  188. if (null != emds) {
  189. for (int k = 0; k < emds.length; k++) {
  190. ExecutableMemberDoc emd = emds[k];
  191. if (null != emd) {
  192. ClassDoc tcd = emd.containingClass();
  193. ClassDoc fcd = adoc.containingClass();
  194. //TODO: This probably sucks!!!
  195. if (!refList(classToAdvisors, tcd).contains(fcd)) {
  196. add(classToAdvisors, tcd, fcd);
  197. }
  198. }
  199. }
  200. }
  201. }
  202. IntroductionDoc[] ids = ad.introductions();
  203. for (int j = 0; j < ids.length; j++) {
  204. IntroductionDoc id = ids[j];
  205. if (id instanceof IntroducedDoc) {
  206. IntroducedDoc idd = (IntroducedDoc)id;
  207. MemberDoc mem = idd.member();
  208. if (mem.isField()) {
  209. FieldDoc fd = (FieldDoc)mem;
  210. ClassDoc tcd = fd.type().asClassDoc();
  211. add(classToFieldIntroductions, tcd, fd);
  212. }
  213. } else if (id instanceof IntroducedSuperDoc) {
  214. IntroducedSuperDoc idd = (IntroducedSuperDoc)id;
  215. boolean isImplements = idd.isImplements();
  216. Type[] types = idd.types();
  217. for (int k = 0; k < types.length; k++) {
  218. ClassDoc tcd = types[k].asClassDoc();
  219. add(isImplements ?
  220. classToInterfaceIntroductions :
  221. classToClassIntroductions, tcd, idd);
  222. }
  223. }
  224. }
  225. AspectDoc[] dominatees = ad.dominatees();
  226. for (int j = 0; j < dominatees.length; j++) {
  227. add(classToDominatees, ad, dominatees[j]);
  228. }
  229. AspectDoc[] dominators = ad.dominators();
  230. for (int j = 0; j < dominators.length; j++) {
  231. add(classToDominators, ad, dominators[j]);
  232. }
  233. }
  234. }
  235. }
  236. protected void mapExecutable(ExecutableMemberDoc em) {
  237. Parameter[] params = em.parameters();
  238. List classargs = new ArrayList();
  239. Map argsmap = ((org.aspectj.ajdoc.MemberDoc)em).isAdvice() ?
  240. classToAdviceArgs : classToPointcutArgs ;
  241. for (int i = 0; i < params.length; i++) {
  242. ClassDoc pcd = params[i].type().asClassDoc();
  243. if (pcd != null && !classargs.contains(pcd)) {
  244. add(argsmap, pcd, em);
  245. classargs.add(pcd);
  246. }
  247. }
  248. }
  249. protected List refList(Map map, ClassDoc cd) {
  250. return (List)Util.invoke(mapper, "refList",
  251. new Class[]{java.util.Map.class,
  252. com.sun.javadoc.ClassDoc.class},
  253. new Object[]{map, cd});
  254. }
  255. protected void add(Map map, ClassDoc cd, ProgramElementDoc ref) {
  256. Util.invoke(mapper, "add",
  257. new Class[]{java.util.Map.class,
  258. com.sun.javadoc.ClassDoc.class,
  259. com.sun.javadoc.ProgramElementDoc.class},
  260. new Object[]{map, cd, ref});
  261. }
  262. }