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(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    }