    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    }