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.

StubFileGenerator.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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.io.*;
  16. import java.util.Hashtable;
  17. import java.util.Iterator;
  18. import java.util.List;
  19. import org.aspectj.asm.AsmManager;
  20. import org.aspectj.asm.IProgramElement;
  21. /**
  22. * @author Mik Kersten
  23. */
  24. class StubFileGenerator{
  25. static Hashtable declIDTable = null;
  26. static void doFiles (Hashtable table,
  27. SymbolManager symbolManager,
  28. File[] inputFiles,
  29. File[] signatureFiles) throws DocException {
  30. declIDTable = table;
  31. for (int i = 0; i < inputFiles.length; i++) {
  32. processFile(symbolManager, inputFiles[i], signatureFiles[i]);
  33. }
  34. }
  35. static void processFile(SymbolManager symbolManager, File inputFile, File signatureFile) throws DocException {
  36. try {
  37. String path = StructureUtil.translateAjPathName(signatureFile.getCanonicalPath());
  38. PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(path)));
  39. String packageName = StructureUtil.getPackageDeclarationFromFile(inputFile);
  40. if (packageName != null && packageName != "") {
  41. writer.println( "package " + packageName + ";" );
  42. }
  43. IProgramElement fileNode = (IProgramElement)AsmManager.getDefault().getHierarchy().findElementForSourceFile(inputFile.getAbsolutePath());
  44. for (Iterator it = fileNode.getChildren().iterator(); it.hasNext(); ) {
  45. IProgramElement node = (IProgramElement)it.next();
  46. if (node.getKind().equals(IProgramElement.Kind.IMPORT_REFERENCE)) {
  47. processImportDeclaration(node, writer);
  48. } else {
  49. try {
  50. processTypeDeclaration(node, writer);
  51. } catch (DocException d){
  52. throw new DocException("File name invalid: " + inputFile.toString());
  53. }
  54. }
  55. }
  56. // if we got an error we don't want the contents of the file
  57. writer.close();
  58. } catch (IOException e) {
  59. System.err.println(e.getMessage());
  60. e.printStackTrace();
  61. }
  62. }
  63. private static void processImportDeclaration(IProgramElement node, PrintWriter writer) throws IOException {
  64. List imports = node.getChildren();
  65. for (Iterator i = imports.iterator(); i.hasNext();) {
  66. IProgramElement importNode = (IProgramElement) i.next();
  67. writer.print("import ");
  68. writer.print(importNode.getName());
  69. writer.println(';');
  70. }
  71. }
  72. private static void processTypeDeclaration(IProgramElement classNode, PrintWriter writer) throws DocException {
  73. String formalComment = addDeclID(classNode, classNode.getFormalComment());
  74. writer.println(formalComment);
  75. String signature = genSourceSignature(classNode);// StructureUtil.genSignature(classNode);
  76. if (signature == null){
  77. throw new DocException("The java file is invalid");
  78. }
  79. // System.err.println("######" + signature + ", " + classNode.getName());
  80. if (!StructureUtil.isAnonymous(classNode) && !classNode.getName().equals("<undefined>")) {
  81. writer.println(signature + " {" );
  82. processMembers(classNode.getChildren(), writer, classNode.getKind().equals(IProgramElement.Kind.INTERFACE));
  83. writer.println();
  84. writer.println("}");
  85. }
  86. }
  87. private static void processMembers(List/*IProgramElement*/ members, PrintWriter writer, boolean declaringTypeIsInterface) throws DocException {
  88. for (Iterator it = members.iterator(); it.hasNext();) {
  89. IProgramElement member = (IProgramElement) it.next();
  90. if (member.getKind().isType()) {
  91. if (!member.getParent().getKind().equals(IProgramElement.Kind.METHOD)
  92. && !StructureUtil.isAnonymous(member)) {// don't print anonymous types
  93. // System.err.println(">>>>>>>>>>>>>" + member.getName() + "<<<<" + member.getParent());
  94. processTypeDeclaration(member, writer);
  95. }
  96. } else {
  97. String formalComment = addDeclID(member, member.getFormalComment());;
  98. writer.println(formalComment);
  99. String signature = "";
  100. if (!member.getKind().equals(IProgramElement.Kind.POINTCUT)
  101. && !member.getKind().equals(IProgramElement.Kind.ADVICE)) {
  102. signature = member.getSourceSignature();//StructureUtil.genSignature(member);
  103. if (member.getKind().equals(IProgramElement.Kind.ENUM_VALUE)){
  104. int index = members.indexOf(member);
  105. if ((index + 1 < members.size()) &&
  106. ((IProgramElement)members.get(index+1)).getKind().equals(IProgramElement.Kind.ENUM_VALUE)){
  107. // if the next member is also an ENUM_VALUE:
  108. signature = signature + ",";
  109. } else {
  110. signature = signature + ";";
  111. }
  112. }
  113. }
  114. if (member.getKind().isDeclare()) {
  115. // System.err.println("> Skipping declare (ajdoc limitation): " + member.toLabelString());
  116. } else if (signature != null &&
  117. signature != "" &&
  118. !member.getKind().isInterTypeMember() &&
  119. !member.getKind().equals(IProgramElement.Kind.INITIALIZER) &&
  120. !StructureUtil.isAnonymous(member)) {
  121. writer.print(signature);
  122. } else {
  123. // System.err.println(">> skipping: " + member.getKind());
  124. }
  125. if (member.getKind().equals(IProgramElement.Kind.METHOD) ||
  126. member.getKind().equals(IProgramElement.Kind.CONSTRUCTOR)) {
  127. if (member.getParent().getKind().equals(IProgramElement.Kind.INTERFACE) ||
  128. signature.indexOf("abstract ") != -1) {
  129. writer.println(";");
  130. } else {
  131. writer.println(" { }");
  132. }
  133. } else if (member.getKind().equals(IProgramElement.Kind.FIELD)) {
  134. // writer.println(";");
  135. }
  136. }
  137. }
  138. }
  139. /**
  140. * Translates "aspect" to "class", as long as its not ".aspect"
  141. */
  142. private static String genSourceSignature(IProgramElement classNode) {
  143. String signature = classNode.getSourceSignature();
  144. if (signature != null){
  145. int index = signature.indexOf("aspect");
  146. if (index == 0 || (index != -1 && signature.charAt(index-1) != '.') ) {
  147. signature = signature.substring(0, index) +
  148. "class " +
  149. signature.substring(index + 6, signature.length());
  150. }
  151. }
  152. return signature;
  153. }
  154. static int nextDeclID = 0;
  155. static String addDeclID(IProgramElement decl, String formalComment) {
  156. String declID = "" + ++nextDeclID;
  157. declIDTable.put(declID, decl);
  158. return addToFormal(formalComment, Config.DECL_ID_STRING + declID + Config.DECL_ID_TERMINATOR);
  159. }
  160. /**
  161. * We want to go:
  162. * just before the first period
  163. * just before the first @
  164. * just before the end of the comment
  165. *
  166. * Adds a place holder for the period ('#') if one will need to be
  167. * replaced.
  168. */
  169. static String addToFormal(String formalComment, String string) {
  170. boolean appendPeriod = true;
  171. if ( (formalComment == null) || formalComment.equals("")) {
  172. //formalComment = "/**\n * . \n */\n";
  173. formalComment = "/**\n * \n */\n";
  174. appendPeriod = false;
  175. }
  176. formalComment = formalComment.trim();
  177. int atsignPos = formalComment.indexOf('@');
  178. int endPos = formalComment.indexOf("*/");
  179. int periodPos = formalComment.indexOf("/**")+2;
  180. int position = 0;
  181. String periodPlaceHolder = "";
  182. if ( periodPos != -1 ) {
  183. position = periodPos+1;
  184. }
  185. else if ( atsignPos != -1 ) {
  186. string = string + "\n * ";
  187. position = atsignPos;
  188. }
  189. else if ( endPos != -1 ) {
  190. string = "* " + string + "\n";
  191. position = endPos;
  192. }
  193. else {
  194. // !!! perhaps this error should not be silent
  195. throw new Error("Failed to append to formal comment for comment: " +
  196. formalComment );
  197. }
  198. return
  199. formalComment.substring(0, position) + periodPlaceHolder +
  200. string +
  201. formalComment.substring(position);
  202. }
  203. }