001 /* Copyright 2000, 2001, Compaq Computer Corporation */
002
003 package javafe;
004
005 import javafe.ast.*;
006 import javafe.tc.*;
007 import javafe.util.*;
008
009 import java.io.*;
010
011 import java.util.StringTokenizer;
012 import java.util.ArrayList;
013
014 /**
015 * <code>PrintSpec</code> print specs for class files.
016 */
017 public class PrintSpec extends SrcTool
018 {
019 /*@ also public normal_behavior
020 @ ensures \result.equals("PrintSpec");
021 @*/
022 public /*@ pure non_null @*/ String name() { return "PrintSpec"; }
023
024 /***************************************************
025 * *
026 * Keeping track of loaded CompilationUnits: *
027 * *
028 **************************************************/
029
030 class PrintSpecPrettyPrint extends StandardPrettyPrint {
031
032 public void printnoln(/*@non_null*/OutputStream o, int ind, TypeDecl d) {
033 if (d != null && d.getTag() == javafe.ast.TagConstants.CLASSDECL) {
034 ClassDecl cd = (ClassDecl)d;
035 if (Character.isDigit((cd.id.toString().charAt(0)))) {
036 System.out.println("---> skipping anonymous inner class");
037 return;
038 }
039 }
040 super.printnoln(o, ind, d);
041 }
042 }
043
044 /*@ also public normal_behavior
045 @ modifies \everything;
046 @ ensures \fresh(PrettyPrint.inst);
047 @*/
048 public void setup() {
049 super.setup();
050 PrettyPrint.inst = new PrintSpecPrettyPrint();
051 }
052
053 /***************************************************
054 * *
055 * Main processing code: *
056 * *
057 **************************************************/
058
059 //@ requires \nonnullelements(args);
060 public static void main(String[] args) {
061 Tool t = new PrintSpec();
062 int result = t.run(args);
063 if (result != 0) System.exit(result);
064 }
065
066 //@ ensures \nonnullelements(\result);
067 //@ ensures \result != null;
068 public String[] FQNpackage(/*@ non_null */ String s) {
069 StringTokenizer st = new StringTokenizer(s, ".", false);
070 int len = st.countTokens();
071 if (len < 1) {
072 return new String[0];
073 }
074 String array[] = new String[len-1];
075 for (int i = 0; i < len-1; i++) {
076 array[i] = st.nextToken();
077 }
078 return array;
079 }
080
081 //@ ensures \result != null;
082 public String FQNname(/*@ non_null */ String s) {
083 return s.substring(s.lastIndexOf(".") + 1);
084 }
085
086 /*@ private normal_behavior
087 @ requires \nonnullelements(P);
088 @ ensures (* for each element of P, a directory exists of that name *);
089 @ ensures \result.length() == 1 + P.length + (\sum int i; 0 < i && i < P.length; P[i].length());
090 @*/
091 private /*@ pure non_null @*/ String makeDirTree(/*@ non_null */ String P[]) {
092 String s = ".";
093 for (int i = 0; i < P.length; i++) {
094 s = s + "/" + P[i];
095 File f = new File(s);
096 if (!f.exists()) f.mkdir();
097 }
098 return s;
099 }
100
101 public void loadAndPrintSpec(/*@ non_null */ String s) {
102 String P[] = FQNpackage(s);
103 String T = FQNname(s);
104 TypeSig sig = OutsideEnv.lookup(P, T);
105 if (sig == null) {
106 System.out.println("Can't find " + s);
107 return;
108 }
109 String path = makeDirTree(P);
110 String outFile = T + ".spec";
111 String filename = path + "/" + outFile;
112 System.out.println("generating " + filename + "...");
113 FileOutputStream fos = null;
114 try {
115 fos = new FileOutputStream(filename);
116 } catch (Exception e) {
117 ErrorSet.fatal(e.getMessage());
118 }
119 PrettyPrint.inst.print(fos, sig.getCompilationUnit());
120 }
121
122 public final void frontEndToolProcessing(ArrayList args) {
123 /*
124 * At this point, all options have already been processed and
125 * the front end has been initialized.
126 */
127
128 // Set up to receive CompilationUnit-loading notification events:
129 OutsideEnv.setListener(this);
130
131 /*
132 * Load in each source file:
133 */
134 /* FIXME
135 for (; offset<args.length; offset++) {
136 this.loadAndPrintSpec(args[offset]);
137 }
138 */
139
140 /* load in source files from supplied file name */
141 /* FIXME
142 for (int i = 0; i < argumentFileNames.size(); i++) {
143 String argumentClassName = (String)argumentFileNames.get(i);
144 try {
145 BufferedReader in = new BufferedReader(
146 new FileReader(argumentClassName));
147 String s;
148 while ((s = in.readLine()) != null) {
149 // allow blank lines in files list
150 if (!s.equals("")) {
151 this.loadAndPrintSpec(s);
152 }
153 }
154 } catch (IOException e) {
155 ErrorSet.fatal(e.getMessage());
156 }
157 }
158 */
159 }
160 }