    001    /* Copyright 2000, 2001, Compaq Computer Corporation */
    002
    003    package javafe.reader;
    004
    005    import java.io.*;
    006
    007    import javafe.ast.CompilationUnit;
    008    import javafe.ast.TypeDecl;
    009    import javafe.ast.TypeDeclVec;
    010    import javafe.ast.ImportDeclVec;
    011    import javafe.ast.PrettyPrint;                  // Debugging methods only
    012
    013    import javafe.genericfile.*;
    014
    015    /**
    016     * A BinReader is a Reader that reads in CompilationUnits from binary
    017     * files (.class files).
    018     *
    019     * <p> BinReaders do not cache the results of their reading and always
    020     * return spec files.
    021     *
    022     * <p> TypeDecls produced by BinReaders always have specOnly set.
    023     *
    024     * <p> This version is not known to work on Java 1.1 class files.
    025     * Later versions are planned to return CompilationUnits with stubs
    026     * where inner classes should be.  It is then the caller's
    027     * responsibility to call this class repeatedly to obtain all the
    028     * inner classes then stitch them together in a single seamless
    029     * CompilationUnit.  (Most likely, a new class will be introduced to
    030     * perform this function, mapping P.N's to Compilation Units.
    031     */
    032
    033    public class BinReader extends Reader
    034    {
    035        /***************************************************
    036         *                                                 *
    037         * Reading:                                        *
    038         *                                                 *
    039         **************************************************/
    040
    041        /**
    042         * Attempt to read and parse a CompilationUnit from *binary*
    043         * target.   Any errors encountered are reported via
    044         * javafe.util.ErrorSet.  Null is returned iff an error was
    045         * encountered.<p>
    046         *
    047         *
    048         * We always return a spec file.  (avoidSpec is ignored)<p>
    049         *
    050         *
    051         * This function is not cached.<p>
    052         *
    053         * Target must be non-null.<p>
    054         */
    055        public CompilationUnit read(GenericFile target, boolean avoidSpec) {
    056            javafe.util.Info.out("[loading " + target.getHumanName() + "]");
    057            try {
    058                ASTClassFileParser parser = new ASTClassFileParser(target,false);
    059                    // if the 2nd argument above is false, omit all bodies.
    060                    // For some reason, despite the comment above, bodies are
    061                    // sometimes included.
    062                TypeDeclVec types =
    063                    TypeDeclVec.make(new TypeDecl[] { parser.typeDecl });
    064                ImportDeclVec emptyImportDeclVec = ImportDeclVec.make();
    065                CompilationUnit result =
    066                    CompilationUnit.make(parser.classPackage,
    067                                         null,
    068                                         emptyImportDeclVec,
    069                                         types,
    070                                         parser.classLocation,null);
    071                return result;
    072            }
    073            catch (IOException e)
    074            {
    075              javafe.util.ErrorSet.error("I/O error: " + e.getMessage());
    076            }
    077            catch (ClassFormatError e)
    078            {
    079              javafe.util.ErrorSet.error("Class format error: " + e.getMessage());
    080            }
    081
    082            return null;
    083        }
    084
    085        /***************************************************
    086         *                                                 *
    087         * Test methods:                                   *
    088         *                                                 *
    089         **************************************************/
    090
    091        //@ requires \nonnullelements(args);
    092        public static void main(String[] args) {
    093            if (args.length != 1) {
    094                System.err.println("BinReader: <source filename>");
    095                System.exit(1);
    096            }
    097
    098            GenericFile target = new NormalGenericFile(args[0]);
    099            BinReader reader = new BinReader();
    100
    101            CompilationUnit cu = reader.read(target, false);
    102            if (cu != null)
    103                PrettyPrint.inst.print( System.out, cu );
    104        }
    105    }