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 }