From 8694fb6d7cdc635f39232f7a7fa65c04f106cee0 Mon Sep 17 00:00:00 2001 From: crawshaw Date: Mon, 22 Nov 2004 20:10:15 +0000 Subject: [PATCH] add constants support to compiler darcs-hash:20041122201015-2eb37-333c418019833ef1decad33865c85bb9197da06c.gz --- src/java/org/ibex/tool/Compiler.java | 240 ++++++++++++++++++++-------------- 1 file changed, 145 insertions(+), 95 deletions(-) diff --git a/src/java/org/ibex/tool/Compiler.java b/src/java/org/ibex/tool/Compiler.java index a9e6b0c..4ab50be 100644 --- a/src/java/org/ibex/tool/Compiler.java +++ b/src/java/org/ibex/tool/Compiler.java @@ -15,15 +15,8 @@ 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.IBinaryField; -import org.eclipse.jdt.internal.compiler.env.IBinaryMethod; -import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType; -import org.eclipse.jdt.internal.compiler.env.IBinaryType; -import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; -import org.eclipse.jdt.internal.compiler.env.INameEnvironment; -import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; -import org.eclipse.jdt.internal.compiler.impl.Constant; +import org.eclipse.jdt.internal.compiler.env.*; +import org.eclipse.jdt.internal.compiler.impl.*; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; public class Compiler { @@ -58,7 +51,52 @@ public class Compiler { } - // Compiler Parameters //////////////////////////////////////////////////// + /** Represents a file to be compiled. */ + final class Source { + char[] n; char[][] p; + File orig; + char[] processed = null; + byte[] compiled = null; + + ICompilationUnit unit = new ICompilationUnit() { + public char[] getMainTypeName() { return n; } + public char[][] getPackageName() { return p; } + public char[] getFileName() { return orig.getName().toCharArray(); } + 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) { + System.out.println("Preprocessor Errors, "+err); // FIXME + 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) { + orig = o; this.n = n; this.p = p; } + } + + // ClassLoader Wrappers /////////////////////////////////////////////////// final static class LoadedNestedType implements IBinaryNestedType { private Class c; @@ -70,45 +108,42 @@ public class Compiler { final static class LoadedField implements IBinaryField { private Field f; - LoadedField(Field f) { this.f = f; } - public Constant getConstant() { return Constant.NotAConstant; }// FIXME - public char[] getTypeName() { return typeName(f.getType()); } - public char[] getName() { return f.getName().toCharArray(); } - public int getModifiers() { return f.getModifiers(); } - } + private Constant c; - private static char[] typeName(Class p) { - StringBuffer sb = new StringBuffer(); - typeName(p, sb); - return sb.toString().toCharArray(); - } - 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); break; + LoadedField(Field f) { + this.f = f; + int m = f.getModifiers(); - 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(';'); + c = Constant.NotAConstant; + if (Modifier.isFinal(m) && Modifier.isStatic(m)) { + try { + Class type = f.getType(); + if (type == Boolean.class) { + c = new BooleanConstant(f.getBoolean(null)); + } else if (type == Byte.class) { + c = new ByteConstant(f.getByte(null)); + } else if (type == Character.class) { + c = new CharConstant(f.getChar(null)); + } else if (type == Double.class) { + c = new DoubleConstant(f.getDouble(null)); + } else if (type == Float.class) { + c = new FloatConstant(f.getFloat(null)); + } else if (type == Integer.class) { + c = new IntConstant(f.getInt(null)); + } else if (type == Long.class) { + c = new LongConstant(f.getLong(null)); + } else if (type == Short.class) { + c = new ShortConstant(f.getShort(null)); + } else if (type == String.class) { + c = new StringConstant((String)f.get(null)); + } + } catch (IllegalAccessException e) {} + } } - } - 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(); + 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 { @@ -152,7 +187,7 @@ public class Compiler { public char[] getSelector() { return m.getName().toCharArray(); } public boolean isConstructor() { return false; } public boolean isClinit() { return false; } - public char[][] getArgumentNames() { return null; } // FIXME: does this do anything cool? + public char[][] getArgumentNames() { return null; } // FEATURE: does this do anything cool? public char[][] getExceptionTypeNames() { return ex; } public char[] getMethodDescriptor() { return desc; } } @@ -213,7 +248,10 @@ public class Compiler { } - private final INameEnvironment env = new INameEnvironment() { + // 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) { try { @@ -231,7 +269,7 @@ public class Compiler { new NameEnvironmentAnswer(new ClassFileReader(sources[i].compiled, sources[i].orig.getName().toCharArray(), true)); } catch (ClassFormatException e) { - System.out.println("FIXME unexpected ClassFormatException"); + System.out.println("Unexpected ClassFormatException"); // FIXME e.printStackTrace(); } return null; @@ -247,9 +285,11 @@ public class Compiler { 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); @@ -258,6 +298,7 @@ public class Compiler { 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 (result.hasProblems()) { @@ -273,7 +314,7 @@ public class Compiler { out.write(p[i].getMessage()); } } catch (IOException e) { - System.out.println("FIXME severe: IOException on out"); + System.out.println("severe: IOException on out"); // FIXME e.printStackTrace(); } if (hasErrors) return; @@ -288,62 +329,21 @@ public class Compiler { o.write(c[i].getBytes()); o.close(); } catch (IOException e) { - System.out.println("FIXME: IOException writing class"); + System.out.println("IOException writing class"); // FIXME e.printStackTrace(); } } } }; + /** Problem creater for compiler. */ private final IProblemFactory problems = new DefaultProblemFactory(); - private final class Source { - char[] n; char[][] p; - File orig; - char[] processed = null; - byte[] compiled = null; - - ICompilationUnit unit = new ICompilationUnit() { - public char[] getMainTypeName() { return n; } - public char[][] getPackageName() { return p; } - public char[] getFileName() { return orig.getName().toCharArray(); } - 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) { - System.out.println("Preprocessor Errors, "+err); // FIXME - return null; - } - - processed = w.toString().toCharArray(); - } catch (IOException e) { - System.out.println("FIXME: IOException: "+e); // FIXME - return null; - } - - return processed; - } - }; - - private Source(File o, char[] n, char[][] p) { - orig = o; this.n = n; this.p = p; } - } // Helper Functiosn /////////////////////////////////////////////////////// - /** Convert source file path into class name. */ + /** 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(); @@ -356,6 +356,7 @@ public class Compiler { return n; } + /** Convert class name into a String. */ private static String str(char[][] name, char delim) { StringBuffer b = new StringBuffer(); if (name != null) for (int i=0; i < name.length; i++) @@ -364,27 +365,76 @@ public class Compiler { 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.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.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); 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(); + } + } -- 1.7.10.4