X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Ftool%2FCompiler.java;fp=src%2Forg%2Fibex%2Ftool%2FCompiler.java;h=0000000000000000000000000000000000000000;hb=6f0cd02d46e011bd5599e1b7fefc6159cb811135;hp=382cf74c347218b1118b4383f9e1d43e37fc2e28;hpb=622d0e5a4b1b35b6918a516a79a0cc22272a919e;p=org.ibex.tool.git diff --git a/src/org/ibex/tool/Compiler.java b/src/org/ibex/tool/Compiler.java deleted file mode 100644 index 382cf74..0000000 --- a/src/org/ibex/tool/Compiler.java +++ /dev/null @@ -1,804 +0,0 @@ -package org.ibex.tool; - -import java.io.*; -import java.util.*; -import java.util.zip.*; -import java.util.jar.*; - -import java.lang.reflect.*; - -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.internal.compiler.ClassFile; -import org.eclipse.jdt.internal.compiler.CompilationResult; -//import org.eclipse.jdt.internal.compiler.Compiler; -import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; -import org.eclipse.jdt.internal.compiler.ICompilerRequestor; -import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; -import org.eclipse.jdt.internal.compiler.IProblemFactory; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; -import org.eclipse.jdt.internal.compiler.env.*; -import org.eclipse.jdt.internal.compiler.impl.*; -import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; - -// FEATURE: add build dependencies like make (grab some Java dependency-checker code off the net?) - -public class Compiler { - // Static Entry Point ///////////////////////////////////////////////////// - - public static void main(String[] args) throws IOException { - boolean verbose = false, veryverbose = false, warnings = true; - List srcdir = new ArrayList(); - String source = null, target = null, blddir = null, mainclass = null; - boolean buildjar = false; - - if (args.length == 0) args = new String[] { "--help" }; - for (int i=0; i < args.length; i++) { - if (args[i].charAt(0) == '-') { - if (args[i].length() == 1) { - System.out.println("Illegal switch: -"); return; } - switch (args[i].charAt(1)) { - case '-': - if (args[i].equals("--help")) printHelp(); - else System.out.println("Unknown switch: -"); - return; - case 'd': - if (i == args.length - 1) { - System.out.println("Missing parameter: "+args[i]); return; } - if (blddir != null) { System.out.println("cannot specify both -d and -j"); return; } - blddir = args[++i]; - break; - case 'j': - if (i == args.length - 1) { - System.out.println("Missing parameter: "+args[i]); return; } - if (blddir != null) { System.out.println("cannot specify both -d and -j"); return; } - blddir = args[++i]; - buildjar = true; - break; - case 'm': - if (i == args.length - 1) { - System.out.println("Missing parameter: "+args[i]); return; } - mainclass = args[++i]; - break; - case 'w': - if (i == args.length - 1) { - System.out.println("Missing parameter: "+args[i]); return; } - warnings = false; - break; - case 's': - if (i == args.length - 1) { - System.out.println("Missing parameter: "+args[i]); return; } - source = args[++i]; - break; - case 't': - if (i == args.length - 1) { - System.out.println("Missing parameter: "+args[i]); return; } - target = args[++i]; - break; - case 'v': - verbose = true; - break; - case 'V': - veryverbose = true; - break; - case 'h': - printHelp(); return; - - } - } else srcdir.add(args[i]); - } - - Compiler c = new Compiler(); - if (blddir != null) { - if (buildjar) c.setBuildJar(blddir); - else c.setBuildDir(blddir); - } - if (source != null) c.setSource(source); - if (target != null) c.setTarget(target); - if (mainclass != null) c.setMainClass(mainclass); - - String[] s = new String[srcdir.size()]; - srcdir.toArray(s); - c.setSourceDirs(s); - - c.setVerbose(verbose); - c.setWarnings(warnings); - c.setVeryVerbose(veryverbose); - c.compile(); - } - private static void printHelp() { - System.out.println("Usage java -cp ... org.ibex.tool.Compiler [options] ..."); - System.out.println("Options:"); - System.out.println(" -d Directory to put generated class files in"); - System.out.println(" -j Jar file to put generated class files in"); - System.out.println(" -m Main-Class for jar file."); - System.out.println(" -s Compile with specified source compatibility."); - System.out.println(" -t Compile with specified class file compatibility."); - System.out.println(" -v Verbose output."); - System.out.println(" -V Very Verbose output."); - System.out.println(" -h or --help Print this message."); - System.out.println(""); - } - - - // Compiler Interface ///////////////////////////////////////////////////// - - private ClassLoader loader = ClassLoader.getSystemClassLoader(); - private Map loaded = new HashMap(); - private PrintWriter out = new PrintWriter(System.out); - private Preprocessor preprocessor; - - private Source[] sources; - - private File builddir = null; - private boolean buildzip = false; - private ZipOutputStream jarfile = null; - private String mainclass = null; - - private String[] sourcedirs = new String[0]; - - private PrintWriter warn; - private boolean hasErrors; - private boolean verbose = false; - private boolean veryverbose = false; - private boolean warnings = true; - - public Compiler() { - List defs = Collections.EMPTY_LIST; - - String define = System.getProperty("org.ibex.tool.preprocessor.define"); - if (define != null) { - defs = new ArrayList(); - StringTokenizer st = new StringTokenizer(define.toUpperCase(), ","); - while (st.hasMoreTokens()) defs.add(st.nextToken().trim()); - } - - preprocessor = new Preprocessor(null, null, defs); - } - - public void setMainClass(String mainclass) { this.mainclass = mainclass; } - public void setBuildJar(String dir) throws IOException { - builddir = new File(dir == null ? "." : dir); - buildzip = true; - } - public void setBuildDir(String dir) throws IOException { - builddir = new File(dir == null ? "." : dir); - } - - public void setSourceDirs(String[] dir) { sourcedirs = dir; } - - /** Pass CompilerOptions.VERSION_1_*. A String of form "1.1", ".2", etc. */ - public void setSource(String v) { - if (v.equals("1.1")) settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_1); - else if (v.equals("1.2")) settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_2); - else if (v.equals("1.3")) settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); - else if (v.equals("1.4")) settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4); - else if (v.equals("1.5")) settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); - else throw new RuntimeException("I have no idea what Java " + v + " is. Ask David Crawshaw."); - } - - /** Pass CompilerOptions.VERSION_1_*. A String of form "1.1", ".2", etc. */ - public void setTarget(String v) { - if (v.equals("1.1")) settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); - else if (v.equals("1.2")) settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); - else if (v.equals("1.3")) settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3); - else if (v.equals("1.4")) settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); - else if (v.equals("1.5")) settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); - else throw new RuntimeException("I have no idea what Java " + v + " is. Ask David Crawshaw."); - } - - public void setVerbose(boolean v) { verbose = v; } - public void setVeryVerbose(boolean v) { veryverbose = v; } - public void setWarnings(boolean w) { warnings = w; } - - public void compile() throws IOException { - List s = new ArrayList(); - - if (buildzip) { - Manifest m = new Manifest(); - m.getMainAttributes().putValue("Manifest-Version", "1.0"); - if (mainclass != null) m.getMainAttributes().putValue("Main-Class", mainclass); - jarfile = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(builddir)), m); - } - for (int i=0; i < sourcedirs.length; i++) { - File src = new File(sourcedirs[i]); - if (!src.exists()) { - if (veryverbose) System.out.println("source directory not found: "+sourcedirs[i]); - continue; - } - filterSources(s, src, new char[0][], sourcedirs[i]); - } - - if (veryverbose) System.out.println("working with "+s.size() +" sources"); - sources = new Source[s.size()]; s.toArray(sources); - ICompilationUnit[] units = new ICompilationUnit[s.size()]; - int u = 0; for (int i=0; i < sources.length; i++) - if (sources[i].compiled == null) units[u++] = sources[i].unit; - if (u != units.length) { - ICompilationUnit[] newu = new ICompilationUnit[u]; - System.arraycopy(units, 0, newu, 0, u); - units = newu; - } - - hasErrors = false; - - StringWriter sw = new StringWriter(); - StringBuffer w = sw.getBuffer(); - warn = new PrintWriter(sw); - - org.eclipse.jdt.internal.compiler.Compiler jdt = - new org.eclipse.jdt.internal.compiler.Compiler( - env, policy, settings, results, problems); - jdt.compile(units); - - if (warnings && !hasErrors) { out.write(w.toString()); out.flush(); } - warn = null; - try { - if (jarfile != null) jarfile.close(); - } catch (Exception e) { - e.printStackTrace(); - } - if (verbose) System.out.print(clearing + " \r"); - } - - private final FilenameFilter filterSrcs = new FilenameFilter() { - public boolean accept(File dir, String name) { return name.endsWith(".java"); } - }; - private final FileFilter filterDirs = new FileFilter() { - public boolean accept(File path) { return path.isDirectory(); } - }; - private byte[] bytes(File bfile) { - byte[] bytes = new byte[2 * 1024]; - int pos = 0, in = 0; - try { - InputStream bin = new FileInputStream(bfile); - while ((in = bin.read(bytes, pos, bytes.length - pos)) != -1) { - pos += in; - if (pos == bytes.length) { - byte[] newbytes= new byte[pos * 2]; - System.arraycopy(bytes, 0, newbytes, 0, pos); - bytes = newbytes; - } - } - bin.close(); - } catch (IOException e) { - System.out.println("Error reading class file"); // FIXME - e.printStackTrace(); return null; - } - - if (pos != bytes.length) { - byte[] newbytes= new byte[pos * 2]; - System.arraycopy(bytes, 0, newbytes, 0, pos); - bytes = newbytes; - } - - return bytes; - } - private void filterSources(List s, File dir, char[][] pack, String srcdir) { - List bclasses = new ArrayList(); - File bdir = new File(builddir, str(pack, File.separatorChar)); - - // add the java files in this directory - File[] ja = dir.listFiles(filterSrcs); - for (int i=0; i < ja.length; i++) { - char[] n = name(classname(ja[i].getName())); - Source src = new Source(ja[i], n, pack, srcdir); - - // skip the file if the build version is newer than the source - String bclass = new String(n); - File bfile = new File(bdir, bclass + ".class"); - if (bfile.lastModified() > ja[i].lastModified()) { - src.compiled = bytes(bfile); - bclasses.add(bclass); - } - - s.add(src); - } - - // process the inner classes of any binary files - for (int i=0; i < bclasses.size(); i++) { - final String bc = (String)bclasses.get(i); - final FilenameFilter f = new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.length() > bc.length() && name.startsWith(bc) && - name.charAt(bc.length()) == '$' && name.endsWith(".class"); - } - }; - File[] bfile = bdir.listFiles(f); - for (int j=0; j < bfile.length; j++) { - Source src = new Source(bfile[j], - name(classname(bfile[j].getName())), pack, srcdir); - src.compiled = bytes(bfile[j]); - s.add(src); - } - } - - // add the subdirectories as packages - File[] d = dir.listFiles(filterDirs); - for (int i=0; i < d.length; i++) { - char[][] newpack = new char[pack.length + 1][]; - for (int j=0; j < pack.length; j++) newpack[j] = pack[j]; - newpack[pack.length] = d[i].getName().toCharArray(); - filterSources(s, d[i], newpack, srcdir); - } - } - - - /** Represents a file to be compiled. */ - final class Source { - char[] fileName; - char[] n; char[][] p; - File orig; - char[] processed = null; - byte[] compiled = null; - ClassFileReader reader = null; - - final ICompilationUnit unit = new ICompilationUnit() { - public char[] getMainTypeName() { return n; } - public char[][] getPackageName() { return p; } - public char[] getFileName() { return fileName; } - public char[] getContents() { - if (processed != null) return processed; - - try { - Reader r = new InputStreamReader(new BufferedInputStream( - new FileInputStream(orig))); - StringWriter w = new StringWriter(); - Vector err; - - synchronized (preprocessor) { - preprocessor.setReader(r); - preprocessor.setWriter(w); - err = preprocessor.process(); - } - - if (err.size() > 0) { - for (int i=0; i < err.size(); i++) { - Preprocessor.Warning warn = (Preprocessor.Warning)err.get(i); - out.print(getFileName()); - out.print(':'); - out.print(warn.getLine()); - out.print(':'); - out.print(warn instanceof Preprocessor.Error ? - " error: " : " warning: "); - out.println(warn.getMessage()); - } - return null; - } - - processed = w.toString().toCharArray(); - } catch (IOException e) { - System.out.println("IOException: "+e); // FIXME - return null; - } - - return processed; - } - }; - - private Source(File o, char[] n, char[][] p, String srcdir) { - orig = o; this.n = n; this.p = p; - String file = srcdir; - file += File.separatorChar + str(p, File.separatorChar); - file += File.separatorChar + new String(n) + ".java"; - fileName = file.toCharArray(); - } - } - - // ClassLoader Wrappers /////////////////////////////////////////////////// - - final static class LoadedNestedType implements IBinaryNestedType { - private Class c; - LoadedNestedType(Class c) { this.c = c; } - public char[] getName() { return name(c); } - public char[] getEnclosingTypeName() { return name(c.getDeclaringClass()); } - public int getModifiers() { return c.getModifiers(); } - } - - final static class LoadedField implements IBinaryField { - private Field f; - private Constant c; - - LoadedField(Field f) { - this.f = f; - int m = f.getModifiers(); - - c = Constant.NotAConstant; - if (Modifier.isFinal(m) && Modifier.isStatic(m)) { - try { - Class type = f.getType(); - if (type == Boolean.TYPE) { - c = new BooleanConstant(f.getBoolean(null)); - } else if (type == Byte.TYPE) { - c = new ByteConstant(f.getByte(null)); - } else if (type == Character.TYPE) { - c = new CharConstant(f.getChar(null)); - } else if (type == Double.TYPE) { - c = new DoubleConstant(f.getDouble(null)); - } else if (type == Float.TYPE) { - c = new FloatConstant(f.getFloat(null)); - } else if (type == Integer.TYPE) { - c = new IntConstant(f.getInt(null)); - } else if (type == Long.TYPE) { - c = new LongConstant(f.getLong(null)); - } else if (type == Short.TYPE) { - c = new ShortConstant(f.getShort(null)); - } else if (type == String.class) { - c = new StringConstant((String)f.get(null)); - } - } catch (IllegalAccessException e) {} - } - } - public Constant getConstant() { return c; } - public char[] getTypeName() { return typeName(f.getType()); } - public char[] getName() { return f.getName().toCharArray(); } - public int getModifiers() { return f.getModifiers(); } - } - - final static class LoadedConstructor implements IBinaryMethod { - private Constructor c; - private char[][] ex; - private char[] desc; - - LoadedConstructor(Constructor c) { - this.c = c; - - Class[] exs = c.getExceptionTypes(); - ex = new char[exs.length][]; - for (int i=0; i < ex.length; i++) ex[i] = name(exs[i]); - - desc = descriptor(c.getParameterTypes(), null); - } - public int getModifiers() { return c.getModifiers(); } - public char[] getSelector() { return c.getName().toCharArray(); } - public boolean isConstructor() { return true; } - public boolean isClinit() { return false; } - public char[][] getArgumentNames() { return null; } - public char[][] getExceptionTypeNames() { return ex; } - public char[] getMethodDescriptor() { return desc; } - } - - final static class LoadedMethod implements IBinaryMethod { - private Method m; - private char[][] ex; - private char[] desc; - - LoadedMethod(Method m) { - this.m = m; - - Class[] exs = m.getExceptionTypes(); - ex = new char[exs.length][]; - for (int i=0; i < ex.length; i++) ex[i] = name(exs[i]); - - desc = descriptor(m.getParameterTypes(), m.getReturnType()); - } - public int getModifiers() { return m.getModifiers(); } - public char[] getSelector() { return m.getName().toCharArray(); } - public boolean isConstructor() { return false; } - public boolean isClinit() { return false; } - public char[][] getArgumentNames() { return null; } // FEATURE: does this do anything cool? - public char[][] getExceptionTypeNames() { return ex; } - public char[] getMethodDescriptor() { return desc; } - } - - final static class LoadedClass implements IBinaryType { - private Class c; - private IBinaryField[] f; - private char[][] inf; - private IBinaryNestedType[] nested; - private IBinaryMethod[] meth = null; - - LoadedClass(Class c) { - this.c = c; - - Field[] fields = c.getDeclaredFields(); - List flist = new ArrayList(fields.length); - for (int i=0; i < fields.length; i++) - if (!Modifier.isPrivate(fields[i].getModifiers())) - flist.add(new LoadedField(fields[i])); - f = new IBinaryField[flist.size()]; - flist.toArray(f); - - Class[] interfaces = c.getInterfaces(); - inf = new char[interfaces.length][]; - for (int i=0; i < inf.length; i++) inf[i] = name(interfaces[i]); - - Class[] classes = c.getClasses(); - nested = new IBinaryNestedType[classes.length]; - for (int i=0; i < nested.length; i++) - nested[i] = new LoadedNestedType(classes[i]); - - Constructor[] constructors = c.getDeclaredConstructors(); - Method[] methods = c.getDeclaredMethods(); - if (methods.length + constructors.length > 0) { - List m = new ArrayList(methods.length + constructors.length); - for (int j=0; j < methods.length; j++) - if (!Modifier.isPrivate(methods[j].getModifiers())) - m.add(new LoadedMethod(methods[j])); - for (int j=0; j < constructors.length; j++) - if (!Modifier.isPrivate(constructors[j].getModifiers())) - m.add(new LoadedConstructor(constructors[j])); - meth = new IBinaryMethod[m.size()]; m.toArray(meth); - } - } - - public char[] getName() { return name(c); } - public char[] getEnclosingTypeName() { return name(c.getDeclaringClass()); } - public char[] getSuperclassName() { return name(c.getSuperclass()); } - public IBinaryField[] getFields() { return f; } - public char[][] getInterfaceNames() { return inf; } - public IBinaryNestedType[] getMemberTypes() { return nested; } - public IBinaryMethod[] getMethods() { return meth; } - public int getModifiers() { return c.getModifiers(); } - - public boolean isBinaryType() { return true; } - public boolean isClass() { return true; } - public boolean isInterface() { return c.isInterface(); } - public boolean isAnonymous() { return false; } - public boolean isLocal() { return false; } // FIXME - public boolean isMember() { return false; } // FIXME - public char[] sourceFileName() { return null; } - public char[] getFileName() { return null; } - - public boolean equals(Object o) { - return o == this || super.equals(o) || - (o != null && o instanceof LoadedClass && - c.equals(((LoadedClass)o).c)); - } - } - - - // Compiler Parameters //////////////////////////////////////////////////// - - /** Used by compiler to resolve classes. */ - final INameEnvironment env = new INameEnvironment() { - public NameEnvironmentAnswer findType(char[][] c) { return findType(name(c), pack(c)); } - public NameEnvironmentAnswer findType(char[] n, char[][] p) { - if (veryverbose) System.out.print("findType: "+ str(p, '.') + "."+new String(n)); - - try { - Class c = Class.forName(str(p, '.') + '.' + new String(n)); - if (veryverbose) System.out.println(" found in classloader: "+ c); - IBinaryType b = (IBinaryType)loaded.get(c); - if (b == null) loaded.put(c, b = new LoadedClass(c)); - return new NameEnvironmentAnswer(b); - } catch (ClassNotFoundException e) {} - - // cut out searches for java.* packages in sources list - if (p.length > 0 && eq(p[0], "java".toCharArray())) { - if (veryverbose) System.out.println(" not found, unknown java.*"); - return null; - } - - try { - for (int i=0; i < sources.length; i++) { - Source s = sources[i]; - if (eq(n, s.n) && eq(p, s.p)) { - if (s.reader != null) { - if (veryverbose) System.out.println(" found reader"); - return new NameEnvironmentAnswer(s.reader); - } - if (s.compiled != null) { - if (veryverbose) System.out.println(" found compiled, new reader"); - s.reader = new ClassFileReader(s.compiled, - s.orig.getName().toCharArray(), true); - return new NameEnvironmentAnswer(s.reader); - } - if (veryverbose) System.out.println(" found unit"); - return new NameEnvironmentAnswer(sources[i].unit); - } - } - } catch (ClassFormatException e) { - System.out.println("Unexpected ClassFormatException"); // FIXME - e.printStackTrace(); return null; - } - if (veryverbose) System.out.println(" not found"); - return null; - } - public boolean isPackage(char[][] parent, char[] name) { - if (veryverbose) System.out.println("isPackage: "+ str(parent, '.') + "."+new String(name)); - String parentName = str(parent, '/'); - for (int i=0; i < sources.length; i++) { - if (eq(name, sources[i].n) && eq(parent, sources[i].p)) return false; - if (eq(pack(sources[i].p), parent) && eq(name(sources[i].p), name)) return true; - } - return - loader.getResource(parentName + ".class") == null && - loader.getResource(parentName + '/' + new String(name) + ".class") == null; - } - public void cleanup() {} - }; - - /** Used by compiler to decide what do with problems.. */ - private final IErrorHandlingPolicy policy = - DefaultErrorHandlingPolicies.proceedWithAllProblems(); - - /** Used by compiler for general options. */ - private final Map settings = new HashMap(); - { - settings.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); - settings.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE); - settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); - settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); - }; - - /** Used by compiler for processing compiled classes and their errors. */ - private final ICompilerRequestor results = new ICompilerRequestor() { - public void acceptResult(CompilationResult result) { - if (veryverbose) System.out.println("got result: "+result); - if (result.hasProblems()) { - boolean err = false; - IProblem[] p = result.getProblems(); - PrintWriter o; - for (int i=0; i < p.length; i++) { - if (p[i].isError()) { o = out; err = true; } - else o = warn; - - o.print(p[i].getOriginatingFileName()); - o.print(':'); - o.print(p[i].getSourceLineNumber()); - o.print(':'); - o.print(p[i].isError() ? " error: " : " warning: "); - o.println(p[i].getMessage()); - } - out.flush(); - if (err) { hasErrors = true; return; } - } - - ClassFile[] c = result.getClassFiles(); - for (int i=0; i < c.length; i++) { - try { - char[][] name = c[i].getCompoundName(); - if (verbose) { - String pct = ""; - /*+ percent; - percent++; - while (pct.length() < 2) pct = " " + pct; - pct = "(" + pct + "%) "; - */ - String printme = " writing: " + pct + str(pack(name),'.') + "." + new String(name(name)); - if (clearing.length() < printme.length()) clearing = ""; - else clearing = clearing.substring(printme.length()); - System.out.print(printme + clearing + "\r"); - for(clearing = ""; clearing.length() < printme.length() + 5; clearing += " "); - } - if (buildzip) { - try { - jarfile.putNextEntry(new ZipEntry(str(pack(name), '/') + "/" + new String(name(name)) + ".class")); - jarfile.write(c[i].getBytes()); - } catch (java.util.zip.ZipException ze) { - // HACK: horrendous hack - if (ze.getMessage().indexOf("duplicate entry") != -1) { - //System.out.println("compiler emitted class twice: " + new String(name(name))); - } else { - throw ze; - } - } - } else { - // build package path to new class file - File path = new File(builddir, str(pack(name), '/')); - if (!path.exists()) path.mkdirs(); - // write new class file - path = new File(path, new String(name(name)) + ".class"); - OutputStream o = new BufferedOutputStream(new FileOutputStream(path)); - o.write(c[i].getBytes()); - o.close(); - } - } catch (IOException e) { - System.out.println("IOException writing class"); // FIXME - e.printStackTrace(); - } - } - } - }; - - int percent = 0; - String clearing = ""; - - /** Problem creater for compiler. */ - private final IProblemFactory problems = new DefaultProblemFactory(); - - - // Helper Functiosn /////////////////////////////////////////////////////// - - /** Convert source file path into class name block. - * eg. in: java/lang/String.java -> { {java} {lang} {String} } */ - private char[][] classname(String name) { - String delim = name.indexOf('/') == -1 ? "." : "/"; - name = name.trim(); - if (name.endsWith(".java")) name = name.substring(0, name.length() - 5); - if (name.endsWith(".class")) name = name.substring(0, name.length() - 6); - if (name.startsWith(delim)) name = name.substring(1); - - StringTokenizer st = new StringTokenizer(name, delim); - char[][] n = new char[st.countTokens()][]; - for (int i=0; st.hasMoreTokens(); i++) n[i] = st.nextToken().toCharArray(); - return n; - } - - /** Convert class name into a String. */ - private static String str(char[][] name, char delim) { - StringBuffer b = new StringBuffer(); - for (int i=0; name != null && i < name.length; i++) { - if (name[i] == null || name[i].length == 0) continue; - if (i > 0) b.append(delim); - b.append(name[i]); - } - return b.toString(); - } - - /** Returns the package component of a class name. - * Effectively returns char[length - 1][]. */ - private static char[][] pack(char[][] c) { - char[][] p = new char[c.length - 1][]; - for (int i=0; i < p.length; i++) p[i] = c[i]; - return p; - } - - /** Returns the direct-name component of a class name. - * eg. String from java.lang.String */ - private static char[] name(char[][] c) { return c[c.length - 1]; } - - /** Returns true of contents of both char arrays are equal. */ - private static boolean eq(char[][] c1, char[][] c2) { - if (c1 == null || c2 == null) return c1 == c2; - if (c1.length != c2.length) return false; - for (int i=0; i < c1.length; i++) if (!eq(c1[i], c2[i])) return false; - return true; - } - - /** Returns true of contents of both char arrays are equal. */ - private static boolean eq(char[] c1, char[] c2) { - if (c1 == null || c2 == null) return c1 == c2; - if (c1.length != c2.length) return false; - for (int i=0; i < c1.length; i++) if (c1[i] != c2[i]) return false; - return true; - } - - /** Returns class name as per VM Spec 4.2. eg. java/lang/String */ - private static char[] name(Class c) { - return c == null ? null : c.getName().replace('.', '/').toCharArray(); - } - - /** Returns the type name of a class as per VM Spec 4.3.2. */ - private static char[] typeName(Class p) { - StringBuffer sb = new StringBuffer(); - typeName(p, sb); - return sb.toString().toCharArray(); - } - - /** Returns the type name of a class as per VM Spec 4.3.2. - * eg. int -> I, String -> Ljava/lang/String; */ - private static void typeName(Class p, StringBuffer sb) { - String name = p.getName(); - switch (name.charAt(0)) { - case 'B': case 'C': case 'D': case 'F': case 'I': - case 'J': case 'S': case 'Z': case 'V': case '[': - sb.append(name(p)); break; - - case 'b': if (name.equals("boolean")) { sb.append('Z'); break; } - if (name.equals("byte")) { sb.append('B'); break; } - case 'c': if (name.equals("char")) { sb.append('C'); break; } - case 'd': if (name.equals("double")) { sb.append('D'); break; } - case 'f': if (name.equals("float")) { sb.append('F'); break; } - case 'i': if (name.equals("int")) { sb.append('I'); break; } - case 'l': if (name.equals("long")) { sb.append('J'); break; } - case 's': if (name.equals("short")) { sb.append('S'); break; } - case 'v': if (name.equals("void")) { sb.append('V'); break; } - default: - sb.append('L'); sb.append(name(p)); sb.append(';'); - } - } - - /** Returns the descriptor of a method per VM Spec 4.3.3. - * eg. int get(String n, boolean b) -> (Ljava/lang/String;B)I */ - private static char[] descriptor(Class[] p, Class r) { - StringBuffer sb = new StringBuffer(); - sb.append('('); - if (p != null) for (int i=0; i < p.length; i++) typeName(p[i], sb); - sb.append(')'); - if (r != null) typeName(r, sb); - return sb.toString().toCharArray(); - } - -}