//package spimedb.util.js; // //import org.slf4j.Logger; //import org.slf4j.LoggerFactory; //import org.teavm.cache.DiskRegularMethodNodeCache; //import org.teavm.cache.FileNameEncoder; //import org.teavm.cache.ProgramIO; //import org.teavm.cache.SymbolTable; //import org.teavm.diagnostics.DefaultProblemTextConsumer; //import org.teavm.diagnostics.Problem; //import org.teavm.diagnostics.ProblemSeverity; //import org.teavm.javascript.MethodNodeCache; //import org.teavm.javascript.ast.AsyncMethodNode; //import org.teavm.javascript.ast.RegularMethodNode; //import org.teavm.model.*; //import org.teavm.model.instructions.*; //import org.teavm.parsing.ClassDateProvider; //import org.teavm.parsing.ClasspathClassHolderSource; //import org.teavm.vm.TeaVM; //import org.teavm.vm.TeaVMBuilder; // //import java.io.*; //import java.util.*; //import java.util.concurrent.ConcurrentHashMap; // ///** convenient wrapper for TeaVM compiler which produces client-side JS from Java src */ //public class JavaToJavascript { // // static final Logger logger = LoggerFactory.getLogger(JavaToJavascript.class); // // static final ClassLoader cl = JavaToJavascript.class.getClassLoader(); // static final int FILE_BUFFER_SIZE = 1024 * 1024; // // final TeaVMBuilder builder; // final ProgramCache programCache; // final MethodNodeCache methodCache; // //private final Properties properties; // // public static JavaToJavascript build() { // // ClasspathClassHolderSource chs = new ClasspathClassHolderSource(); // // return new JavaToJavascript( // chs, // /*new MyDiskProgramCache(HTTP.tmpCacheDir().toFile(), // new MyFileSymbolTable(HTTP.tmpCacheFile("sym")), // new MyFileSymbolTable(HTTP.tmpCacheFile("file")), // chs // ),*/ // new MapProgramCache(new ConcurrentHashMap()), // new ConcurrentMapMethodNodeCache() // // //doesnt work yet: // /*new DiskRegularMethodNodeCache( // HTTP.tmpCacheDir().toFile(), // sym, // file, // chs // )*/ // ); // } // // public JavaToJavascript() { // this(new ClasspathClassHolderSource(), new MapProgramCache(new ConcurrentHashMap<>()), new ConcurrentMapMethodNodeCache()); // } // //// public JavaToJavascript(Map<MethodReference, Program> cache) { //// this(new MyMemoryProgramCache(cache)); //// } //// //// public JavaToJavascript(ProgramCache programCache) { //// this(new ClasspathClassHolderSource(), programCache ); //// } // // public JavaToJavascript(ClasspathClassHolderSource chs, ProgramCache programCache, MethodNodeCache methodCache) { // builder = new TeaVMBuilder() // .setClassLoader(cl) // .setClassSource( // new PreOptimizingClassHolderSource(chs) // ); // //this.properties = new Properties(); // // this.methodCache = methodCache; // this.programCache = programCache; // // // } // // // public StringBuilder compile(String entryFunc, MethodReference method) { // // long startTime = System.currentTimeMillis(); // // TeaVM t = builder.build(); // // // t.installPlugins(); // //// t.add(new AbstractDependencyListener() { //// //// @Override //// public void classReached(DependencyAgent agent, String className, CallLocation location) { //// System.out.println(className + " @ " + (location!=null ? location.getMethod() : "")); //// } //// //// }); // // t.setProgramCache(programCache); // t.setAstCache(methodCache); // // t.entryPoint(entryFunc, method); // t.setMinifying(false); //when true, mangles leaflet's L variable // t.setIncremental(true); // //t.setProperties(properties); // // // // /*t.setProgressListener(new TeaVMProgressListener() { // // @Override // public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) { // logger.info("start {} {}", phase, count); // return TeaVMProgressFeedback.CONTINUE; // } // // @Override // public TeaVMProgressFeedback progressReached(int progress) { // //logger.info("@ {}", progress); // return TeaVMProgressFeedback.CONTINUE; // } // });*/ // // StringBuilder sb = new StringBuilder(FILE_BUFFER_SIZE); // t.build(sb, null); // // // //t.build(new File("/tmp/a"), "main.js"); // // List<Problem> problems = t.getProblemProvider().getSevereProblems(); // if (!problems.isEmpty()) { // DefaultProblemTextConsumer pc = new DefaultProblemTextConsumer(); // // problems.forEach(p -> { // p.render(pc); // // if (p.getSeverity() == ProblemSeverity.ERROR) // logger.error("{}: {}", p.getLocation(), pc.getText()); // else if (p.getSeverity() == ProblemSeverity.WARNING) // logger.warn("{}: {}", p.getLocation(), pc.getText()); // // pc.clear(); // }); // } // // if (t.wasCancelled()) { // logger.error("cancelled: {}", problems); // return null; // } // // // long endTime = System.currentTimeMillis(); // logger.info("compiled {} to {} bytes .JS in {} ms", method, sb.length(), endTime-startTime); // logger.info("\tcache: {} {}", programCache, methodCache); // // // if (programCache instanceof MyDiskProgramCache) { // try { // ((MyDiskProgramCache) programCache).commit(); // } catch (IOException e) { // logger.error("flush programCache: {}", e); // } // } // if (methodCache instanceof DiskRegularMethodNodeCache) { // try { // ((DiskRegularMethodNodeCache) methodCache).flush(); // } catch (IOException e) { // logger.error("flush methodCache: {}", e); // } // } // //// System.out.println(t.getClasses()); //// System.out.println(t.getDependencyInfo().getCallGraph()); //// System.out.println(t.getDependencyInfo().getReachableMethods()); //// System.out.println(t.getWrittenClasses().getClassNames()); // // return sb; // } // // /** compiles the static void main() method of a class */ // public StringBuilder compileMain(Class c) { // MethodReference method = new MethodReference(c, "main", String[].class, void.class); // // //return compile(null, new MethodReference(c, "main", String[].class)); // // return compile("main", method ); // } // // public static class MapProgramCache implements ProgramCache { // // private final Map<MethodReference, Program> cache; // // public MapProgramCache(Map<MethodReference, Program> cache) { // this.cache = cache; // } // // @Override // public Program get(MethodReference method) { // return cache.get(method); // } // // @Override // public void store(MethodReference method, Program program) { // cache.put(method, /*ProgramUtils.copy*/(program)); // } // // @Override // public String toString() { // return "MapProgramCache{" + // "size=" + cache.size() + // '}'; // } // } // // public static class ConcurrentMapMethodNodeCache implements MethodNodeCache { // private final Map<MethodReference, RegularMethodNode> cache = new ConcurrentHashMap<>(1024); // private final Map<MethodReference, AsyncMethodNode> asyncCache = new ConcurrentHashMap<>(1024); // // @Override // public RegularMethodNode get(MethodReference methodReference) { // return cache.get(methodReference); // } // // @Override // public void store(MethodReference methodReference, RegularMethodNode node) { // cache.put(methodReference, node); // } // // @Override // public AsyncMethodNode getAsync(MethodReference methodReference) { // return null; // //return asyncCache.get(methodReference); // } // // @Override // public void storeAsync(MethodReference methodReference, AsyncMethodNode node) { // //asyncCache.put(methodReference, node); // } // // @Override // public String toString() { // return "MyMemoryRegularMethodNodeCache{size=" + cache.size() + "+" + asyncCache.size() + '}'; // } // } // // public static class MyFileSymbolTable implements SymbolTable { // private final File file; // private final List<String> symbols = Collections.synchronizedList(new ArrayList<>()); // private final Map<String, Integer> symbolMap = new ConcurrentHashMap<>(); // // // public MyFileSymbolTable(File file) { // this.file = file; // } // // public void update() throws IOException { // synchronized (symbols) { // symbols.clear(); // symbolMap.clear(); // try (DataInputStream input = new DataInputStream(new BufferedInputStream(new FileInputStream(file), 32 * 1024))) { // //StringBuilder sb = new StringBuilder(); // int nextNum = symbols.size(); // while (true) { //// int length = input.read(); //// if (length == -1) { //// break; //// } // try { // String symbol = input.readUTF();//sb.toString(); // if (symbolMap.putIfAbsent(symbol, nextNum) == null) { // symbols.add(symbol); // nextNum++; // } // //assert(symbols.size() == symbolMap.size()); // } catch (EOFException ee) { // break; // } // } // } // } // } // // public void commit() throws IOException { // synchronized (symbols) { // // try (BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(file, true))) { // // DataOutputStream output = new DataOutputStream(bos); // for (String s : symbols) // output.writeUTF(s); // output.close(); // } // } // } // // @Override // public String at(int index) { // return symbols.get(index); // } // // @Override // public int lookup(String symbol) { // return symbolMap.computeIfAbsent(symbol, s -> { // int index; // synchronized (symbols) { // index = symbols.size(); // symbols.add(s); // } // return index; // }); // } // } // // /** // * // * @author Alexey Andreev // */ // static public class MyDiskProgramCache implements ProgramCache { // private final File directory; // private final ProgramIO programIO; // private final Map<MethodReference, Item> cache = new ConcurrentHashMap<>(); // private final Set<MethodReference> newMethods = new HashSet(); // private final ClassDateProvider classDateProvider; // private final MyFileSymbolTable fileTable, symbolTable; // // public MyDiskProgramCache (File directory, MyFileSymbolTable symbolTable, MyFileSymbolTable fileTable, // ClassDateProvider classDateProvider) { // this.directory = directory; // // programIO = new ProgramIO(symbolTable, fileTable); // // this.fileTable = fileTable; // this.symbolTable = symbolTable; // // this.classDateProvider = classDateProvider; // // update(symbolTable, fileTable); // // } // // private static void update(MyFileSymbolTable symbolTable, MyFileSymbolTable fileTable) { // try { // fileTable.update(); // symbolTable.update(); // } catch (IOException e) { // logger.error("file and symbol table: {}", e); // } // } // // // @Override // public Program get(MethodReference method) { // return cache.computeIfAbsent(method, m -> { // Item item = new Item(); // File file = getMethodFile(method); // if (file.exists()) { // try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) { // DataInput input = new DataInputStream(stream); // int depCount = input.readShort(); // boolean dependenciesChanged = false; // for (int i = 0; i < depCount; ++i) { // String depClass = input.readUTF(); // Date depDate = classDateProvider.getModificationDate(depClass); // if (depDate == null || depDate.after(new Date(file.lastModified()))) { // dependenciesChanged = true; // break; // } // } // if (!dependenciesChanged) { // item.program = programIO.read(stream); // } // } catch (IOException e) { // // we could not read program, just leave it empty // } // } // return item; // }).program; // } // // @Override // public void store(MethodReference method, Program program) { // Item item = new Item(); // item.program = program; // if (cache.put(method, item)==null) { // newMethods.add(method); // } // } // // public void commit() throws IOException { // for (Iterator<MethodReference> iterator = newMethods.iterator(); iterator.hasNext(); ) { // MethodReference method = iterator.next(); // iterator.remove(); // // ProgramDependencyAnalyzer analyzer = new ProgramDependencyAnalyzer(); // // Program program = cache.get(method).program; // for (int i = 0; i < program.basicBlockCount(); ++i) { // BasicBlock block = program.basicBlockAt(i); // List<Instruction> instructions = block.getInstructions(); // for (int i1 = 0, instructionsSize = instructions.size(); i1 < instructionsSize; i1++) { // instructions.get(i1).acceptVisitor(analyzer); // } // } // // Set<String> deps = analyzer.dependencies; // deps.add(method.getClassName()); // // File file = getMethodFile(method); // file.getParentFile().mkdirs(); // try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file), FILE_BUFFER_SIZE)) { // DataOutputStream output = new DataOutputStream(stream); // output.writeShort(deps.size()); // for (String dep : deps) { // output.writeUTF(dep); // } // programIO.write(program, output); // output.close(); // } // } // // newMethods.clear(); // // fileTable.commit(); // symbolTable.commit(); // } // // private File getMethodFile(MethodReference method) { // File dir = new File(directory, method.getClassName().replace('.', '/')); // return new File(dir, FileNameEncoder.encodeFileName(method.getDescriptor().toString()) + ".teavm-opt"); // } // // static class Item { // Program program; // } // // static class ProgramDependencyAnalyzer implements InstructionVisitor { // final Set<String> dependencies = new HashSet<>(); // // public void clear() { // dependencies.clear(); // } // // @Override public void visit(GetFieldInstruction insn) { // dependencies.add(insn.getField().getClassName()); // } // @Override public void visit(PutFieldInstruction insn) { // dependencies.add(insn.getField().getClassName()); // } // @Override public void visit(InvokeInstruction insn) { // dependencies.add(insn.getMethod().getClassName()); // } // // @Override // public void visit(InvokeDynamicInstruction insn) { // List<RuntimeConstant> bootstrapArguments = insn.getBootstrapArguments(); // for (int i = 0, bootstrapArgumentsSize = bootstrapArguments.size(); i < bootstrapArgumentsSize; i++) { // RuntimeConstant cst = bootstrapArguments.get(i); // if (cst.getKind() == RuntimeConstant.METHOD_HANDLE) { // MethodHandle handle = cst.getMethodHandle(); // dependencies.add(handle.getClassName()); // } // } // } // @Override public void visit(EmptyInstruction insn) { } // @Override public void visit(ClassConstantInstruction insn) { } // @Override public void visit(NullConstantInstruction insn) { } // @Override public void visit(IntegerConstantInstruction insn) { } // @Override public void visit(LongConstantInstruction insn) { } // @Override public void visit(FloatConstantInstruction insn) { } // @Override public void visit(DoubleConstantInstruction insn) { } // @Override public void visit(StringConstantInstruction insn) { } // @Override public void visit(BinaryInstruction insn) { } // @Override public void visit(NegateInstruction insn) { } // @Override public void visit(AssignInstruction insn) { } // @Override public void visit(CastInstruction insn) { } // @Override public void visit(CastNumberInstruction insn) { } // @Override public void visit(CastIntegerInstruction insn) { } // @Override public void visit(BranchingInstruction insn) { } // @Override public void visit(BinaryBranchingInstruction insn) { } // @Override public void visit(JumpInstruction insn) { } // @Override public void visit(SwitchInstruction insn) { } // @Override public void visit(ExitInstruction insn) { } // @Override public void visit(RaiseInstruction insn) { } // @Override public void visit(ConstructArrayInstruction insn) { } // @Override public void visit(ConstructInstruction insn) { } // @Override public void visit(ConstructMultiArrayInstruction insn) { } // @Override public void visit(ArrayLengthInstruction insn) { } // @Override public void visit(CloneArrayInstruction insn) { } // @Override public void visit(UnwrapArrayInstruction insn) { } // @Override public void visit(GetElementInstruction insn) { } // @Override public void visit(PutElementInstruction insn) { } // @Override public void visit(IsInstanceInstruction insn) { } // @Override public void visit(InitClassInstruction insn) { } // @Override public void visit(NullCheckInstruction insn) { } // @Override public void visit(MonitorEnterInstruction insn) { } // @Override public void visit(MonitorExitInstruction insn) { } // } // } // //}