|
Javac |
|
1 /* 2 * 3 * Copyright (c) 1998-2001, The University of Sheffield. 4 * 5 * This file is part of GATE (see http://gate.ac.uk/), and is free 6 * software, licenced under the GNU Library General Public License, 7 * Version 2, June 1991 (in the distribution as file licence.html, 8 * and also available at http://gate.ac.uk/gate/licence.html). 9 * 10 * Valentin Tablan, 18/Feb/2002 11 * 12 * $Id: Javac.java,v 1.8 2002/10/21 16:21:17 valyt Exp $ 13 */ 14 package gate.util; 15 16 17 import com.sun.tools.javac.v8.util.*; 18 import com.sun.tools.javac.v8.comp.*; 19 import com.sun.tools.javac.v8.code.*; 20 import com.sun.tools.javac.v8.*; 21 22 import java.io.*; 23 import java.util.Map; 24 import java.util.ArrayList; 25 26 import gate.util.*; 27 import gate.*; 28 29 /** 30 * This class copiles a set of java sources by accessing the java compiler 31 * from tools.jar file in the jdk. 32 * All processing is done without touching the disk. 33 */ 34 public class Javac{ 35 36 protected static class MemoryLog extends Log{ 37 MemoryLog(Map sources){ 38 super(); 39 this.sources = sources; 40 errorsString = new StringBuffer(); 41 } 42 43 public void error(int pos, String key, String arg0, String arg1, 44 String arg2, String arg3, String arg4, String arg5, 45 String arg6) { 46 if(nerrors < MaxErrors){ 47 String msg = getText("compiler.err." + key, arg0, arg1, arg2, arg3, 48 arg4, arg5, arg6); 49 50 if (pos == Position.NOPOS) { 51 errorsString.append(getText("compiler.err.error", null, null, null, 52 null, null, null, null)); 53 errorsString.append(msg + Strings.getNl()); 54 }else{ 55 int line = Position.line(pos); 56 int col = Position.column(pos); 57 errorsString.append("Compilation error in " + 58 className + ":" + line + ": " + msg + 59 Strings.getNl() + Strings.getNl()); 60 61 String sourceCode = (String)sources.get(className); 62 errorsString.append("The offending input was :" + Strings.getNl() + 63 (sourceCode == null || sourceCode.equals("") ? 64 "<not available>" : 65 Strings.addLineNumbers(sourceCode)) + 66 Strings.getNl()); 67 } 68 prompt(); 69 nerrors++; 70 } 71 } 72 73 //redirect automatic error reporting from System.err to memory 74 public void print(String s) { 75 errorsString.append(s); 76 }//print 77 Map sources; 78 StringBuffer errorsString; 79 String className; 80 } 81 82 protected static class GJC extends JavaCompiler{ 83 GJC(MemoryLog log, Symtab syms, Hashtable options, Map sources){ 84 super(log, syms, options); 85 this.sources = sources; 86 this.memLog = log; 87 } 88 89 /** 90 * Overidden so that it reads the sources from the provided Map rather than 91 * from the disk. 92 * @param fileName the name of the file that should contain the source. 93 * @return an input stream for the java source. 94 */ 95 public InputStream openSource(String fileName) { 96 //Out.prln("Read request for: " + fileName); 97 String className = fileName.substring(0, fileName.lastIndexOf(".java")); 98 className = className.replace('/', '.'); 99 className = className.replace('\\', '.'); 100 String classSource = (String)sources.get(className); 101 memLog.className = className; 102 //Out.prln("Source for: " + className + "\n" + classSource); 103 return new ByteArrayInputStream(classSource.getBytes()); 104 } 105 106 void printCount(String kind, int count) { 107 System.out.println("Count: " + count); 108 } 109 110 /** 111 * Overidden so it loads the compiled class in the gate classloader rather 112 * than writting it on the disk. 113 * @param c the class symbol 114 * @throws IOException 115 */ 116 public void writeClass(com.sun.tools.javac.v8.code.Symbol.ClassSymbol c) 117 throws IOException { 118 //the compiler will try to write the class file too; 119 //we'll just load the class instead 120 ByteArrayOutputStream os = new ByteArrayOutputStream(4000); 121 new ClassWriter(Hashtable.make()).writeClassFile(os, c); 122 os.flush(); 123 byte[] bytes = os.toByteArray(); 124 // String className = c.className(); 125 //this is the full name with all the $ signs in the right place 126 String className = c.flatName().toJava(); 127 128 // //replace the final '.' with '$' for inner classes 129 // if(c.isInner()){ 130 // int loc = className.lastIndexOf('.'); 131 // if(loc != -1) className = className.substring(0, loc) + "$" + 132 // className.substring(loc + 1); 133 // } 134 //Out.pr(className + "[" + os.size() + " bytes]"); 135 Gate.getClassLoader().defineGateClass(className, 136 bytes, 0, os.size()); 137 } 138 139 Map sources; 140 MemoryLog memLog; 141 } 142 143 /** 144 * Compiles a set of java sources and loads the compiled classes in the gate 145 * class loader. 146 * @param sources a map from fully qualified classname to java source 147 * @throws GateException in case of a compilation error or warning. 148 * In the case of warnings the compiled classes are loaded before the error is 149 * raised. 150 */ 151 public static void loadClasses(Map sources) 152 throws GateException{ 153 //build the compiler 154 Hashtable options = Hashtable.make(); 155 MemoryLog log = new MemoryLog(sources); 156 157 options.put("-classpath", System.getProperty("java.class.path")); 158 159 160 JavaCompiler compiler = new GJC(log, 161 new Symtab(new ClassReader(options), 162 new ClassWriter(options)), 163 options, 164 sources); 165 166 //we have the compiler, let's put it to work 167 ArrayList classNames = new ArrayList(sources.keySet()); 168 for(int i = 0; i < classNames.size(); i++){ 169 String className = (String)classNames.get(i); 170 String filename = className.replace('.', 171 Strings.getFileSep().charAt(0)); 172 classNames.set(i, filename + ".java" ); 173 } 174 175 try{ 176 compiler.compile(List.make(classNames.toArray())); 177 }catch(Throwable t){ 178 throw new GateException(t); 179 } 180 181 //check for errors and warnings 182 if(log.errorsString != null && log.errorsString.length() > 0){ 183 throw new GateException(log.errorsString.toString()); 184 } 185 } 186 187 }
|
Javac |
|