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