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.1KB

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