109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)package org.chromium.devtools.compiler;
209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import com.google.common.collect.Lists;
409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import com.google.javascript.jscomp.CommandLineRunner;
509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import com.google.javascript.jscomp.CompilerOptions;
609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import org.kohsuke.args4j.CmdLineException;
809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import org.kohsuke.args4j.CmdLineParser;
909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import org.kohsuke.args4j.Option;
1009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.io.BufferedReader;
1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.io.ByteArrayOutputStream;
1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.io.FileInputStream;
1409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.io.IOException;
1509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.io.InputStreamReader;
1609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.io.PrintStream;
1709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.ArrayList;
1843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)import java.util.Collections;
1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.List;
2009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.concurrent.Callable;
2109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.concurrent.ExecutorService;
2209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.concurrent.Executors;
2309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.concurrent.Future;
2409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.regex.Matcher;
2509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)import java.util.regex.Pattern;
2609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
2709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/**
2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Prepares and executes several instances of the closure compiler.
2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
3009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public class Runner {
3109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    protected final Flags flags = new Flags();
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private final PrintStream err;
3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private boolean isConfigValid;
3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    public Runner(String[] args, PrintStream err) {
3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        this.err = err;
3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        List<String> argList = processArgs(args);
3809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        CmdLineParser parser = new CmdLineParser(flags);
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        isConfigValid = true;
4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        try {
4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            parser.parseArgument(argList.toArray(new String[] {}));
4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (flags.compilerArgsFile == null) {
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                isConfigValid = false;
4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } catch (CmdLineException e) {
4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            err.println(e.getMessage());
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            isConfigValid = false;
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!isConfigValid) {
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            parser.printUsage(err);
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private List<String> processArgs(String[] args) {
5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Pattern argPattern = Pattern.compile("(--[a-zA-Z_]+)=(.*)");
5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Pattern quotesPattern = Pattern.compile("^['\"](.*)['\"]$");
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        List<String> processedArgs = Lists.newArrayList();
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (String arg : args) {
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            Matcher matcher = argPattern.matcher(arg);
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (matcher.matches()) {
6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                processedArgs.add(matcher.group(1));
6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
6509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                String value = matcher.group(2);
6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                Matcher quotesMatcher = quotesPattern.matcher(value);
6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (quotesMatcher.matches()) {
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    processedArgs.add(quotesMatcher.group(1));
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                } else {
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    processedArgs.add(value);
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            } else {
7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                processedArgs.add(arg);
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return processedArgs;
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private boolean shouldRunCompiler() {
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return isConfigValid;
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    protected void logError(String message, Exception e) {
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        err.println("ERROR: " + message);
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (e != null) {
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            e.printStackTrace(err);
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private void run() {
9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        List<CompilerInstanceDescriptor> descriptors = getDescriptors();
9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (descriptors == null) {
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return;
9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ExecutorService executor = Executors.newFixedThreadPool(
9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                Math.min(descriptors.size(), Runtime.getRuntime().availableProcessors() / 2 + 1));
9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        try {
9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            runWithExecutor(descriptors, executor);
10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } finally {
10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            executor.shutdown();
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private void runWithExecutor(
10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            List<CompilerInstanceDescriptor> descriptors, ExecutorService executor) {
10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        List<Future<CompilerRunner>> futures = new ArrayList<>(descriptors.size());
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (CompilerInstanceDescriptor descriptor : descriptors) {
10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            CompilerRunner task = new CompilerRunner(descriptor, new ByteArrayOutputStream(512));
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            futures.add(executor.submit(task));
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (Future<CompilerRunner> future : futures) {
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            try {
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                CompilerRunner task = future.get();
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                int result = task.result;
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (result != 0) {
11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    System.err.println("ERROR: Compiler returned " + result);
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                task.errStream.flush();
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                System.err.println("@@ START_MODULE:" + task.descriptor.moduleName + " @@");
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                System.err.println(task.errStream.toString("UTF-8"));
12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                System.err.println("@@ END_MODULE @@");
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            } catch (Exception e) {
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                System.err.println("ERROR - " + e.getMessage());
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        System.exit(0);
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private List<CompilerInstanceDescriptor> getDescriptors() {
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        List<CompilerInstanceDescriptor> result = new ArrayList<>();
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        try (BufferedReader reader = new BufferedReader(
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                new InputStreamReader(
13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        new FileInputStream(flags.compilerArgsFile), "UTF-8"))) {
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            int lineIndex = 0;
13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            while (true) {
13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                ++lineIndex;
13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                String line = reader.readLine();
14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (line == null) {
14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    break;
14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
14309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (line.length() == 0) {
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    continue;
14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                String[] moduleAndArgs = line.split(" +", 2);
14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (moduleAndArgs.length != 2) {
14809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    logError(String.format(
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            "Line %d does not contain module name and compiler arguments",
15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            lineIndex), null);
15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    continue;
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                result.add(new CompilerInstanceDescriptor(moduleAndArgs[0], moduleAndArgs[1]));
15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } catch (IOException e) {
15609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            logError("Failed to read compiler arguments file", e);
15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return null;
15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
16009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return result;
16109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
16209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
16309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    public static void main(String[] args) {
16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Runner runner = new Runner(args, System.err);
16509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (runner.shouldRunCompiler()) {
16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            runner.run();
16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } else {
16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            System.exit(-1);
16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private static class LocalCommandLineRunner extends CommandLineRunner {
17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        protected LocalCommandLineRunner(String[] args, PrintStream out, PrintStream err) {
17409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            super(args, out, err);
17509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
17609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
17709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        @Override
17809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        protected CompilerOptions createOptions() {
17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            CompilerOptions options = super.createOptions();
18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            options.setIdeMode(true);
18143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            options.setExtraAnnotationNames(Collections.singletonList("suppressReceiverCheck"));
18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return options;
18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        @Override
186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        protected void setRunOptions(CompilerOptions options)
187197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                throws FlagUsageException, IOException {
188197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            super.setRunOptions(options);
189197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            options.setCodingConvention(new DevToolsCodingConvention());
190197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
191197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        int execute() {
19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            int result = 0;
19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            int runs = 1;
19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            try {
19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                for (int i = 0; i < runs && result == 0; i++) {
19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    result = doRun();
19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            } catch (Throwable t) {
20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                t.printStackTrace();
20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                result = -2;
20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return result;
20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private static class CompilerRunner implements Callable<CompilerRunner> {
20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        private final CompilerInstanceDescriptor descriptor;
20909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        private final ByteArrayOutputStream errStream;
21009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        private int result;
21109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
21209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        public CompilerRunner(
21309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                CompilerInstanceDescriptor descriptor, ByteArrayOutputStream errStream) {
21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            this.descriptor = descriptor;
21509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            this.errStream = errStream;
21609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
21809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        @Override
21909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        public CompilerRunner call() throws Exception {
22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            PrintStream errPrintStream = new PrintStream(errStream, false, "UTF-8");
22109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            LocalCommandLineRunner runner =
22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    new LocalCommandLineRunner(prepareArgs(), System.out, errPrintStream);
22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!runner.shouldRunCompiler()) {
22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                this.result = -1;
22509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
22609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            this.result = runner.execute();
22709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return this;
22809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
22909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
23009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        private String[] prepareArgs() {
23109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            // FIXME: This does not support quoted arguments.
23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return descriptor.commandLine.split(" +");
23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
23509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
23609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private static class Flags {
23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        @Option(name = "--compiler-args-file",
23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                usage = "Full path to file containing compiler arguments (one line per instance)")
23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        private String compilerArgsFile = null;
24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    private static class CompilerInstanceDescriptor {
24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        private final String moduleName;
24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        private final String commandLine;
24509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        public CompilerInstanceDescriptor(String moduleName, String commandLine) {
24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            this.moduleName = moduleName;
24809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            this.commandLine = commandLine;
24909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
25009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
25109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
252