!7 m { // md5 to class dir // class dirs are in {user.home}/.javax, so they might get deleted // after a day. we check for dir existence when using the cache. static new Map cache; p { readLocally("cache"); makeAndroid("Compiler bot!"); } static synchronized S answer(S s) { //print("Compile bot processing: " + shorten(s, 200)); //print(shorten(structure(parse3(s)), 200)); //print(structure(parse3("Please compile this Java text: *"))); new Matches m; if (match3("Please compile this JavaX snippet: *", s, m)) { S snippetID = unquote(m.m[0]); S transpiledSrc = getServerTranspiled(snippetID); int i = transpiledSrc.indexOf('\n'); String libs = transpiledSrc.substring(0, Math.max(0, i)); transpiledSrc = transpiledSrc.substring(i+1); return compile(transpiledSrc); } if (match3("Please compile this Java text: *", s, m)) { String src = unquote(m.m[0]); return compile(src); } if (match3("Please compile this Java text: * for java version *", s, m)) { String src = unquote(m.m[0]); String target = unquote(m.m[1]); return compile(src, target); } return null; } static synchronized S compile(S src) { return compile(src, null); } static synchronized S compile(S src, S javaTarget) { S md5 = md5(src); File classesDir = cache.get(md5); if (classesDir == null || !classesDir.isDirectory()) { Class j = getJavaX(); setOpt(j, "javaTarget", javaTarget); //setOpt(j, "verbose", true); File srcDir = cast call(j, "TempDirMaker_make"); L tok = javaTok(src); S className = null; if (tok.contains("package")) splitJavaFiles(tok, srcDir); else { className = getNameOfPublicClass(tok); if (className == null) className = getNameOfAnyClass(tok); S fileName = className + ".java"; saveTextFile(new File(srcDir, fileName), src); } classesDir = (File) call(j, "TempDirMaker_make"); new L libraries; try { print("Compiler said: " + call(j, "compileJava", srcDir, libraries, classesDir)); // sanity test if (!tok.contains("package")) if (!new File(classesDir, className + ".class").exists()) fail("No class generated (" + className + ")"); } catch (Exception e) { e.printStackTrace(); return "Compile Error. " + getOpt(j, "javaCompilerOutput"); } cache.put(md5, classesDir); // cache on success only saveLocally("cache"); } else print("Getting classes from cache."); return "ok, " + quote(classesDir.getAbsolutePath()); } static S getNameOfPublicClass(L tok) { for (L c : allClasses(tok)) if (modifiersContain(c, "public")) return getClassDeclarationName(c); return null; } static L modifiers = litlist("static", "abstract", "public", "private", "protected", "final", "native", "volatile", "synchronized", "transient"); static boolean modifiersContain(L tok, S modifier) { for (int i = 1; i < tok.size() && modifiers.contains(tok.get(i)); i += 2) if (tok.get(i).equals(modifier)) return true; return false; } }