public class Compiler {
+ // Static Entry Point /////////////////////////////////////////////////////
+
+ public static void main(String[] args) {
+ String source = null, target = null;
+ String srcdir = null, blddir = null;
+
+ 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; }
+ blddir = args[++i];
+ 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 'h':
+ printHelp(); return;
+
+ }
+ } else srcdir = args[i];
+ }
+
+ Compiler c = new Compiler();
+ if (blddir != null) c.setBuildDir(blddir);
+ if (srcdir != null) c.setSourceDir(srcdir);
+ if (source != null) c.setSource(source);
+ if (target != null) c.setTarget(target);
+ c.compile();
+ }
+ private static void printHelp() {
+ System.out.println("Usage java -cp ... org.ibex.tool.Compiler <options> <source directory>");
+ System.out.println("Options:");
+ System.out.println(" -d <directory> Location for generated class files.");
+ System.out.println(" -s <release> Compile with specified source compatibility.");
+ System.out.println(" -t <release> Compile with specified class file compatibility.");
+ 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 Writer out = new PrintWriter(System.out);
+ private PrintWriter out = new PrintWriter(System.out);
private Preprocessor preprocessor = new Preprocessor(null, null, Collections.EMPTY_LIST);
private Source[] sources;
- private ICompilationUnit[] units;
+ private File builddir = new File(".");
+ private File sourcedir = new File(".");
- public static void main(String[] args) {
- new Compiler(args);
- }
+ public Compiler() { }
- public Compiler(String[] files) {
- sources = new Source[files.length];
- units = new ICompilationUnit[files.length];
+ public void setBuildDir(String dir) { builddir = new File(dir == null ? "." : dir); }
+ public void setSourceDir(String dir) { sourcedir = new File(dir == null ? "." : dir); }
- for (int i=0; i < files.length; i++) {
- char[][] n = classname(files[i]);
- sources[i] = new Source(new File(files[i]), name(n), pack(n));
- units[i] = sources[i].unit;
- }
+ /** Pass CompilerOptions.VERSION_1_*. A String of form "1.1", ".2", etc. */
+ public void setSource(String v) { settings.put(CompilerOptions.OPTION_Source, v); }
+
+ /** Pass CompilerOptions.VERSION_1_*. A String of form "1.1", ".2", etc. */
+ public void setTarget(String v) { settings.put(CompilerOptions.OPTION_TargetPlatform, v); }
+
+ public void setBuilddir(File f) { builddir = f; }
+ public void compile() {
+ List s = new ArrayList();
+ filterSources(s, sourcedir, new char[0][]);
+ System.out.println("working with "+s.size() +" sources");
+ sources = new Source[s.size()]; s.toArray(sources);
+ ICompilationUnit[] units = new ICompilationUnit[s.size()];
+ for (int i=0; i < sources.length; i++) units[i] = sources[i].unit;
+
+ System.out.println("compiling");
org.eclipse.jdt.internal.compiler.Compiler jdt =
new org.eclipse.jdt.internal.compiler.Compiler(
env, policy, settings, results, problems);
jdt.compile(units);
}
+ 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 void filterSources(List s, File dir, char[][] pack) {
+ File[] ja = dir.listFiles(filterSrcs);
+ for (int i=0; i < ja.length; i++)
+ s.add(new Source(ja[i], name(classname(ja[i].getName())), pack));
+
+ 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);
+ }
+ }
+
/** Represents a file to be compiled. */
final class Source {
+ char[] fileName;
char[] n; char[][] p;
File orig;
char[] processed = null;
byte[] compiled = null;
- ICompilationUnit unit = new ICompilationUnit() {
+ final ICompilationUnit unit = new ICompilationUnit() {
public char[] getMainTypeName() { return n; }
public char[][] getPackageName() { return p; }
- public char[] getFileName() { return orig.getName().toCharArray(); }
+ public char[] getFileName() { return fileName; }
public char[] getContents() {
if (processed != null) return processed;
};
private Source(File o, char[] n, char[][] p) {
- orig = o; this.n = n; this.p = p; }
+ orig = o; this.n = n; this.p = p;
+ try { fileName = orig.getCanonicalPath().toCharArray(); } // FIXME: dont use full path
+ catch (IOException e) { fileName = orig.getName().toCharArray(); }
+ }
}
// ClassLoader Wrappers ///////////////////////////////////////////////////
if (Modifier.isFinal(m) && Modifier.isStatic(m)) {
try {
Class type = f.getType();
- if (type == Boolean.class) {
+ if (type == Boolean.TYPE) {
c = new BooleanConstant(f.getBoolean(null));
- } else if (type == Byte.class) {
+ } else if (type == Byte.TYPE) {
c = new ByteConstant(f.getByte(null));
- } else if (type == Character.class) {
+ } else if (type == Character.TYPE) {
c = new CharConstant(f.getChar(null));
- } else if (type == Double.class) {
+ } else if (type == Double.TYPE) {
c = new DoubleConstant(f.getDouble(null));
- } else if (type == Float.class) {
+ } else if (type == Float.TYPE) {
c = new FloatConstant(f.getFloat(null));
- } else if (type == Integer.class) {
+ } else if (type == Integer.TYPE) {
c = new IntConstant(f.getInt(null));
- } else if (type == Long.class) {
+ } else if (type == Long.TYPE) {
c = new LongConstant(f.getLong(null));
- } else if (type == Short.class) {
+ } else if (type == Short.TYPE) {
c = new ShortConstant(f.getShort(null));
} else if (type == String.class) {
c = new StringConstant((String)f.get(null));
for (int i=0; i < ex.length; i++) ex[i] = name(exs[i]);
desc = descriptor(m.getParameterTypes(), m.getReturnType());
+ /*if (new String(desc).indexOf("[") > -1)
+ System.out.println("method: "+m+", desc="+new String(desc));*/ // DEBUG
}
public int getModifiers() { return m.getModifiers(); }
public char[] getSelector() { return m.getName().toCharArray(); }
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));
+ }
}
final INameEnvironment env = new INameEnvironment() {
public NameEnvironmentAnswer findType(char[][] c) { return findType(name(c), pack(c)); }
public NameEnvironmentAnswer findType(char[] n, char[][] p) {
+ boolean DEBUG = false;
+ if (DEBUG) System.out.println("requesting: "+ str(p, '.') + "."+new String(n));
+
try {
Class c = Class.forName(str(p, '.') + '.' + new String(n));
+ if (DEBUG) System.out.println("found class: "+ c);
IBinaryType b = (IBinaryType)loaded.get(c);
if (b == null) loaded.put(c, b = new LoadedClass(c));
+ if (DEBUG) System.out.println("returning "+b+", name="+new String(b.getName()));
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())) return null;
+
try {
for (int i=0; i < sources.length; i++)
if (eq(n, sources[i].n) && eq(p, sources[i].p))
if (eq(name, sources[i].n) && eq(parent, sources[i].p)) return false;
return
loader.getResource(parentName + ".class") == null &&
- loader.getResource(parentName + '/' + name + ".class") == null;
+ loader.getResource(parentName + '/' + new String(name) + ".class") == null;
}
public void cleanup() {}
};
/** Used by compiler for processing compiled classes and their errors. */
private final ICompilerRequestor results = new ICompilerRequestor() {
public void acceptResult(CompilationResult result) {
+ System.out.println("got result: "+result);
if (result.hasProblems()) {
boolean hasErrors = false;
IProblem[] p = result.getProblems();
- try {
- for (int i=0; i < p.length; i++) {
- if (p[i].isError()) hasErrors = true;
- out.write(p[i].getOriginatingFileName());
- out.write(':');
- out.write(p[i].getSourceLineNumber());
- out.write(':');
- out.write(p[i].getMessage());
- }
- } catch (IOException e) {
- System.out.println("severe: IOException on out"); // FIXME
- e.printStackTrace();
+ for (int i=0; i < p.length; i++) {
+ if (p[i].isError()) hasErrors = true;
+ out.print(p[i].getOriginatingFileName());
+ out.print(':');
+ out.print(p[i].getSourceLineNumber());
+ out.print(':');
+ out.println(p[i].getMessage());
}
+ out.flush();
if (hasErrors) return;
}
ClassFile[] c = result.getClassFiles();
for (int i=0; i < c.length; i++) {
try {
- String name = str(c[i].getCompoundName(), '/') + ".class";
+ // build package path to new class file
+ File path = builddir;
+ char[][] name = c[i].getCompoundName();
+ path = new File(builddir, str(pack(name), '/'));
+ System.out.println("DEBUG: creating path "+path+", out of builddir="+builddir);
+ if (!path.exists()) path.mkdirs();
+
+ // write new class file
+ path = new File(path, new String(name(name)) + ".class");
+ System.out.println("DEBUG: writing file "+path);
OutputStream o = new BufferedOutputStream(
- new FileOutputStream(new File(name)));
+ new FileOutputStream(path));
o.write(c[i].getBytes());
o.close();
} catch (IOException e) {
/** 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++)
- if (name[i] != null) { b.append(delim); b.append(name[i]); }
- if (b.length() > 0) b.deleteCharAt(0);
+ 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();
}
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;
+ sb.append(name(p)); break;
case 'b': if (name.equals("boolean")) { sb.append('Z'); break; }
if (name.equals("byte")) { sb.append('B'); break; }