private void splitFiles(String[] input) {
    Compiler compiler = new Compiler();
    List<SourceFile> files = Lists.newArrayList();

    for (int i = 0; i < input.length; i++) {
      files.add(SourceFile.fromCode("file" + i, input[i]));
    }

    compiler.init(ImmutableList.<SourceFile>of(), files, new CompilerOptions());
    compiler.parse();
    Node original = compiler.getRoot();
    Node root = original.cloneTree();

    AstParallelizer parallelizer = AstParallelizer.createNewFileLevelAstParallelizer(root);
    List<Node> forest = parallelizer.split();
    assertEquals(input.length, forest.size());
    int i = 0;
    for (Node n : forest) {
      Node tree = compiler.parseTestCode(input[i++]);
      assertEquals(compiler.toSource(tree), compiler.toSource(n));
    }

    parallelizer.join();
    assertTrue(original.isEquivalentTo(root));
  }
  protected void testExternChanges(String extern, String input, String expectedExtern) {
    Compiler compiler = createCompiler();
    CompilerOptions options = getOptions();
    compiler.init(
        ImmutableList.of(SourceFile.fromCode("extern", extern)),
        ImmutableList.of(SourceFile.fromCode("input", input)),
        options);
    compiler.parseInputs();
    assertFalse(compiler.hasErrors());

    Node externsAndJs = compiler.getRoot();
    Node root = externsAndJs.getLastChild();

    Node externs = externsAndJs.getFirstChild();

    Node expected = compiler.parseTestCode(expectedExtern);
    assertFalse(compiler.hasErrors());

    (getProcessor(compiler)).process(externs, root);

    String externsCode = compiler.toSource(externs);
    String expectedCode = compiler.toSource(expected);

    assertEquals(expectedCode, externsCode);
  }
  /**
   * Splits at function level with {@link AstParallelizer#split()}, verify the output matches what
   * is expected and then verify {@link AstParallelizer#join()} can reverse the whole process.
   */
  private void splitFunctions(String input, String... output) {
    Compiler compiler = new Compiler();
    Node original = compiler.parseTestCode(input);
    Node root = original.cloneTree();
    AstParallelizer parallelizer =
        AstParallelizer.createNewFunctionLevelAstParallelizer(root, true);
    List<Node> forest = parallelizer.split();
    assertEquals(output.length, forest.size());
    int i = 0;
    for (Node n : forest) {
      Node tree = compiler.parseTestCode(output[i++]);
      assertEquals(compiler.toSource(tree), compiler.toSource(n));
    }

    parallelizer.join();
    assertTrue(original.isEquivalentTo(root));
  }
 private static LiveVariablesAnalysis computeLiveness(String src) {
   Compiler compiler = new Compiler();
   CompilerOptions options = new CompilerOptions();
   options.setCodingConvention(new GoogleCodingConvention());
   compiler.initOptions(options);
   src = "function _FUNCTION(param1, param2){" + src + "}";
   Node n = compiler.parseTestCode(src).removeFirstChild();
   Node script = new Node(Token.SCRIPT, n);
   assertEquals(0, compiler.getErrorCount());
   Scope scope = new SyntacticScopeCreator(compiler).createScope(n, new Scope(script, compiler));
   ControlFlowAnalysis cfa = new ControlFlowAnalysis(compiler, false, true);
   cfa.process(null, n);
   ControlFlowGraph<Node> cfg = cfa.getCfg();
   LiveVariablesAnalysis analysis = new LiveVariablesAnalysis(cfg, scope, compiler);
   analysis.analyze();
   return analysis;
 }
  protected void testExternChanges(String extern, String input, String expectedExtern) {
    Compiler compiler = createCompiler();
    CompilerOptions options = getOptions();
    compiler.init(
        ImmutableList.of(SourceFile.fromCode("extern", extern)),
        ImmutableList.of(SourceFile.fromCode("input", input)),
        options);
    compiler.parseInputs();
    assertFalse(compiler.hasErrors());

    Node externsAndJs = compiler.getRoot();
    Node root = externsAndJs.getLastChild();

    Node externs = externsAndJs.getFirstChild();

    Node expected = compiler.parseTestCode(expectedExtern);
    assertFalse(compiler.hasErrors());

    (getProcessor(compiler)).process(externs, root);

    if (compareAsTree) {
      // Expected output parsed without implied block.
      Preconditions.checkState(externs.isBlock());
      Preconditions.checkState(compareJsDoc);
      Preconditions.checkState(
          externs.hasOneChild(), "Compare as tree only works when output has a single script.");
      externs = externs.getFirstChild();
      String explanation = expected.checkTreeEqualsIncludingJsDoc(externs);
      assertNull(
          "\nExpected: "
              + compiler.toSource(expected)
              + "\nResult:   "
              + compiler.toSource(externs)
              + "\n"
              + explanation,
          explanation);
    } else {
      String externsCode = compiler.toSource(externs);
      String expectedCode = compiler.toSource(expected);
      assertEquals(expectedCode, externsCode);
    }
  }
 private static Node parse(Compiler compiler, String js) {
   Node n = compiler.parseTestCode(js);
   assertEquals(0, compiler.getErrorCount());
   return n;
 }