15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)package org.chromium.closure.compiler; 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import com.google.common.collect.Lists; 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import com.google.javascript.jscomp.ChromePassConfig; 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import com.google.javascript.jscomp.CommandLineRunner; 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import com.google.javascript.jscomp.CompilerOptions; 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import org.kohsuke.args4j.CmdLineException; 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import org.kohsuke.args4j.CmdLineParser; 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import org.kohsuke.args4j.Option; 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.io.BufferedReader; 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.io.ByteArrayOutputStream; 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.io.FileInputStream; 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.io.IOException; 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.io.InputStreamReader; 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.io.PrintStream; 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.ArrayList; 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.Collections; 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.List; 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.concurrent.Callable; 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.concurrent.ExecutorService; 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.concurrent.Executors; 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.concurrent.Future; 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.regex.Matcher; 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import java.util.regex.Pattern; 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/** 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Prepares and executes several instances of the closure compiler. 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)public class Runner { 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected final Flags flags = new Flags(); 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private final PrintStream err; 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private boolean isConfigValid; 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public Runner(String[] args, PrintStream err) { 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.err = err; 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) List<String> argList = processArgs(args); 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CmdLineParser parser = new CmdLineParser(flags); 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) isConfigValid = true; 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try { 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parser.parseArgument(argList.toArray(new String[] {})); 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (flags.compilerArgsFile == null) { 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) isConfigValid = false; 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } catch (CmdLineException e) { 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err.println(e.getMessage()); 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) isConfigValid = false; 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!isConfigValid) { 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parser.printUsage(err); 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private List<String> processArgs(String[] args) { 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Pattern argPattern = Pattern.compile("(--[a-zA-Z_]+)=(.*)"); 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Pattern quotesPattern = Pattern.compile("^['\"](.*)['\"]$"); 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) List<String> processedArgs = Lists.newArrayList(); 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (String arg : args) { 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Matcher matcher = argPattern.matcher(arg); 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (matcher.matches()) { 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) processedArgs.add(matcher.group(1)); 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) String value = matcher.group(2); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Matcher quotesMatcher = quotesPattern.matcher(value); 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (quotesMatcher.matches()) { 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) processedArgs.add(quotesMatcher.group(1)); 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) processedArgs.add(value); 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) processedArgs.add(arg); 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return processedArgs; 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private boolean shouldRunCompiler() { 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return isConfigValid; 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected void logError(String message, Exception e) { 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err.println("ERROR: " + message); 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (e != null) { 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.printStackTrace(err); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private void run() { 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) List<CompilerInstanceDescriptor> descriptors = getDescriptors(); 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (descriptors == null) { 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExecutorService executor = Executors.newFixedThreadPool( 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Math.min(descriptors.size(), Runtime.getRuntime().availableProcessors() / 2 + 1)); 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try { 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) runWithExecutor(descriptors, executor); 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } finally { 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) executor.shutdown(); 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private void runWithExecutor( 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) List<CompilerInstanceDescriptor> descriptors, ExecutorService executor) { 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) List<Future<CompilerRunner>> futures = new ArrayList<>(descriptors.size()); 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (CompilerInstanceDescriptor descriptor : descriptors) { 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CompilerRunner task = new CompilerRunner(descriptor, new ByteArrayOutputStream(512)); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) futures.add(executor.submit(task)); 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (Future<CompilerRunner> future : futures) { 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try { 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CompilerRunner task = future.get(); 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task.errStream.flush(); 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) //System.err.println("@@ START_MODULE:" + task.descriptor.moduleName + " @@"); 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) System.err.println(task.errStream.toString("UTF-8")); 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) //System.err.println("@@ END_MODULE @@"); 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (task.result != 0) { 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) System.exit(task.result); 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } catch (Exception e) { 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) System.err.println("ERROR: " + e.getMessage()); 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) System.exit(1); 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) System.exit(0); 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private List<CompilerInstanceDescriptor> getDescriptors() { 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) List<CompilerInstanceDescriptor> result = new ArrayList<>(); 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try (BufferedReader reader = new BufferedReader( 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new InputStreamReader( 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new FileInputStream(flags.compilerArgsFile), "UTF-8"))) { 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int lineIndex = 0; 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while (true) { 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ++lineIndex; 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) String line = reader.readLine(); 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (line == null) { 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (line.length() == 0) { 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) String[] moduleAndArgs = line.split(" +", 2); 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (moduleAndArgs.length != 2) { 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logError(String.format( 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Line %d does not contain module name and compiler arguments", 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lineIndex), null); 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result.add(new CompilerInstanceDescriptor(moduleAndArgs[0], moduleAndArgs[1])); 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } catch (IOException e) { 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) logError("Failed to read compiler arguments file", e); 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return null; 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return result; 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public static void main(String[] args) { 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Runner runner = new Runner(args, System.err); 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (runner.shouldRunCompiler()) { 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) runner.run(); 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) System.exit(-1); 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private static class LocalCommandLineRunner extends CommandLineRunner { 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected LocalCommandLineRunner(String[] args, PrintStream out, PrintStream err) { 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(args, out, err); 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) @Override 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected CompilerOptions createOptions() { 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CompilerOptions options = super.createOptions(); 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) options.setIdeMode(true); 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) options.setExtraAnnotationNames(Collections.singletonList("suppressReceiverCheck")); 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return options; 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) @Override 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected void setRunOptions(CompilerOptions options) 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) throws FlagUsageException, IOException { 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super.setRunOptions(options); 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) options.setCodingConvention(new ChromeCodingConvention()); 1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) getCompiler().setPassConfig(new ChromePassConfig(options)); 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int execute() { 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int result = 0; 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int runs = 1; 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try { 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int i = 0; i < runs && result == 0; i++) { 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = doRun(); 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } catch (Throwable t) { 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) t.printStackTrace(); 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = -2; 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return result; 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private static class CompilerRunner implements Callable<CompilerRunner> { 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private final CompilerInstanceDescriptor descriptor; 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private final ByteArrayOutputStream errStream; 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private int result; 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public CompilerRunner( 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CompilerInstanceDescriptor descriptor, ByteArrayOutputStream errStream) { 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.descriptor = descriptor; 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.errStream = errStream; 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) @Override 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public CompilerRunner call() throws Exception { 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrintStream errPrintStream = new PrintStream(errStream, false, "UTF-8"); 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LocalCommandLineRunner runner = 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new LocalCommandLineRunner(prepareArgs(), System.out, errPrintStream); 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!runner.shouldRunCompiler()) { 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.result = -1; 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.result = runner.execute(); 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return this; 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private String[] prepareArgs() { 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // FIXME: This does not support quoted arguments. 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return descriptor.commandLine.split(" +"); 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private static class Flags { 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) @Option(name = "--compiler-args-file", 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) usage = "Full path to file containing compiler arguments (one line per instance)") 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private String compilerArgsFile = null; 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private static class CompilerInstanceDescriptor { 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private final String moduleName; 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private final String commandLine; 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public CompilerInstanceDescriptor(String moduleName, String commandLine) { 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.moduleName = moduleName; 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.commandLine = commandLine; 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 261