/*
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.UnstableNestedAnonymousGenerator.OutputVersion;
import com.google.gwt.dev.cfg.EntryMethodHolderGenerator;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.ModuleDefLoader;
import com.google.gwt.dev.cfg.ResourceLoader;
import com.google.gwt.dev.cfg.ResourceLoaders;
import com.google.gwt.dev.javac.UnitCacheSingleton;
import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.javac.testing.impl.MockResource;
import com.google.gwt.dev.jjs.JsOutputOption;
import com.google.gwt.dev.jjs.impl.JjsUtils;
import com.google.gwt.dev.util.UnitTestTreeLogger;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.SourceLevel;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.thirdparty.guava.common.base.Charsets;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.io.Files;
import com.google.gwt.util.tools.Utility;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * Test for {@link Compiler}.
 */
public class CompilerTest extends ArgProcessorTestBase {

  public static final String HELLO_MODULE = "com.google.gwt.sample.hello.Hello";
  public static final String HELLO_MODULE_STACKMODE_STRIP =
      "com.google.gwt.sample.hello.Hello_stackMode_strip";

  private MockJavaResource packagePrivateParentResource =
      JavaResourceBase.createMockJavaResource("com.foo.PackagePrivateParent",
          "package com.foo;",
          "public abstract class PackagePrivateParent {",
          "  abstract void someFunction();",
          "}");

  private MockJavaResource packagePrivateChildResource =
      JavaResourceBase.createMockJavaResource("com.foo.PackagePrivateChild",
          "package com.foo;",
          "public class PackagePrivateChild extends PackagePrivateParent {",
          "  @Override",
          "  void someFunction() {}",
          "}");

  private MockJavaResource referencesParentResource =
      JavaResourceBase.createMockJavaResource("com.foo.ReferencesParent",
          "package com.foo;",
          "public class ReferencesParent {",
          "  void run() {",
          "    PackagePrivateParent packagePrivateParent = null;",
          "    packagePrivateParent.someFunction();",
          "  }",
          "}");

  private MockJavaResource packagePrivateDispatchEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    ReferencesParent referencesParent = new ReferencesParent();",
          "    PackagePrivateChild packagePrivateChild = new PackagePrivateChild();",
          "  }",
          "}");

  private MockJavaResource jsoOne =
      JavaResourceBase.createMockJavaResource("com.foo.JsoOne",
          "package com.foo;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public class JsoOne extends JavaScriptObject {",
          "  protected JsoOne() {",
          "  }",
          "}");

  private MockJavaResource jsoTwo_before =
      JavaResourceBase.createMockJavaResource("com.foo.JsoTwo",
          "package com.foo;",
          "public class JsoTwo {",
          "  protected JsoTwo() {",
          "  }",
          "}");

  private MockJavaResource jsoTwo_after =
      JavaResourceBase.createMockJavaResource("com.foo.JsoTwo",
          "package com.foo;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public class JsoTwo extends JavaScriptObject {",
          "  protected JsoTwo() {",
          "  }",
          "}");

  private MockJavaResource someClassReferringToJsoOneArrays =
      JavaResourceBase.createMockJavaResource("com.foo.SomeClassReferringToJsoOneArrays",
          "package com.foo;",
          "public class SomeClassReferringToJsoOneArrays {",
          "  public static Object createJsoOneArray() { return new JsoOne[30]; }",
          "}");

  private MockJavaResource someClassReferringToJsoTwoArrays =
      JavaResourceBase.createMockJavaResource("com.foo.SomeClassReferringToJsoTwoArrays",
          "package com.foo;",
          "public class SomeClassReferringToJsoTwoArrays {",
          "  public static Object createJsoTwoArray() { return new JsoTwo[30]; }",
          "}");

  private MockJavaResource jsoArrayTestEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    Object o1 = SomeClassReferringToJsoOneArrays.createJsoOneArray();",
          "    Object o2 = SomeClassReferringToJsoTwoArrays.createJsoTwoArray();",
          "  }",
          "}");

  private MockJavaResource simpleDialogResourceWithExport =
      JavaResourceBase.createMockJavaResource("com.foo.SimpleDialog",
          "package com.foo;",
          "import jsinterop.annotations.JsProperty;",
          "public class SimpleDialog {",
          "  @JsProperty(namespace = \"ns\")",
          "  public static int show;",
          "}");

  private MockJavaResource complexDialogResourceWithExport =
      JavaResourceBase.createMockJavaResource("com.foo.ComplexDialog",
          "package com.foo;",
          "import jsinterop.annotations.JsProperty;",
          "public class ComplexDialog {",
          "  @JsProperty(namespace = \"ns\")",
          "  public static int show;",
          "}");

  private MockJavaResource complexDialogResourceSansExport =
      JavaResourceBase.createMockJavaResource("com.foo.ComplexDialog",
          "package com.foo;",
          "public class ComplexDialog {",
          "  public static void show() {}",
          "}");

  private MockJavaResource simpleModelEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    SimpleModel simpleModel1 = new SimpleModel();",
          "    SimpleModel simpleModel2 = new SimpleModel();",
          "    simpleModel2.copyFrom(simpleModel1);",
          "  }",
          "}");

  private MockJavaResource simpleModelResource =
      JavaResourceBase.createMockJavaResource("com.foo.SimpleModel",
          "package com.foo;",
          "public class SimpleModel {",
          "  private int value = Constants.CONSTANT;",
          "  public void copyFrom(Object object) {}",
          "}");

  private MockJavaResource modifiedFunctionSignatureSimpleModelResource =
      JavaResourceBase.createMockJavaResource("com.foo.SimpleModel",
          "package com.foo;",
          "public class SimpleModel {",
          "  private int value = Constants.CONSTANT;",
          "  public void copyFrom(SimpleModel that) {}",
          "}");

  private MockResource simpleModuleResource =
      JavaResourceBase.createMockResource("com/foo/SimpleModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TestEntryPoint'/>",
          "</module>");

  private MockJavaResource constantsModelResource =
      JavaResourceBase.createMockJavaResource("com.foo.Constants",
          "package com.foo;",
          "public class Constants {",
          "  public static final int CONSTANT = 0;",
          "}");

  private MockJavaResource modifiedConstantsModelResource =
      JavaResourceBase.createMockJavaResource("com.foo.Constants",
          "package com.foo;",
          "public class Constants {",
          "  public static final int CONSTANT = 2;",
          "}");

  private MockResource unstableGeneratorModuleResource = JavaResourceBase.createMockResource(
      "com/foo/SimpleModule.gwt.xml",
      "<module>",
      "<source path=''/>",
      "<entry-point class='com.foo.TestEntryPoint'/>",
      "<generate-with class='com.google.gwt.dev.UnstableNestedAnonymousGenerator'>",
      "  <when-type-is class='java.lang.Object' />",
      "</generate-with>",
      "</module>");

  private MockResource resourceReadingGeneratorModuleResource =
      JavaResourceBase.createMockResource("com/foo/SimpleModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TestEntryPoint'/>",
          "<generate-with class='com.google.gwt.dev.FooResourceGenerator'>",
          "  <when-type-is class='java.lang.Object' />",
          "</generate-with>",
          "</module>");

  private MockResource barReferencesFooGeneratorModuleResource =
      JavaResourceBase.createMockResource("com/foo/SimpleModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TestEntryPoint'/>",
          "<generate-with class='com.google.gwt.dev.BarReferencesFooGenerator'>",
          "  <when-type-is class='java.lang.Object' />",
          "</generate-with>",
          "</module>");

  private MockResource cascadingGeneratorModuleResource =
      JavaResourceBase.createMockResource("com/foo/SimpleModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TestEntryPoint'/>",
          "<generate-with class='com.google.gwt.dev.CauseStringRebindGenerator'>",
          "  <when-type-is class='java.lang.Object' />",
          "</generate-with>",
          "<generate-with class='com.google.gwt.dev.CauseShortRebindGenerator'>",
          "  <when-type-is class='java.lang.String' />",
          "</generate-with>",
          "<generate-with class='com.google.gwt.dev.FooResourceGenerator'>",
          "  <when-type-is class='java.lang.Short' />",
          "</generate-with>",
          "</module>");

  private MockResource multipleClassGeneratorModuleResource =
      JavaResourceBase.createMockResource("com/foo/SimpleModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TestEntryPoint'/>",
          "<generate-with class='com.google.gwt.dev.MultipleClassGenerator'>",
          "  <when-type-is class='java.lang.Object' />",
          "</generate-with>",
          "</module>");

  private MockResource classNameToGenerateResource =
      JavaResourceBase.createMockResource("com/foo/generatedClassName.txt",
          "FooReplacementOne");

  private MockResource modifiedClassNameToGenerateResource =
      JavaResourceBase.createMockResource("com/foo/generatedClassName.txt",
          "FooReplacementTwo");

  private MockJavaResource generatorEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.google.gwt.core.client.GWT;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    GWT.create(Object.class);",
          "  }",
          "}");

  private MockJavaResource referencesBarAndGeneratorEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.google.gwt.core.client.GWT;",
          "public class TestEntryPoint implements EntryPoint {",
          "  Bar bar = new Bar();",
          "  @Override",
          "  public void onModuleLoad() {",
          "    GWT.create(Object.class);",
          "  }",
          "}");

  private MockJavaResource superClassOrderEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    SuperClass superClass = new SuperClass();",
          "    ASubClass aSubClass = new ASubClass();",
          "  }",
          "}");

  private MockJavaResource referencedBySuperClassResource =
      JavaResourceBase.createMockJavaResource("com.foo.ReferencedBySuperClass",
          "package com.foo;",
          "public class ReferencedBySuperClass {}");

  private MockJavaResource superClassResource =
      JavaResourceBase.createMockJavaResource("com.foo.SuperClass",
          "package com.foo;",
          "public class SuperClass {",
          "  ReferencedBySuperClass referencedBySuperClass = new ReferencedBySuperClass();",
          "}");

  private MockJavaResource aSubClassResource =
      JavaResourceBase.createMockJavaResource("com.foo.ASubClass",
          "package com.foo;",
          "public class ASubClass extends SuperClass {}");

  private MockJavaResource modifiedSuperEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    Object d = new ModelD();",
          "    if (d instanceof ModelA) {",
          "      // ModelD extends ModelA;",
          "    } else {",
          "      // ModelD does not ModelA;",
          "    }",
          "  }",
          "}");

  private MockJavaResource modelAResource =
      JavaResourceBase.createMockJavaResource("com.foo.ModelA",
          "package com.foo;",
          "public class ModelA {}");

  private MockJavaResource modelBResource =
      JavaResourceBase.createMockJavaResource("com.foo.ModelB",
          "package com.foo;",
          "public class ModelB extends ModelA {}");

  private MockJavaResource modelCResource =
      JavaResourceBase.createMockJavaResource("com.foo.ModelC",
          "package com.foo;",
          "public class ModelC {}");

  private MockJavaResource modifiedSuperModelCResource =
      JavaResourceBase.createMockJavaResource("com.foo.ModelC",
          "package com.foo;",
          "public class ModelC extends ModelA {}");

  private MockJavaResource modelDResource =
      JavaResourceBase.createMockJavaResource("com.foo.ModelD",
          "package com.foo;",
          "public class ModelD extends ModelC {}");

  private MockJavaResource modifiedJsoIntfDispatchEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    Caller.call(this);",
          "  }",
          "",
          "  public void runTest(FooInterface fooInterface) {",
          "    fooInterface.run();",
          "  }",
          "}");

  private MockJavaResource callerResource =
      JavaResourceBase.createMockJavaResource("com.foo.Caller",
          "package com.foo;",
          "public class Caller {",
          "  public static void call(TestEntryPoint testEntryPoint) {",
          "    testEntryPoint.runTest(Foo.createFoo());",
          "  }",
          "}");

  private MockJavaResource sameContentDifferentTimeFooResource = JavaResourceBase
      .createMockJavaResource("com.foo.Foo",
          "package com.foo;",
          "public class Foo {}");

  private MockJavaResource fooInterfaceResource =
      JavaResourceBase.createMockJavaResource("com.foo.FooInterface",
          "package com.foo;",
          "public interface FooInterface {",
          "  void run();",
          "}");

  private MockJavaResource jsoFooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Foo",
          "package com.foo;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public final class Foo extends JavaScriptObject implements FooInterface {",
          "  public static native Foo createFoo() /*-{",
          "    return {};",
          "  }-*/;",
          "",
          "  protected Foo() {}",
          "",
          "  @Override",
          "  public void run() {}",
          "}");

  private MockJavaResource nonJsoFooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Foo",
          "package com.foo;",
          "public class Foo implements FooInterface {",
          "  public static Foo createFoo() {",
          "    return new Foo();",
          "  }",
          "",
          "  @Override",
          "  public void run() {}",
          "}");

  private MockJavaResource fooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Foo",
          "package com.foo;",
          "public class Foo {}");

  private MockJavaResource barReferencesFooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Bar",
          "package com.foo;",
          "public class Bar {",
          "  Foo foo = new Foo();",
          "}");

  private MockJavaResource jsTypeBarResource =
      JavaResourceBase.createMockJavaResource(
          "com.foo.Bar",
          "package com.foo;",
          "import jsinterop.annotations.JsType;",
          "@JsType public class Bar {",
          "  void doInstanceBar() {}",
          "  public static void doStaticBaz() {}",
          "}");

  private MockJavaResource nonCompilableFooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Foo",
          "package com.foo;",
          "public class Foo {",
          "  public void run() {",
          "    // Not available in GWT.",
          "    String.format(\"asdf\");",
          "  }",
          "}");

  private MockJavaResource emptyEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {}",
          "}");

  MockJavaResource entryPointResourceForFoo =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.foo.Foo;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() { new Foo(); }",
          "}");

  private MockJavaResource gwtCreateEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.google.gwt.core.client.GWT;",
          "import jsinterop.annotations.JsType;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @JsType public static class MyJsType {}",
          "  @JsType public interface MyJsTypeInterface {}",
          "  public static class MyTypeImplementsJsType implements MyJsTypeInterface {}",
          "  @Override",
          "  public void onModuleLoad() {",
          "    GWT.create(MyJsType.class);",
          "    GWT.create(MyTypeImplementsJsType.class);",
          "  }",
          "}");

  private MockJavaResource dialogEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    SimpleDialog simpleDialog = new SimpleDialog();",
          "    ComplexDialog complexDialog = new ComplexDialog();",
          "  }",
          "}");

  private MockJavaResource brokenGwtCreateEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.google.gwt.core.client.GWT;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public class TestEntryPoint implements EntryPoint {",
          "  public static class MyJso extends JavaScriptObject {",
          "    protected MyJso() {}",
          "  }",
          "  @Override",
          "  public void onModuleLoad() {",
          "    GWT.create(MyJso.class);",
          "  }",
          "}");

  private MockJavaResource topResource =
      JavaResourceBase.createMockJavaResource("com.foo.top",
          "package com.foo;",
          "abstract class Top {",
          "  Object run() {",
          "    return \"\";",
          "  }",
          "}");

  private MockJavaResource middleResource =
      JavaResourceBase.createMockJavaResource("com.foo.Middle",
          "package com.foo;",
          "public abstract class Middle extends Top {",
          "  abstract String run();",
          "}");

  private MockJavaResource bottomResource =
      JavaResourceBase.createMockJavaResource("com.foo.Bottom",
          "package com.foo;",
          "public class Bottom extends Middle {",
          "  // ",
          "  private final class Value {}",
          "  String run() {",
          "    Value value = new Value();",
          "    return \"\";",
          "  }",
          "}");

  private MockJavaResource overriddenMethodChainEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    Bottom bottom = new Bottom();",
          "    ((Top)bottom).run();",
          "  }",
          "}");

  private MockJavaResource bazResource =
      JavaResourceBase.createMockJavaResource("com.foo.Baz",
          "package com.foo;",
          "public class Baz {}");

  private MockJavaResource regularFooImplemetorResource =
      JavaResourceBase.createMockJavaResource("com.foo.FooImplementor",
          "package com.foo;",
          "public class FooImplementor implements FooInterface {",
          "  @Override",
          "  public void run() {}",
          "}");

  private MockJavaResource simpleFactory =
      JavaResourceBase.createMockJavaResource("com.foo.SimpleFactory",
          "package com.foo;",
          "public class SimpleFactory {",
          "  public static SimpleIntf getJso() {",
          "    return getJsoImpl();",
          "  };",
          "  public static native SimpleJso getJsoImpl() /*-{",
          "    return null;",
          "  }-*/;",
          "}");

  private MockJavaResource simpleJso =
      JavaResourceBase.createMockJavaResource("com.foo.SimpleJso",
          "package com.foo;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public class SimpleJso extends JavaScriptObject implements SimpleIntf {",
          "  protected SimpleJso() {",
          "  }",
          "  public final void method() {",
          "  }",
          "}");

  private MockJavaResource simpleIntf =
      JavaResourceBase.createMockJavaResource("com.foo.SimpleIntf",
          "package com.foo;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public interface SimpleIntf {",
          "  public void method();",
          "}");

  private MockJavaResource jsoTestEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    SimpleFactory.getJso().method();",
          "  }",
          "}");

  private MockResource jsoTestModuleResource =
      JavaResourceBase.createMockResource("com/foo/SimpleModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TestEntryPoint'/>",
          "</module>");

  private MockResource myWidgetUiXml =
      JavaResourceBase.createMockResource("com/foo/MyWidget.ui.xml",
          "<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'",
          "    xmlns:g='urn:import:com.google.gwt.user.client.ui'>",
          "<g:HTMLPanel>",
          "  Hello, <g:ListBox ui:field='myListBox' visibleItemCount='1'/>.",
          "</g:HTMLPanel>",
          "</ui:UiBinder>");

  private MockResource myWidgetWithWhiteStyleUiXml =
      JavaResourceBase.createMockResource("com/foo/MyWidget.ui.xml",
          "<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'",
          "    xmlns:g='urn:import:com.google.gwt.user.client.ui'>",
          "  <ui:style>",
          "  .title {",
          "    background-color: white;",
          "  }",
          "  </ui:style>",
          "  <g:HTMLPanel><g:ListBox ui:field='myListBox' visibleItemCount='1'/></g:HTMLPanel>",
          "</ui:UiBinder>");

  private MockResource myWidgetWithGreyStyleUiXml =
      JavaResourceBase.createMockResource("com/foo/MyWidget.ui.xml",
          "<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'",
          "    xmlns:g='urn:import:com.google.gwt.user.client.ui'>",
          "  <ui:style>",
          "  .title {",
          "    background-color: grey;",
          "  }",
          "  </ui:style>",
          "  <g:HTMLPanel><g:ListBox ui:field='myListBox' visibleItemCount='1'/></g:HTMLPanel>",
          "</ui:UiBinder>");

  private MockJavaResource myWidget =
      JavaResourceBase.createMockJavaResource("com.foo.MyWidget",
          "package com.foo;",
          "import com.google.gwt.core.client.GWT;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "import com.google.gwt.uibinder.client.UiBinder;",
          "import com.google.gwt.uibinder.client.UiField;",
          "import com.google.gwt.user.client.ui.Composite;",
          "import com.google.gwt.user.client.ui.ListBox;",
          "import com.google.gwt.user.client.ui.Widget;",
          "public class MyWidget extends Composite {",
          "  interface Binder extends UiBinder<Widget, MyWidget> {",
          "  }",
          "  private static final Binder binder = GWT.create(Binder.class);",
          "  @UiField ListBox myListBox;",
          "  public MyWidget() {",
          "    init();",
          "  }",
          "  protected void init() {",
          "    initWidget(binder.createAndBindUi(this));",
          "    myListBox.addItem(\"One\");",
          "  }",
          "}");

  private MockJavaResource uiBinderTestEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.google.gwt.dom.client.Node;",
          "import com.google.gwt.user.client.ui.RootPanel;",
          "public class TestEntryPoint implements EntryPoint {",
          "  private Node node;",
          "  private MyWidget widget;",
          "  @Override",
          "  public void onModuleLoad() {",
          "    node = null; widget = new MyWidget();",
          "    RootPanel.get().add(widget);",
          "  }",
          "}");

  private MockResource uiBinderTestModuleResource =
      JavaResourceBase.createMockResource("com/foo/UiBinderTestModule.gwt.xml",
          "<module>",
          "  <inherits name='com.google.gwt.core.Core'/>",
          "  <inherits name='com.google.gwt.user.User' />",
          "  <source path=''/>",
          "  <set-property name='user.agent' value='safari'/>",
          "  <entry-point class='com.foo.TestEntryPoint'/>",
          "</module>");

  private MockResource devirtualizeStringModuleResource =
      JavaResourceBase.createMockResource("com/foo/DevirtualizeStringModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.DevirtualizeStringEntryPoint'/>",
          "</module>");

  private MockJavaResource devirtualizeStringEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.DevirtualizeStringEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class DevirtualizeStringEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    CharSequence seq = \"A\";",
          "    seq.subSequence(0,1);",
          "  }",
          "}");

  private MockResource transitivelyFoldableConstantModuleResource =
      JavaResourceBase.createMockResource(
          "com/foo/TransitivelyFoldableConstantModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TransitivelyFoldableConstantEntryPoint'/>",
          "</module>");

  private MockJavaResource transitivelyFoldableConstantEntryPointResource =
      JavaResourceBase.createMockJavaResource(
          "com.foo.TransitivelyFoldableConstantEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TransitivelyFoldableConstantEntryPoint",
          "    implements EntryPoint {",
          "  static final int CONST = 1 + ClassOne.CONST;",
          "  @Override",
          "  public void onModuleLoad() {",
          "    int c = CONST;",
          "  }",
          "}");

  private MockJavaResource classOneResource =
      JavaResourceBase.createMockJavaResource(
          "com.foo.ClassOne",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class ClassOne {",
          "  static final int CONST = 1 + ClassTwo.CONST;",
          "}");

  private MockJavaResource classTwoResource =
      JavaResourceBase.createMockJavaResource(
          "com.foo.ClassTwo",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class ClassTwo {",
          "  static final int CONST = 1 + 3;",
          "}");

  private MockResource superFromStaleInnerModuleResource =
      JavaResourceBase.createMockResource(
          "com/foo/SuperFromStaleInnerModule.gwt.xml",
          "<module>",
          "  <source path=''/>",
          "  <entry-point class='com.foo.SuperFromStaleInnerEntryPoint'/>",
          "</module>");

  private MockJavaResource superFromStaleInnerEntryPointResource =
      JavaResourceBase.createMockJavaResource(
          "com.foo.SuperFromStaleInnerEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class SuperFromStaleInnerEntryPoint",
          "    implements EntryPoint {",
          "  static class A { int f() { return 1; } }",
          "  static class B extends A {",
          "    int f() { return 2; }",
          "    void g() {",
          "      new InterfaceOne() {",
          "        public int m() { return 2 + B.super.f(); }",
          "      }.m();",
          "    }",
          "  }",
          "  @Override",
          "  public void onModuleLoad() {",
          "    new B().g();",
          "  }",
          "}");

  private MockJavaResource interfaceOneResource =
      JavaResourceBase.createMockJavaResource(
          "com.foo.InterfaceOne",
          "package com.foo;",
          "interface InterfaceOne {",
          "  int m();",
          "}");

  private MockResource helloModuleResource =
      JavaResourceBase.createMockResource(
          "com/foo/Hello.gwt.xml",
          "<module>",
          "  <inherits name='com.google.gwt.user.User'/>",
          "  <source path=''/>",
          "  <set-property name='user.agent' value='safari'/>",
          "  <entry-point class='com.foo.HelloEntryPoint'/>",
          "</module>");

  private MockJavaResource helloEntryPointResource =
      JavaResourceBase.createMockJavaResource(
          "com.foo.HelloEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.google.gwt.event.dom.client.ClickEvent;",
          "import com.google.gwt.event.dom.client.ClickHandler;",
          "import com.google.gwt.user.client.Window;",
          "import com.google.gwt.user.client.ui.Button;",
          "import com.google.gwt.user.client.ui.RootPanel;",
          "public class HelloEntryPoint implements EntryPoint {",
          "  public void onModuleLoad() {",
          "    Button b = new Button(\"Click me\", new ClickHandler() {",
          "        public void onClick(ClickEvent event) {",
          "          Window.alert(\"Hello, AJAX\");",
          "        }",
          "      });",
          "    RootPanel.get().add(b);" ,
          "  }",
          "}");

  private Set<String> emptySet = stringSet();

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    FooResourceGenerator.runCount = 0;
    BarReferencesFooGenerator.runCount = 0;
    CauseStringRebindGenerator.runCount = 0;
    CauseShortRebindGenerator.runCount = 0;
  }

  public void testAllValidArgs() {
    CompilerOptionsImpl options = new CompilerOptionsImpl();
    Compiler.ArgProcessor argProcessor = new Compiler.ArgProcessor(options);

    assertProcessSuccess(argProcessor, new String[] {"-logLevel", "DEBUG", "-style",
        "PRETTY", "-ea", "-gen", "myGen",
        "-war", "myWar", "-workDir", "myWork", "-extra", "myExtra", "-incremental",
        "-localWorkers", "2", "-sourceLevel", "1.8", "c.g.g.h.H", "my.Module"});

    assertEquals(new File("myGen").getAbsoluteFile(),
        options.getGenDir().getAbsoluteFile());
    assertEquals(new File("myWar"), options.getWarDir());
    assertEquals(new File("myWork"), options.getWorkDir());
    assertEquals(new File("myExtra"), options.getExtraDir());

    assertEquals(2, options.getLocalWorkers());

    assertEquals(TreeLogger.DEBUG, options.getLogLevel());
    assertEquals(JsOutputOption.PRETTY, options.getOutput());
    assertTrue(options.isEnableAssertions());
    assertTrue(options.shouldClusterSimilarFunctions());
    assertTrue(options.shouldInlineLiteralParameters());
    assertFalse(options.shouldOptimizeDataflow());
    assertTrue(options.shouldOrdinalizeEnums());
    assertTrue(options.shouldRemoveDuplicateFunctions());
    assertTrue(options.isIncrementalCompileEnabled());

    assertEquals(SourceLevel.JAVA8, options.getSourceLevel());

    assertEquals(2, options.getModuleNames().size());
    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
    assertEquals("my.Module", options.getModuleNames().get(1));
  }

  public void testDefaultArgs() {
    CompilerOptionsImpl options = new CompilerOptionsImpl();
    Compiler.ArgProcessor argProcessor = new Compiler.ArgProcessor(options);

    assertProcessSuccess(argProcessor, new String[]{"c.g.g.h.H"});

    assertEquals(null, options.getGenDir());
    assertEquals(new File("war").getAbsoluteFile(),
        options.getWarDir().getAbsoluteFile());
    assertEquals(null, options.getWorkDir());
    assertEquals(null, options.getExtraDir());

    assertEquals(TreeLogger.INFO, options.getLogLevel());
    assertEquals(JsOutputOption.OBFUSCATED, options.getOutput());
    assertFalse(options.isEnableAssertions());
    assertTrue(options.shouldClusterSimilarFunctions());
    assertTrue(options.shouldInlineLiteralParameters());
    assertFalse(options.shouldOptimizeDataflow());
    assertTrue(options.shouldOrdinalizeEnums());
    assertTrue(options.shouldRemoveDuplicateFunctions());
    assertFalse(options.isIncrementalCompileEnabled());

    assertEquals(1, options.getLocalWorkers());

    assertEquals(1, options.getModuleNames().size());
    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
  }

  public void testForbiddenArgs() {
    CompilerOptionsImpl options = new CompilerOptionsImpl();
    Compiler.ArgProcessor argProcessor = new Compiler.ArgProcessor(options);

    assertProcessFailure(argProcessor, "Unknown argument", new String[]{"-out", "www"});
    assertProcessFailure(argProcessor, "Source level must be one of",
        new String[]{"-sourceLevel", "ssss"});
    assertProcessFailure(argProcessor, "Source level must be one of",
        new String[]{"-sourceLevel", "1.5"});
  }

  /**
   * Tests ordering for emum {@link SourceLevel}.
   */
  public void testSourceLevelOrdering() {
    SourceLevel[] sourceLevels = SourceLevel.values();
    SourceLevel previousSourceLevel = sourceLevels[0];
    for (int i = 1; i < sourceLevels.length; i++) {
      assertTrue(Utility.versionCompare(previousSourceLevel.getStringValue(),
          sourceLevels[i].getStringValue()) < 0);
      previousSourceLevel = sourceLevels[i];
    }
  }

  public void testSourceLevelSelection() {
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.4"));
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.5"));
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.6"));
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.6_26"));

    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.7"));
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.8"));
    assertEquals(SourceLevel.JAVA9, SourceLevel.getBestMatchingVersion("1.9"));
    assertEquals(SourceLevel.JAVA10, SourceLevel.getBestMatchingVersion("1.10"));
    assertEquals(SourceLevel.JAVA11, SourceLevel.getBestMatchingVersion("1.11"));

    // not proper version strings => default to JAVA8.
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.6u3"));
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.6b3"));
    assertEquals(SourceLevel.JAVA8, SourceLevel.getBestMatchingVersion("1.7b3"));
  }

  public void testSourceLevelHighestVersion() {
    assertEquals(SourceLevel.values()[SourceLevel.values().length - 1], SourceLevel.getHighest());
  }

  /**
   * Verify that a compile with a @JsType at least compiles successfully.
   */
  public void testGwtCreateJsTypeRebindResult() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compileToJs(compilerOptions, Files.createTempDir(), "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, gwtCreateEntryPointResource),
        new MinimalRebuildCache(), emptySet, JsOutputOption.OBFUSCATED);
  }

   /**
   * Test that some lightly referenced interface through a @JsFunction is included in the output.
   */
  public void testReferenceThroughJsFunction() throws Exception {
    MockJavaResource someJsFunction =
        JavaResourceBase.createMockJavaResource(
            "com.foo.SomeJsFunction",
            "package com.foo;",
            "import jsinterop.annotations.JsFunction;",
            "@JsFunction",
            "public interface SomeJsFunction {",
            "  void m();",
            "}");

    MockJavaResource jsFunctionInterfaceImplementation =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Impl",
            "package com.foo;",
            "public final class Impl implements SomeJsFunction {",
            "  public void m() { SomeInterface.class.getName(); } ",
            "}");

    MockJavaResource someInterface =
        JavaResourceBase.createMockJavaResource(
            "com.foo.SomeInterface",
            "package com.foo;",
            "public interface SomeInterface {",
            "}");

    MockJavaResource testEntryPoint =
        JavaResourceBase.createMockJavaResource(
            "com.foo.TestEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class TestEntryPoint implements EntryPoint {",
            "  private static native void f(SomeJsFunction f) /*-{}-*/;",
            "  public void onModuleLoad() {",
                // Create Impl and pass it to JS but do not explicitly call m
            "    f(new Impl());",
            "  }",
            "}");

    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/TestEntryPoint.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.TestEntryPoint'/>",
            "</module>");

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    String js = compileToJs(compilerOptions, Files.createTempDir(), testEntryPoint.getTypeName(),
        Lists.newArrayList(moduleResource, testEntryPoint, someJsFunction,
            jsFunctionInterfaceImplementation, someInterface),
        new MinimalRebuildCache(), emptySet, JsOutputOption.DETAILED);
    // Make sure the referenced class literals ends up being included in the resulting JS.
    String classliteralHolderVarName =
        JjsUtils.mangleMemberName("com.google.gwt.lang.ClassLiteralHolder",
            JjsUtils.classLiteralFieldNameFromJavahTypeSignatureName(
                JjsUtils.javahSignatureFromName(someInterface.getTypeName())));
    assertTrue(js.contains("var " + classliteralHolderVarName + " = "));
  }

  /**
   * Tests that changing Js namespace name on an exported method comes out accurately.
   *
   * <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
   * exports do not forget non-edited items in a recompile.
   */
  public void testChangeJsNamespaceOnMethod() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setGenerateJsInteropExports(true);

    MockJavaResource jsNamespaceFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsMethod;",
            "import jsinterop.annotations.JsType;",
            "@JsType public class Foo {",
            "  @JsMethod(namespace=\"spazz\") public static void doStaticBar() {}",
            "}");

    MockJavaResource regularFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType public class Foo {",
            "  public static void doStaticBar() {}",
            "}");

    checkRecompiledModifiedApp(
        compilerOptions,
        "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, emptyEntryPointResource, jsTypeBarResource),
        regularFooResource,
        jsNamespaceFooResource,
        stringSet("com.foo.Bar", "com.foo.Foo"),
        JsOutputOption.DETAILED);
  }

  /**
   * Tests that changing Js namespace on a class comes out accurately.
   *
   * <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
   * exports do not forget non-edited items in a recompile.
   */
  public void testChangeJsNamespaceOnClass() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setGenerateJsInteropExports(true);

    MockJavaResource jsNamespaceFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType(namespace=\"spazz\") public class Foo {",
            "  public static void doStaticBar() {}",
            "}");

    MockJavaResource regularFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType public class Foo {",
            "  public static void doStaticBar() {}",
            "}");

    checkRecompiledModifiedApp(
        compilerOptions,
        "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, emptyEntryPointResource, jsTypeBarResource),
        regularFooResource,
        jsNamespaceFooResource,
        stringSet("com.foo.Bar", "com.foo.Foo"),
        JsOutputOption.DETAILED);
  }

  /**
   * Tests that changing @JsFunction name on an interface comes out accurately.
   *
   * <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
   * exports do not forget non-edited items in a recompile.
   */
  public void testChangeJsFunction() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setGenerateJsInteropExports(true);

    MockJavaResource jsFunctionIFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.IFoo",
            "package com.foo;",
            "import jsinterop.annotations.JsFunction;",
            "@JsFunction public interface IFoo {",
            "  int foo(int x);",
            "}");

    MockJavaResource regularIFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.IFoo",
            "package com.foo;",
            "public interface IFoo {",
            "  int foo(int x);",
            "}");

    MockJavaResource fooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "public final class Foo implements IFoo {",
            "  @Override public int foo(int x) { return 0; }",
            "}");

    checkRecompiledModifiedApp(
        compilerOptions,
        "com.foo.SimpleModule",
        Lists.newArrayList(
            simpleModuleResource, entryPointResourceForFoo, fooResource, jsTypeBarResource),
        regularIFooResource,
        jsFunctionIFooResource,
        stringSet("com.foo.Bar", "com.foo.Foo", "com.foo.IFoo", "com.foo.TestEntryPoint"),
        JsOutputOption.DETAILED);
  }

  /**
   * Tests that toggling JsProperty methods in an interface comes out accurately.
   *
   * <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
   * exports do not forget non-edited items in a recompile.
   */
  public void testChangeJsProperty() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setGenerateJsInteropExports(true);

    MockJavaResource jsPropertyIFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.IFoo",
            "package com.foo;",
            "import jsinterop.annotations.JsProperty;",
            "import jsinterop.annotations.JsType;",
            "@JsType public interface IFoo {",
            "  @JsProperty int getX();",
            "  @JsProperty int getY();",
            "}");

    MockJavaResource regularIFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.IFoo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType public interface IFoo {",
            "  int getX();",
            "  int getY();",
            "}");

    MockJavaResource fooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "public class Foo implements IFoo {",
            "  @Override public int getX() { return 0; }",
            "  @Override public int getY() { return 0; }",
            "}");

    checkRecompiledModifiedApp(
        compilerOptions,
        "com.foo.SimpleModule",
        Lists.newArrayList(
            simpleModuleResource, entryPointResourceForFoo, fooResource, jsTypeBarResource),
        regularIFooResource,
        jsPropertyIFooResource,
        stringSet("com.foo.Bar", "com.foo.Foo", "com.foo.IFoo", "com.foo.TestEntryPoint"),
        JsOutputOption.DETAILED);
  }

  /**
   * Tests that adding a @JsType annotation on a class comes out accurately and that removing it
   * comes out accurately as well.
   *
   * <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
   * exports do not forget non-edited items in a recompile.
   */
  public void testChangeJsType() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setGenerateJsInteropExports(true);

    MockJavaResource jsTypeFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType public class Foo {",
            "  void doInstanceBar() {}",
            "  public static void doStaticBar() {}",
            "}");

    MockJavaResource regularFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo", "package com.foo;", "public class Foo {}");

    checkRecompiledModifiedApp(
        compilerOptions,
        "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, emptyEntryPointResource, jsTypeBarResource),
        regularFooResource,
        jsTypeFooResource,
        stringSet("com.foo.Bar", "com.foo.Foo"),
        JsOutputOption.DETAILED);
  }

  /**
   * Tests that changing a prototype on a @JsType annotated class comes out accurately.
   *
   * <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
   * exports do not forget non-edited items in a recompile.
   */
  public void testChangeJsTypeNative() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setGenerateJsInteropExports(true);

    MockJavaResource nativeFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType(isNative=true) public class Foo {",
            "  public static native void doStaticBar();",
            "}");

    MockJavaResource regularFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType public class Foo {",
            "  public static void doStaticBar() {}",
            "}");

    checkRecompiledModifiedApp(
        compilerOptions,
        "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, emptyEntryPointResource, jsTypeBarResource),
        regularFooResource,
        nativeFooResource,
        stringSet("com.foo.Bar", "com.foo.Foo"),
        JsOutputOption.DETAILED);
  }

  /**
   * Tests that adding a @JsIgnore annotation on a method comes out accurately and that removing
   * it comes out accurately as well.
   *
   * <p>An unrelated and non-updated @JsType is also included in each compile to verify that updated
   * exports do not forget non-edited items in a recompile.
   */
  public void testChangeJsIgnore() throws Exception {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setGenerateJsInteropExports(true);

    MockJavaResource jsIgnoreFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsIgnore;",
            "import jsinterop.annotations.JsType;",
            "@JsType public class Foo {",
            "  @JsIgnore public static void doStaticBar() {}",
            "}");

    MockJavaResource regularFooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType public class Foo {",
            "  public static void doStaticBar() {}",
            "}");

    checkRecompiledModifiedApp(
        compilerOptions,
        "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, emptyEntryPointResource, jsTypeBarResource),
        regularFooResource,
        jsIgnoreFooResource,
        stringSet("com.foo.Bar", "com.foo.Foo"),
        JsOutputOption.DETAILED);
  }

  public void testJsInteropNameCollision() throws Exception {
    MinimalRebuildCache minimalRebuildCache = new MinimalRebuildCache();
    File applicationDir = Files.createTempDir();
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setGenerateJsInteropExports(true);

    // Simple compile with one dialog.alert() export succeeds.
    compileToJs(compilerOptions, applicationDir, "com.foo.SimpleModule", Lists.newArrayList(
        simpleModuleResource, dialogEntryPointResource, simpleDialogResourceWithExport,
        complexDialogResourceSansExport), minimalRebuildCache, emptySet, JsOutputOption.OBFUSCATED);

    try {
      // Exporting a second dialog.alert() fails with an exported name collision.
      compileToJs(compilerOptions, applicationDir, "com.foo.SimpleModule",
          Lists.<MockResource> newArrayList(complexDialogResourceWithExport), minimalRebuildCache,
          emptySet, JsOutputOption.OBFUSCATED);
      fail("Compile should have failed");
    } catch (UnableToCompleteException e) {
      // success
    }

    // Reverting to just a single dialog.alert() starts succeeding again.
    compileToJs(compilerOptions, applicationDir, "com.foo.SimpleModule",
        Lists.<MockResource>newArrayList(complexDialogResourceSansExport), minimalRebuildCache,
        stringSet("com.foo.SimpleDialog", "com.foo.ComplexDialog", "com.foo.TestEntryPoint"),
        JsOutputOption.OBFUSCATED);
  }

  public void testGwtCreateJsoRebindResult() throws Exception {
    try {
      compileToJs(Files.createTempDir(), "com.foo.SimpleModule",
          Lists.newArrayList(simpleModuleResource, brokenGwtCreateEntryPointResource),
          new MinimalRebuildCache(), emptySet, JsOutputOption.OBFUSCATED);
      fail("Compile should have failed");
    } catch (UnableToCompleteException e) {
      // success
    }
  }

  public void testNonZeroArgConstructorEntryPoint() throws Exception {
    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/NonZeroArgConstructor.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.NonZeroArgConstructorEntryPoint'/>",
            "</module>");

    MockJavaResource entryPointResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.NonZeroArgConstructorEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class NonZeroArgConstructorEntryPoint implements EntryPoint {",
            "  public NonZeroArgConstructorEntryPoint(String s) {",
            "  }",
            "  public void onModuleLoad() {",
            "  }",
            "}");

    MinimalRebuildCache minimalRebuildCache = new MinimalRebuildCache();
    File applicationDir = Files.createTempDir();
    CompilerOptions compilerOptions = new CompilerOptionsImpl();

    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
    builder.setLowestLogLevel(TreeLogger.ERROR);
    builder.expectError(Pattern.compile("Errors in .*"), null);
    builder.expectError("Line 3: Rebind result 'com.foo.NonZeroArgConstructorEntryPoint' "
        + "has no default (zero argument) constructors", null);
    UnitTestTreeLogger errorLogger = builder.createLogger();
    try {
      // Simple compile with one dialog.alert() export succeeds.

      compileToJs(errorLogger, compilerOptions, applicationDir, "com.foo.NonZeroArgConstructor",
          Lists.newArrayList(moduleResource, entryPointResource), minimalRebuildCache,
          emptySet, JsOutputOption.OBFUSCATED);
      fail("Compile should have failed");
    } catch (UnableToCompleteException expected) {
      errorLogger.assertCorrectLogEntries();
    }
  }

  public void testDeterministicBuild_Draft_StackModeStrip() throws
      UnableToCompleteException, IOException {
    assertDeterministicBuild(HELLO_MODULE_STACKMODE_STRIP, 0);
  }

  public void testDeterministicBuild_Optimized_StackModeStrip() throws
      UnableToCompleteException, IOException {
    assertDeterministicBuild(HELLO_MODULE_STACKMODE_STRIP, 9);
  }

  public void testDeterministicBuild_Draft() throws UnableToCompleteException, IOException {
    assertDeterministicBuild(HELLO_MODULE, 0);
  }

  public void testDeterministicBuild_Optimized() throws UnableToCompleteException, IOException {
    assertDeterministicBuild(HELLO_MODULE, 9);
  }

  public void testSuccessfulCompile_jsoClassLiteralOrder() throws Exception {
    // Crafted resource to make sure the a native subclass is compiled before the JSO class,
    // In the case of native sublcasses the class hierarchy does not match the class literal
    // hierarchy.
    MockJavaResource nativeClassAndSubclass =
        JavaResourceBase.createMockJavaResource(
            "com.foo.MyNativeSubclass",
            "package com.foo;",
            "import jsinterop.annotations.JsType;",
            "@JsType(isNative=true)",
            "class NativeClass {",
            "}",
            "public class MyNativeSubclass extends NativeClass {",
            "}");

    MockJavaResource testEntryPoint =
        JavaResourceBase.createMockJavaResource(
            "com.foo.MyEntryPoint",
            "package com.foo;",
            "import com.foo.MyNativeSubclass;",
            "public class MyEntryPoint extends MyNativeSubclass {",
            "  public void onModuleLoad() {",
            "    Object o = new Object();",
            "    if (MyNativeSubclass.class.getName() == null) ",
            "      o = new MyNativeSubclass();",
            // Make .clazz reachable so that class literals are emmitted with the respective
            // classses.
            "    o.getClass();",
            "  }",
            "}");

    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/MyEntryPoint.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.MyEntryPoint'/>",
            "</module>");

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    // Make sure it compiles successfully with no assertions
    compilerOptions.setEnableAssertions(true);
    compilerOptions.setGenerateJsInteropExports(true);
    compilerOptions.setOutput(JsOutputOption.PRETTY);
    compilerOptions.setOptimizationLevel(9);
    assertCompileSucceeds(compilerOptions, testEntryPoint.getTypeName(),
        Lists.newArrayList(moduleResource, nativeClassAndSubclass, testEntryPoint));
  }

  // TODO(stalcup): add recompile tests for file deletion.

  public void testIncrementalRecompile_noop() throws UnableToCompleteException, IOException,
      InterruptedException {
    checkIncrementalRecompile_noop(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_noop(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_dateStampChange() throws UnableToCompleteException,
      IOException, InterruptedException {
    checkIncrementalRecompile_dateStampChange(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_dateStampChange(JsOutputOption.DETAILED);
  }

  // Repro for bug #9518
  public void testIncrementalRecompile_jsPropertyConsistencyCheck()
      throws UnableToCompleteException,
      IOException, InterruptedException {
    // Supertype defines the getter.
    MockJavaResource superType =
        JavaResourceBase.createMockJavaResource(
            "com.foo.SuperType",
            "package com.foo;",
            "import jsinterop.annotations.JsProperty;",
            "public class SuperType {",
            "  @JsProperty String getString() { return null; }",
            "}");

    // Subtype defines the setter.
    MockJavaResource subType =
        JavaResourceBase.createMockJavaResource(
            "com.foo.SubType",
            "package com.foo;",
            "import jsinterop.annotations.JsProperty;",
            "public class SubType extends SuperType {",
            "  @JsProperty void setString(String s) {}",
            "}");

    MockJavaResource testEntryPoint =
        JavaResourceBase.createMockJavaResource(
            "com.foo.TestEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class TestEntryPoint implements EntryPoint {",
            "  public void onModuleLoad() {",
            // Create Impl and pass it to JS but do not explicitly call m
            "    new SubType();",
            "  }",
            "}");

    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/TestModule.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.TestEntryPoint'/>",
            "</module>");

    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();

    // Perform a first compile.
    compileToJs(relinkApplicationDir, "com.foo.TestModule",
        Lists.newArrayList(moduleResource, testEntryPoint, subType, superType),
        relinkMinimalRebuildCache, null, JsOutputOption.OBFUSCATED);

    // Invalidate ONLY the subtype. The types referred by the parameters of supertype methods are
    // going to be reference only which means that the supertype property will have a reference
    // to a JClassType for "java.lang.String" that isExternal() and is different from the
    // (non external) reference in the supertype.
    relinkMinimalRebuildCache.markSourceFileStale("com/foo/SubType.java");
    compileToJs(relinkApplicationDir, "com.foo.TestModule", Lists.<MockResource> newArrayList(),
        relinkMinimalRebuildCache, null, JsOutputOption.OBFUSCATED);
  }

  public void testIncrementalRecompile_invalidatePreamble() throws UnableToCompleteException,
      IOException, InterruptedException {
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();

    // Perform a first compile.
    compileToJs(relinkApplicationDir, "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, emptyEntryPointResource),
        relinkMinimalRebuildCache, null, JsOutputOption.OBFUSCATED);
    // On first compile nothing is explicitly stale, only implicitly stale.
    assertEquals(0, relinkMinimalRebuildCache.getStaleTypeNames().size());

    // Recompile with a deep change that invalidates the preamble.
    relinkMinimalRebuildCache.markSourceFileStale("java/lang/Object.java");
    compileToJs(relinkApplicationDir, "com.foo.SimpleModule", Lists.<MockResource> newArrayList(),
        relinkMinimalRebuildCache, null, JsOutputOption.OBFUSCATED);
    // Show that preamble invalidation marks everything stale.
    assertTrue(relinkMinimalRebuildCache.getProcessedStaleTypeNames().size() > 100);

    // Recompile again with a tiny change. Prove that it's not stuck repeatedly invalidating the
    // whole world.
    compileToJs(relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource> newArrayList(emptyEntryPointResource), relinkMinimalRebuildCache, null,
        JsOutputOption.OBFUSCATED);
    // Show that only this little change is stale, not the whole world.
    assertEquals(2, getStaleTypeNames(relinkMinimalRebuildCache).size());
  }

  public void testIncrementalRecompile_bridgeMethodOverrideChain()
      throws UnableToCompleteException, IOException, InterruptedException {
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();

    // Perform a first compile.
    compileToJs(relinkApplicationDir, "com.foo.SimpleModule", Lists.newArrayList(
        simpleModuleResource, overriddenMethodChainEntryPointResource, topResource, middleResource,
        bottomResource), relinkMinimalRebuildCache, null, JsOutputOption.OBFUSCATED);
    // On first compile nothing is explicitly stale, only implicitly stale.
    assertEquals(0, relinkMinimalRebuildCache.getStaleTypeNames().size());

    // Recompile with a change to Bottom.
    relinkMinimalRebuildCache.markSourceFileStale("com/foo/Bottom.java");
    compileToJs(relinkApplicationDir, "com.foo.SimpleModule", Lists.<MockResource> newArrayList(),
        relinkMinimalRebuildCache, null, JsOutputOption.OBFUSCATED);
    // Show that the third level bridge method override of Top.run() is seen to be live and thus
    // makes type com.foo.Bottom$Value live.
    assertTrue(
        relinkMinimalRebuildCache.getProcessedStaleTypeNames().contains("com.foo.Bottom$Value"));
  }

  public void testIncrementalRecompile_classLiteralNewReference()
      throws UnableToCompleteException, IOException, InterruptedException {
    checkIncrementalRecompile_classLiteralNewReference(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_classLiteralNewReference(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_primitiveClassLiteralReference()
      throws UnableToCompleteException, IOException, InterruptedException {
    checkIncrementalRecompile_primitiveClassLiteralReference(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_primitiveClassLiteralReference(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_superClassOrder()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Linked output is sorted alphabetically except that super-classes come before sub-classes. If
    // on recompile a sub-class -> super-class relationship is lost then a sub-class with an
    // alphabetically earlier name might start linking out before the super-class.
    checkIncrementalRecompile_superClassOrder(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_superClassOrder(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_superFromStaleInner()
      throws UnableToCompleteException, IOException, InterruptedException {
    checkIncrementalRecompile_superFromStaleInner(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_superFromStaleInner(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_deterministicUiBinder() throws UnableToCompleteException,
      IOException, InterruptedException {
    checkIncrementalRecompile_deterministicUiBinder(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_deterministicUiBinder(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_uiBinderCssChange() throws UnableToCompleteException,
      IOException, InterruptedException {
    checkIncrementalRecompile_uiBinderCssChange(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_uiBinderCssChange(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_unstableGeneratorReferencesModifiedType()
      throws UnableToCompleteException, IOException, InterruptedException {
    checkIncrementalRecompile_unstableGeneratorReferencesModifiedType(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_unstableGeneratorReferencesModifiedType(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_withErrors()
      throws UnableToCompleteException, IOException, InterruptedException {
    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/Errors.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.ErrorsEntryPoint'/>",
            "</module>");

    MockJavaResource entryPointResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.ErrorsEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class ErrorsEntryPoint implements EntryPoint {",
            "  public void onModuleLoad() {",
            "    Foo.foo();",
            "  }",
            "}");

    MockJavaResource fooResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "public class Foo {",
            "  public static void foo() {",
            "  }",
            "}");

    MockJavaResource fooResourceWithErrors =
        JavaResourceBase.createMockJavaResource(
            "com.foo.Foo",
            "package com.foo;",
            "public class Foo {",
            "  public static void foo() {",
            "    // x() method is not defined anywhere, should result in a compile error.",
            "    x();",
            "  }",
            "}");

    MinimalRebuildCache minimalRebuildCache = new MinimalRebuildCache();
    File applicationDir = Files.createTempDir();
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setSourceLevel(SourceLevel.JAVA11);

    // Compile the application with no errors.
    compileToJs(TreeLogger.NULL, compilerOptions, applicationDir, "com.foo.Errors",
        Lists.newArrayList(moduleResource, entryPointResource, fooResource), minimalRebuildCache,
        emptySet, JsOutputOption.OBFUSCATED);

    // Recompile and expect error reporting.
    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
    builder.setLowestLogLevel(TreeLogger.ERROR);
    builder.expectError("Line 5: The method x() is undefined for the type Foo", null);
    UnitTestTreeLogger errorLogger = builder.createLogger();
    try {
      // Recompile but now the changed file has an error
      compileToJs(errorLogger, compilerOptions, applicationDir, "com.foo.Errors",
          Lists.newArrayList(moduleResource, entryPointResource, fooResourceWithErrors),
          minimalRebuildCache,
          emptySet, JsOutputOption.OBFUSCATED);
      fail("Compile should have failed");
    } catch (UnableToCompleteException expected) {
      errorLogger.assertLogEntriesContainExpected();
    }
  }

  public void testIncrementalRecompile_representedAsNative()
      throws UnableToCompleteException, IOException, InterruptedException {
    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/RepresentedAsNative.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.RepresentedAsNativeEntryPoint'/>",
            "</module>");

    MockResource entryPointResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.RepresentedAsNativeEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class RepresentedAsNativeEntryPoint implements EntryPoint {",
            "  public void onModuleLoad() {",
            "  Double d = new Double(1d);",
            "  }",
            "}");

    MockResource modifiedEntryPointResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.RepresentedAsNativeEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class RepresentedAsNativeEntryPoint implements EntryPoint {",
            "  public void onModuleLoad() {",
            "  Double d = new Double(\"1\");",
            "  }",
            "}");

    PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
    logger.setMaxDetail(TreeLogger.ERROR);

    MinimalRebuildCache minimalRebuildCache = new MinimalRebuildCache();
    File applicationDir = Files.createTempDir();
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setSourceLevel(SourceLevel.JAVA11);
    compilerOptions.setGenerateJsInteropExports(false);

    // Compile the application with no errors.
    compileToJs(logger, compilerOptions, applicationDir, "com.foo.RepresentedAsNative",
        Lists.newArrayList(moduleResource, entryPointResource), minimalRebuildCache,
        emptySet, JsOutputOption.OBFUSCATED);

    // Recompile but now the changed file has an error
    compileToJs(logger, compilerOptions, applicationDir, "com.foo.RepresentedAsNative",
        Lists.newArrayList(modifiedEntryPointResource),
        minimalRebuildCache,
        stringSet(
            "com.foo.RepresentedAsNativeEntryPoint",
            getEntryMethodHolderTypeName("com.foo.RepresentedAsNative")),
        JsOutputOption.OBFUSCATED);
  }

  public void testIncrementalRecompile_functionSignatureChange() throws UnableToCompleteException,
      IOException, InterruptedException {
    // Not testing recompile equality with Pretty/Obfuscated output since the JsIncrementalNamer's
    // behavior is order dependent, and while still correct, will come out different in a recompile
    // with this change versus a from scratch compile with this change.
    checkIncrementalRecompile_functionSignatureChange(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_compileTimeConstantChange() throws UnableToCompleteException,
      IOException, InterruptedException {
    checkIncrementalRecompile_compileTimeConstantChange(JsOutputOption.DETAILED);
    checkIncrementalRecompile_compileTimeConstantChange(JsOutputOption.OBFUSCATED);
  }

  public void testIncrementalRecompile_transitivelyFoldableConstant()
      throws UnableToCompleteException,
      IOException, InterruptedException {
    checkIncrementalRecompile_transitivelyFoldableConstant(JsOutputOption.DETAILED);
    checkIncrementalRecompile_transitivelyFoldableConstant(JsOutputOption.OBFUSCATED);
  }

  public void testIncrementalRecompile_packagePrivateDispatch() throws UnableToCompleteException,
      IOException, InterruptedException {
    checkIncrementalRecompile_packagePrivateOverride(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_packagePrivateOverride(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_prettyOutput()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Nominal tests for pretty output. Pretty and Obfuscated output share most of the same code
    // paths.
    checkIncrementalRecompile_typeHierarchyChange(JsOutputOption.PRETTY);
    checkIncrementalRecompile_unreachableIncompatibleChange(JsOutputOption.PRETTY);
  }

  public void testIncrementalRecompile_regularClassMadeIntoJsoClass()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Not testing recompile equality with Pretty/Obfuscated output since the JsIncrementalNamer's
    // behavior is order dependent, and while still correct, will come out different in a recompile
    // with this change versus a from scratch compile with this change.
    checkIncrementalRecompile_regularClassMadeIntoJsoClass(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_unreachableIncompatibleChange()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Not testing recompile equality with Pretty/Obfuscated output since the JsIncrementalNamer's
    // behavior is order dependent, and while still correct, will come out different in a recompile
    // with this change versus a from scratch compile with this change.
    checkIncrementalRecompile_unreachableIncompatibleChange(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_unreachableIncompatibleChange(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_typeHierarchyChange()
      throws UnableToCompleteException, IOException, InterruptedException {
    checkIncrementalRecompile_typeHierarchyChange(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_typeHierarchyChange(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_defaultMethod()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Tests that default method on superclasses are correctly constructed
    checkIncrementalRecompile_defaultMethod(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_defaultMethod(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_devirtualizeUnchangedJso()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Tests that a JSO calls through interfaces are correctly devirtualized when compiling per file
    // and the JSOs nor their single impl interfaces are not stale.
    checkIncrementalRecompile_devirtualizeUnchangedJso(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_devirtualizeUnchangedJso(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_devirtualizeString()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Tests that String calls through interfaces are correctly devirtualized when compiling per
    // file and neither String nor CharSequence interface are stale.
    checkIncrementalRecompile_devirtualizeString(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_devirtualizeString(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_devirtualizeComparable()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Tests that Doublecalls through interfaces are correctly devirtualized when compiling per
    // file and neither String nor CharSequence interface are stale.
    checkIncrementalRecompile_devirtualizeComparable(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_devirtualizeComparable(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_multipleClassGenerator()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Tests that a Generated type that is not directly referenced from the rebound GWT.create()
    // call is still marked stale, regenerated, retraversed and output as JS.
    checkIncrementalRecompile_multipleClassGenerator(JsOutputOption.OBFUSCATED);
    checkIncrementalRecompile_multipleClassGenerator(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_singleJsoIntfDispatchChange()
      throws UnableToCompleteException,
      IOException, InterruptedException {
    // Not testing recompile equality with Pretty/Obfuscated output since the JsIncrementalNamer's
    // behavior is order dependent, and while still correct, will come out different in a recompile
    // with this change versus a from scratch compile with this change.
    checkIncrementalRecompile_singleJsoIntfDispatchChange(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_dualJsoIntfDispatchChange() throws UnableToCompleteException,
      IOException, InterruptedException {
    // Not testing recompile equality with Pretty/Obfuscated output since the JsIncrementalNamer's
    // behavior is order dependent, and while still correct, will come out different in a recompile
    // with this change versus a from scratch compile with this change.
    checkIncrementalRecompile_dualJsoIntfDispatchChange(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_generatorInputResourceChange() throws IOException,
      UnableToCompleteException, InterruptedException {
    // Not testing recompile equality with Pretty/Obfuscated output since the JsIncrementalNamer's
    // behavior is order dependent, and while still correct, will come out different in a recompile
    // with this change versus a from scratch compile with this change.
    checkIncrementalRecompile_generatorInputResourceChange(JsOutputOption.DETAILED);
  }

  public void testIncrementalRecompile_invalidatedGeneratorOutputRerunsGenerator()
      throws UnableToCompleteException, IOException, InterruptedException {
    // BarReferencesFoo Generator hasn't run yet.
    assertEquals(0, BarReferencesFooGenerator.runCount);

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    List<MockResource> sharedResources =
        Lists.newArrayList(barReferencesFooGeneratorModuleResource, generatorEntryPointResource);
    JsOutputOption output = JsOutputOption.OBFUSCATED;

    List<MockResource> originalResources = Lists.newArrayList(sharedResources);
    originalResources.add(fooResource);

    // Compile the app with original files, modify a file and do a per-file recompile.
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule", originalResources,
        relinkMinimalRebuildCache, emptySet, output);

    // BarReferencesFoo Generator has now been run once.
    assertEquals(1, BarReferencesFooGenerator.runCount);

    // Recompile with no changes, which should not trigger any Generator runs.
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource>newArrayList(), relinkMinimalRebuildCache, emptySet, output);

    // Since there were no changes BarReferencesFoo Generator was not run again.
    assertEquals(1, BarReferencesFooGenerator.runCount);

    // Recompile with a modified Foo class, which should invalidate Bar which was generated by a
    // GWT.create() call in the entry point.
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource>newArrayList(fooResource), relinkMinimalRebuildCache,
        stringSet("com.foo.TestEntryPoint", "com.foo.Foo", "com.foo.Bar"), output);

    // BarReferencesFoo Generator was run again.
    assertEquals(2, BarReferencesFooGenerator.runCount);
  }

  public void testIncrementalRecompile_invalidatedGeneratorOutputRerunsCascadedGenerators()
      throws UnableToCompleteException, IOException, InterruptedException {
    // Generators haven't run yet.
    assertEquals(0, CauseStringRebindGenerator.runCount);
    assertEquals(0, CauseShortRebindGenerator.runCount);
    assertEquals(0, FooResourceGenerator.runCount);

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    List<MockResource> sharedResources = Lists.newArrayList(cascadingGeneratorModuleResource,
        generatorEntryPointResource, classNameToGenerateResource);
    JsOutputOption output = JsOutputOption.OBFUSCATED;

    List<MockResource> originalResources = Lists.newArrayList(sharedResources);

    // Compile the app with original files.
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule", originalResources,
        relinkMinimalRebuildCache, emptySet, output);

    // Generators have now been run once.
    assertEquals(1, CauseStringRebindGenerator.runCount);
    assertEquals(1, CauseShortRebindGenerator.runCount);
    assertEquals(1, FooResourceGenerator.runCount);

    // Recompile with no changes, which should not trigger any Generator runs.
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource>newArrayList(), relinkMinimalRebuildCache, emptySet, output);

    // Since there were no changes Generators were not run again.
    assertEquals(1, CauseStringRebindGenerator.runCount);
    assertEquals(1, CauseShortRebindGenerator.runCount);
    assertEquals(1, FooResourceGenerator.runCount);

    // Recompile with a modified resource, which should invalidate the output of the
    // FooResourceGenerator and cascade the invalidate the Generators that triggered
    // FooResourceGenerator.
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource>newArrayList(modifiedClassNameToGenerateResource),
        relinkMinimalRebuildCache, stringSet("com.foo.TestEntryPoint", "com.foo.Baz$InnerBaz",
            "com.foo.Bar", "com.foo.HasCustomContent", "com.foo.FooReplacementTwo"), output);

    // Generators were run again.
    assertEquals(2, CauseStringRebindGenerator.runCount);
    assertEquals(2, CauseShortRebindGenerator.runCount);
    assertEquals(2, FooResourceGenerator.runCount);
  }

  public void testIncrementalRecompile_carriesOverGeneratorArtifacts()
      throws UnableToCompleteException,
      IOException, InterruptedException {
    // Foo Generator hasn't run yet.
    assertEquals(0, FooResourceGenerator.runCount);

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    List<MockResource> sharedResources = Lists.newArrayList(resourceReadingGeneratorModuleResource,
        referencesBarAndGeneratorEntryPointResource, classNameToGenerateResource,
        barReferencesFooResource);
    JsOutputOption output = JsOutputOption.OBFUSCATED;

    List<MockResource> originalResources = Lists.newArrayList(sharedResources);
    originalResources.add(fooResource);

    // Compile the app with original files.
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule", originalResources,
        relinkMinimalRebuildCache, emptySet, output);

    // Foo Generator has now been run once.
    assertEquals(1, FooResourceGenerator.runCount);
    // The bar.txt artifact was output.
    File barFile = new File(relinkApplicationDir.getPath() + File.separator + "com.foo.SimpleModule"
        + File.separator + "bar.txt");
    assertTrue(barFile.exists());

    // Recompile with just 1 file change, which should not trigger any Generator runs.
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource> newArrayList(fooResource), relinkMinimalRebuildCache,
        stringSet("com.foo.Foo", "com.foo.Bar"), output);

    // Foo Generator was not run again.
    assertEquals(1, FooResourceGenerator.runCount);
    // But the bar.txt artifact was still output.
    barFile = new File(relinkApplicationDir.getPath() + File.separator + "com.foo.SimpleModule"
        + File.separator + "bar.txt");
    assertTrue(barFile.exists());
  }

  /**
   * Regression test for UnifyAST assertion failure problem in incremental SDM.
   */
  public void testIncrementalRecompile_unifyASTAssertionRegression()
      throws UnableToCompleteException, IOException, InterruptedException {

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    List<MockResource> originalResources = Lists.newArrayList(helloEntryPointResource,
        helloModuleResource);
    JsOutputOption output = JsOutputOption.OBFUSCATED;

    // Compile the app with original files.
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();
    compileToJs(compilerOptions, relinkApplicationDir, "com.foo.Hello",
        originalResources, relinkMinimalRebuildCache, emptySet, output);
  }

  private void checkIncrementalRecompile_noop(JsOutputOption output) throws UnableToCompleteException,
      IOException, InterruptedException {
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();

    String originalJs = compileToJs(relinkApplicationDir, "com.foo.SimpleModule", Lists
        .newArrayList(simpleModuleResource, simpleModelEntryPointResource, simpleModelResource,
            constantsModelResource),
        relinkMinimalRebuildCache, emptySet, output);

    // Compile again with absolutely no file changes and reusing the minimalRebuildCache.
    String relinkedJs = compileToJs(relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource>newArrayList(), relinkMinimalRebuildCache, emptySet, output);

    assertTrue(originalJs.equals(relinkedJs));
  }

  private void checkIncrementalRecompile_defaultMethod(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    // Tests that when a superclass has a "inherits" a default method,
    MockJavaResource interfaceWithDefaultMethod =
        JavaResourceBase.createMockJavaResource(
            "com.foo.InterfaceWithDefaultMethod",
            "package com.foo;",
            "interface InterfaceWithDefaultMethod {",
            "  default String m() {return null; }",
            "}");

    MockJavaResource classImplementingInterfaceWithDefaultMethod =
        JavaResourceBase.createMockJavaResource(
            "com.foo.classImplementingInterfaceWithDefaultMethod",
            "package com.foo;",
            "public class classImplementingInterfaceWithDefaultMethod",
            "    implements InterfaceWithDefaultMethod {",
            "}");

    MockJavaResource aSubclass =
        JavaResourceBase.createMockJavaResource(
            "com.foo.ASubclass",
            "package com.foo;",
            "public class ASubclass extends classImplementingInterfaceWithDefaultMethod {",
            "  public String someMethod() {return super.m(); }",
            "}");

    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/DefaultMethod.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.DefaultMethodEntryPoint'/>",
            "</module>");

    MockJavaResource entryPointResource =
        JavaResourceBase.createMockJavaResource(
            "com.foo.DefaultMethodEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class DefaultMethodEntryPoint implements EntryPoint {",
            "  public void onModuleLoad() {",
            "    new ASubclass().someMethod();",
            "  }",
            "}");

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);
    compilerOptions.setSourceLevel(SourceLevel.JAVA11);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.DefaultMethod",
        Lists.newArrayList(moduleResource, entryPointResource, aSubclass,
            classImplementingInterfaceWithDefaultMethod, interfaceWithDefaultMethod),
        aSubclass, aSubclass, stringSet("com.foo.ASubclass", "com.foo.DefaultMethodEntryPoint"),
        output);
  }

  public void checkIncrementalRecompile_classLiteralNewReference(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    MockJavaResource interfaceA =
        JavaResourceBase.createMockJavaResource(
            "com.foo.A",
            "package com.foo;",
            "interface A {",
            " static String b = \"\";",
            "}");

    MockJavaResource classBSansLiteralReference =
        JavaResourceBase.createMockJavaResource(
            "com.foo.B",
            "package com.foo;",
            "public class B {",
            "}");

    MockJavaResource classBWithLiteralReference =
        JavaResourceBase.createMockJavaResource(
            "com.foo.B",
            "package com.foo;",
            "public class B {",
            "  public B() { Class c = A.class; }",
            "}");

    MockJavaResource classC =
        JavaResourceBase.createMockJavaResource(
            "com.foo.C",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class C implements EntryPoint {",
            "  public void onModuleLoad() {",
            "    if (A.b == null) ",
            "      new B();",
            "  }",
            "}");

    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/ClassLiteralReference.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.C'/>",
            "</module>");

    checkRecompiledModifiedApp("com.foo.ClassLiteralReference", Lists.newArrayList(
            moduleResource, interfaceA, classC),
        classBSansLiteralReference, classBWithLiteralReference,
        stringSet("com.foo.B", "com.foo.C"), output);
  }

  public void checkIncrementalRecompile_primitiveClassLiteralReference(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    MockJavaResource classA =
        JavaResourceBase.createMockJavaResource(
            "com.foo.A",
            "package com.foo;",
            "public class A {",
            "  public A() { ",
            "    Class c = void.class; ",
            "    c = int.class; ",
            "    c = boolean.class;",
            "    c = short.class;",
            "    c = byte.class;",
            "    c = long.class;",
            "    c = float.class;",
            "    c = double.class;",
            "  }",
            "}");

    MockJavaResource classB =
        JavaResourceBase.createMockJavaResource(
            "com.foo.B",
            "package com.foo;",
            "public class B {",
            "  public B() {  }",
            "  public void m () { new A(); }",
            "}");

    MockJavaResource classC =
        JavaResourceBase.createMockJavaResource(
            "com.foo.C",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class C implements EntryPoint {",
            "  public void onModuleLoad() {",
            "      new B().m();",
            "  }",
            "}");

    MockResource moduleResource =
        JavaResourceBase.createMockResource(
            "com/foo/PrimitiveClassLiteralReference.gwt.xml",
            "<module>",
            "  <source path=''/>",
            "  <entry-point class='com.foo.C'/>",
            "</module>");

    checkRecompiledModifiedApp("com.foo.PrimitiveClassLiteralReference", Lists.newArrayList(
            moduleResource, classA, classB),
        classC, classC,
        stringSet(getEntryMethodHolderTypeName("com.foo.PrimitiveClassLiteralReference"),
            "com.foo.C"), output);
  }

  private void checkIncrementalRecompile_dateStampChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();

    String originalJs = compileToJs(relinkApplicationDir, "com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, simpleModelEntryPointResource, simpleModelResource,
            constantsModelResource),
        relinkMinimalRebuildCache, emptySet, output);

    // Compile again with the same source but a new date stamp on SimpleModel and reusing the
    // minimalRebuildCache.
    String relinkedJs = compileToJs(relinkApplicationDir, "com.foo.SimpleModule",
        Lists.<MockResource>newArrayList(simpleModelResource), relinkMinimalRebuildCache,
        stringSet("com.foo.TestEntryPoint", "com.foo.SimpleModel"), output);

    assertTrue(originalJs.equals(relinkedJs));
  }

  private void checkIncrementalRecompile_superClassOrder(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    // Mark ReferencedBySuperClassResource modified, so that SuperClass becomes stale. This will
    // result in SuperClass's indexing being rebuilt but NOT ASubClasses's. If there is a bug in the
    // index updates then the link output ordering will change.
    checkRecompiledModifiedApp("com.foo.SimpleModule", Lists.newArrayList(simpleModuleResource,
            superClassOrderEntryPointResource, referencedBySuperClassResource, superClassResource,
            aSubClassResource), referencedBySuperClassResource, referencedBySuperClassResource,
        stringSet("com.foo.SuperClass", "com.foo.ReferencedBySuperClass"), output);
  }

  private void checkIncrementalRecompile_superFromStaleInner(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    // Makes sure that type ids for (effectively static) super dispatches, i.e. of the form
    // super.m() or X.this.m(), are computed also for classes only referenced by stale classes.
    checkRecompiledModifiedApp("com.foo.SuperFromStaleInnerModule",
        Lists.newArrayList(superFromStaleInnerModuleResource,
            superFromStaleInnerEntryPointResource), interfaceOneResource, interfaceOneResource,
        stringSet(interfaceOneResource.getTypeName(), "com.foo.SuperFromStaleInnerEntryPoint$B",
            "com.foo.SuperFromStaleInnerEntryPoint$B$1"),
        output);
  }

  private void checkIncrementalRecompile_deterministicUiBinder(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();

    checkRecompiledModifiedApp(compilerOptions, "com.foo.UiBinderTestModule", Lists.newArrayList(
        uiBinderTestModuleResource, uiBinderTestEntryPointResource, myWidgetUiXml), myWidget,
        myWidget, stringSet("com.foo.MyWidget", "com.foo.MyWidget$Binder", "com.foo.TestEntryPoint",
            "com.foo.MyWidget_BinderImpl", "com.foo.MyWidget_BinderImpl$Widgets"), output);
  }

  private void checkIncrementalRecompile_uiBinderCssChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    // Switches from a white styled widget to a grey styled widget in the CSS in the style tag
    // nested in the .ui.xml template file.
    String binderImpl = "com.foo.MyWidget_BinderImpl";
    checkRecompiledModifiedApp("com.foo.UiBinderTestModule",
        Lists.newArrayList(uiBinderTestModuleResource, uiBinderTestEntryPointResource, myWidget),
        myWidgetWithWhiteStyleUiXml, myWidgetWithGreyStyleUiXml,
        stringSet("com.foo.MyWidget",
            binderImpl, binderImpl + "_GenBundle_default_InlineClientBundleGenerator",
            binderImpl + "_GenBundle_default_InlineClientBundleGenerator$1",
            binderImpl + "_GenBundle_default_InlineClientBundleGenerator$styleInitializer",
            binderImpl + "_TemplateImpl",
            binderImpl + "$Widgets", binderImpl + "$Template"), output);
  }

  private void checkIncrementalRecompile_packagePrivateOverride(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.SimpleModule", Lists.newArrayList(
            simpleModuleResource, packagePrivateDispatchEntryPointResource,
            packagePrivateParentResource, referencesParentResource),
        packagePrivateChildResource, packagePrivateChildResource,
        stringSet("com.foo.PackagePrivateChild", "com.foo.TestEntryPoint"), output);
  }

  private void checkIncrementalRecompile_regularClassMadeIntoJsoClass(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.SimpleModule", Lists.newArrayList(
        simpleModuleResource, jsoArrayTestEntryPointResource, someClassReferringToJsoOneArrays,
        someClassReferringToJsoTwoArrays, jsoOne), jsoTwo_before, jsoTwo_after,
        stringSet("com.foo.JsoTwo", "com.foo.SomeClassReferringToJsoTwoArrays"), output);
  }

  private void checkIncrementalRecompile_unstableGeneratorReferencesModifiedType(
      JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    // Make sure that the recompile with changes and the full compile with changes have the same
    // output from the unstable generator, so that it is safe to make byte for byte output
    // comparisons.
    UnstableNestedAnonymousGenerator.outputVersionOrder.addAll(Lists.newArrayList(
        // first compile
        OutputVersion.A,
        // recompile with changes
        OutputVersion.B,
        // full compile with changes
        OutputVersion.B));
    checkRecompiledModifiedApp("com.foo.SimpleModule",
        Lists.newArrayList(generatorEntryPointResource, unstableGeneratorModuleResource),
        fooResource, sameContentDifferentTimeFooResource, stringSet(
            "com.foo.NestedAnonymousClasses$1", "com.foo.NestedAnonymousClasses",
            "com.foo.NestedAnonymousClasses$ClassTwo", "com.foo.NestedAnonymousClasses$ClassOne",
            "com.foo.TestEntryPoint", "com.foo.NestedAnonymousClasses$1$1", "com.foo.Foo"), output);
  }

  private void checkIncrementalRecompile_functionSignatureChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    checkRecompiledModifiedApp("com.foo.SimpleModule", Lists.newArrayList(
            simpleModuleResource, simpleModelEntryPointResource, constantsModelResource),
        simpleModelResource, modifiedFunctionSignatureSimpleModelResource,
        stringSet("com.foo.TestEntryPoint", "com.foo.SimpleModel"), output);
  }

  private void checkIncrementalRecompile_compileTimeConstantChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    checkRecompiledModifiedApp("com.foo.SimpleModule", Lists.newArrayList(
            simpleModuleResource, simpleModelEntryPointResource, simpleModelResource),
        constantsModelResource, modifiedConstantsModelResource,
        stringSet("com.foo.SimpleModel", "com.foo.Constants"), output);
  }

  private void checkIncrementalRecompile_transitivelyFoldableConstant(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    // Tests that constants that are provided by types are only referenced by reference only types
    // (hence not traversed) are still available for constant propagation.
    checkRecompiledModifiedApp("com.foo.TransitivelyFoldableConstantModule", Lists.newArrayList(
            transitivelyFoldableConstantModuleResource, classOneResource, classTwoResource),
        transitivelyFoldableConstantEntryPointResource,
        transitivelyFoldableConstantEntryPointResource,
        stringSet("com.foo.TransitivelyFoldableConstantEntryPoint",
            getEntryMethodHolderTypeName("com.foo.TransitivelyFoldableConstantModule")),
        output);
  }

  private void checkIncrementalRecompile_unreachableIncompatibleChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    checkRecompiledModifiedApp("com.foo.SimpleModule",
        Lists.newArrayList(simpleModuleResource, emptyEntryPointResource), nonCompilableFooResource,
        nonCompilableFooResource, stringSet(), output);
  }

  private void checkIncrementalRecompile_typeHierarchyChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    checkRecompiledModifiedApp("com.foo.SimpleModule", Lists.newArrayList(simpleModuleResource,
        modifiedSuperEntryPointResource, modelAResource, modelBResource, modelDResource),
        modelCResource, modifiedSuperModelCResource,
        stringSet("com.foo.TestEntryPoint", "com.foo.ModelC", "com.foo.ModelD"), output);
  }

  private void checkIncrementalRecompile_singleJsoIntfDispatchChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.SimpleModule", Lists.newArrayList(
        simpleModuleResource, modifiedJsoIntfDispatchEntryPointResource, callerResource,
        fooInterfaceResource), nonJsoFooResource, jsoFooResource,
        stringSet("com.foo.TestEntryPoint", "com.foo.Foo", "com.foo.Caller"), output);
  }

  private void checkIncrementalRecompile_devirtualizeUnchangedJso(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.SimpleModule",
        Lists.newArrayList(jsoTestModuleResource, simpleFactory, simpleIntf, simpleJso),
        jsoTestEntryPointResource, jsoTestEntryPointResource, stringSet("com.foo.TestEntryPoint",
        getEntryMethodHolderTypeName("com.foo.SimpleModule")), output);
  }

  private void checkIncrementalRecompile_devirtualizeString(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.DevirtualizeStringModule",
        Lists.newArrayList(devirtualizeStringModuleResource),
        devirtualizeStringEntryPointResource, devirtualizeStringEntryPointResource,
        stringSet("com.foo.DevirtualizeStringEntryPoint",
            getEntryMethodHolderTypeName("com.foo.DevirtualizeStringModule")),
        output);
  }

  private void checkIncrementalRecompile_devirtualizeComparable(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {

    final MockResource devirtualizeComparableModuleResource =
        JavaResourceBase.createMockResource("com/foo/DevirtualizeComparableModule.gwt.xml",
            "<module>",
            "<source path=''/>",
            "<entry-point class='com.foo.DevirtualizeComparableEntryPoint'/>",
            "</module>");

    final MockJavaResource devirtualizeComparableEntryPointResource =
        JavaResourceBase.createMockJavaResource("com.foo.DevirtualizeComparableEntryPoint",
            "package com.foo;",
            "import com.google.gwt.core.client.EntryPoint;",
            "public class DevirtualizeComparableEntryPoint implements EntryPoint {",
            "  @Override",
            "  public void onModuleLoad() {",
            "    Comparable c = (Double) 0.1;",
            "    c.compareTo(c);",
            "  }",
            "}");

    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.DevirtualizeComparableModule",
        Lists.newArrayList(devirtualizeComparableModuleResource),
        devirtualizeComparableEntryPointResource, devirtualizeComparableEntryPointResource,
        stringSet("com.foo.DevirtualizeComparableEntryPoint",
            getEntryMethodHolderTypeName("com.foo.DevirtualizeComparableModule")),
        output);
  }

  private void checkIncrementalRecompile_multipleClassGenerator(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.SimpleModule",
        Lists.newArrayList(multipleClassGeneratorModuleResource, generatorEntryPointResource),
        bazResource, bazResource,
        stringSet("com.foo.Baz", "com.foo.TestEntryPoint", "com.foo.Bar"), output);
  }

  private void checkIncrementalRecompile_dualJsoIntfDispatchChange(JsOutputOption output)
      throws UnableToCompleteException, IOException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.SimpleModule", Lists.newArrayList(
        simpleModuleResource, modifiedJsoIntfDispatchEntryPointResource, callerResource,
        fooInterfaceResource, regularFooImplemetorResource), nonJsoFooResource, jsoFooResource,
        stringSet("com.foo.TestEntryPoint", "com.foo.Foo", "com.foo.Caller"), output);
  }

  private void checkIncrementalRecompile_generatorInputResourceChange(JsOutputOption outputOption)
      throws IOException, UnableToCompleteException, InterruptedException {
    CompilerOptions compilerOptions = new CompilerOptionsImpl();
    compilerOptions.setUseDetailedTypeIds(true);

    checkRecompiledModifiedApp(compilerOptions, "com.foo.SimpleModule", Lists.newArrayList(
        resourceReadingGeneratorModuleResource, generatorEntryPointResource, fooInterfaceResource,
        nonJsoFooResource), classNameToGenerateResource, modifiedClassNameToGenerateResource,
        stringSet("com.foo.TestEntryPoint", "com.foo.HasCustomContent",
            "com.foo.FooReplacementTwo"), outputOption);
  }

  private void assertCompileSucceeds(CompilerOptions options, String moduleName,
      List<MockResource> applicationResources) throws Exception {
    File compileWorkDir = Utility.makeTemporaryDirectory(null, moduleName);
    final CompilerOptionsImpl compilerOptions = new CompilerOptionsImpl(options);
    PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
    logger.setMaxDetail(TreeLogger.ERROR);

    String oldPersistentUnitCacheValue =
        System.setProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE, "false");
    try {

      File applicationDir = Files.createTempDir();
      Thread.sleep(1001);
      // We might be reusing the same application dir but we want to make sure that the output dir
      // is clean to avoid confusion when returning the output JS.
      File outputDir = new File(applicationDir.getPath() + File.separator + moduleName);
      if (outputDir.exists()) {
        Util.recursiveDelete(outputDir, true);
      }

      // Fake out the resource loader to read resources both from the normal classpath as well as
      // this new application directory.
      ResourceLoader resourceLoader = ResourceLoaders.fromContextClassLoader();
      resourceLoader =
          ResourceLoaders.forPathAndFallback(ImmutableList.of(applicationDir), resourceLoader);

      // Setup options to perform a per-file compile, output to this new application directory and
      // compile the given module.
      compilerOptions.setGenerateJsInteropExports(true);
      compilerOptions.setWarDir(applicationDir);
      compilerOptions.setModuleNames(ImmutableList.of(moduleName));

      // Write the Java/XML/etc resources that make up the test application.
      for (MockResource applicationResource : applicationResources) {
        writeResourceTo(applicationResource, applicationDir);
      }

      // Cause the module to be cached with a reference to the prefixed resource loader so that the
      // compile process will see those resources.
      ModuleDefLoader.clearModuleCache();
      ModuleDefLoader.loadFromResources(logger, moduleName, resourceLoader, true);

      options.addModuleName(moduleName);
      options.setWarDir(new File(compileWorkDir, "war"));
      options.setExtraDir(new File(compileWorkDir, "extra"));

      // Run the compiler once here.
      Compiler.compile(logger, options);
    } finally {
      Util.recursiveDelete(compileWorkDir, false);
      if (oldPersistentUnitCacheValue == null) {
        System.clearProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE);
      } else {
        System.setProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE, oldPersistentUnitCacheValue);
      }
    }
  }

  private void assertDeterministicBuild(String topLevelModule, int optimizationLevel)
      throws UnableToCompleteException, IOException {

    final CompilerOptionsImpl options = new CompilerOptionsImpl();
    options.setOptimizationLevel(optimizationLevel);

    File firstCompileWorkDir = Utility.makeTemporaryDirectory(null, "hellowork");
    File secondCompileWorkDir = Utility.makeTemporaryDirectory(null, "hellowork");
    String oldPersistentUnitCacheValue =
        System.setProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE, "false");
    try {
      options.addModuleName(topLevelModule);
      options.setWarDir(new File(firstCompileWorkDir, "war"));
      options.setExtraDir(new File(firstCompileWorkDir, "extra"));
      TreeLogger logger = TreeLogger.NULL;

      // Run the compiler once here.
      Compiler.compile(logger, options);
      Set<String> firstTimeOutput =
          Sets.newHashSet(new File(options.getWarDir() + "/hello").list());

      options.setWarDir(new File(secondCompileWorkDir, "war"));
      options.setExtraDir(new File(secondCompileWorkDir, "extra"));
      // Run the compiler for a second time here.
      Compiler.compile(logger, options);
      Set<String> secondTimeOutput =
          Sets.newHashSet(new File(options.getWarDir() + "/hello").list());

      // It is only necessary to check that the filenames in the output directory are the same
      // because the names of the files for the JavaScript outputs are the hash of its contents.
      assertEquals("First and second compile produced different outputs", firstTimeOutput,
          secondTimeOutput);
    } finally {
      if (oldPersistentUnitCacheValue == null) {
        System.clearProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE);
      } else {
        System.setProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE, oldPersistentUnitCacheValue);
      }
      Util.recursiveDelete(firstCompileWorkDir, false);
      Util.recursiveDelete(secondCompileWorkDir, false);
    }
  }

  /**
   * Compiles an initial application with version 1 of file Foo, then recompiles using version 2 of
   * file Foo. Lastly it performs a final from scratch compile using version 2 of file Foo and
   * verifies that the recompile and the full compile (both of which used version 2 of file Foo)
   * come out the same.
   */
  private void checkRecompiledModifiedApp(
      String moduleName,
      List<MockResource> sharedResources,
      MockResource originalResource,
      MockResource modifiedResource,
      Set<String> expectedStaleTypeNamesOnModify,
      JsOutputOption output)
      throws IOException, UnableToCompleteException, InterruptedException {
    checkRecompiledModifiedApp(new CompilerOptionsImpl(), moduleName, sharedResources,
        originalResource, modifiedResource, expectedStaleTypeNamesOnModify, output);
  }

  /**
   * Compiles an initial application with version 1 of file Foo, then recompiles using version 2 of
   * file Foo. Lastly it performs a final from scratch compile using version 2 of file Foo and
   * verifies that the recompile and the full compile (both of which used version 2 of file Foo)
   * come out the same.
   */
  private void checkRecompiledModifiedApp(
      CompilerOptions compilerOptions,
      String moduleName,
      List<MockResource> sharedResources,
      MockResource originalResource,
      MockResource modifiedResource,
      Set<String> expectedStaleTypeNamesOnModify,
      JsOutputOption output)
      throws IOException, UnableToCompleteException, InterruptedException {
    List<MockResource> originalResources = Lists.newArrayList(sharedResources);
    originalResources.add(originalResource);

    List<MockResource> modifiedResources = Lists.newArrayList(sharedResources);
    modifiedResources.add(modifiedResource);

    // Compile the app with original files, modify a file and do a per-file recompile.
    MinimalRebuildCache relinkMinimalRebuildCache = new MinimalRebuildCache();
    File relinkApplicationDir = Files.createTempDir();
    String originalAppFromScratchJs = compileToJs(compilerOptions, relinkApplicationDir, moduleName,
        originalResources, relinkMinimalRebuildCache, emptySet, output);
    String modifiedAppRelinkedJs = compileToJs(compilerOptions, relinkApplicationDir, moduleName,
        Lists.<MockResource> newArrayList(modifiedResource), relinkMinimalRebuildCache,
        expectedStaleTypeNamesOnModify, output);

    // Compile the app from scratch with the modified file.
    MinimalRebuildCache fromScratchMinimalRebuildCache = new MinimalRebuildCache();
    File fromScratchApplicationDir = Files.createTempDir();
    String modifiedAppFromScratchJs = compileToJs(compilerOptions, fromScratchApplicationDir,
        moduleName, modifiedResources, fromScratchMinimalRebuildCache, emptySet, output);

    // If a resource contents were changed between the original compile and the relink compile
    // check that the output JS has also changed. If all resources have the same content (their
    // timestamps might have changed) then outputs should be the same.
    boolean wasNotModified = modifiedResource == originalResource;
    assertTrue("Resource " + modifiedResource.getPath()  + " was " +
        (wasNotModified ? "NOT " : "") + "modified but the output was " +
        (wasNotModified ? "" : "NOT ") + "different.",
        wasNotModified  == originalAppFromScratchJs.equals(modifiedAppRelinkedJs));

    // If per-file compiles properly avoids global-knowledge dependencies and correctly invalidates
    // referencing types when a type changes, then the relinked and from scratch JS will be
    // identical.
    assertTrue(modifiedAppRelinkedJs.equals(modifiedAppFromScratchJs));
  }

  private String compileToJs(File applicationDir, String moduleName,
      List<MockResource> applicationResources, MinimalRebuildCache minimalRebuildCache,
      Set<String> expectedStaleTypeNames, JsOutputOption output) throws IOException,
      UnableToCompleteException, InterruptedException {
    return compileToJs(new CompilerOptionsImpl(), applicationDir, moduleName, applicationResources,
        minimalRebuildCache, expectedStaleTypeNames, output);
  }

  private String compileToJs(CompilerOptions compilerOptions, File applicationDir,
      String moduleName, List<MockResource> applicationResources,
      MinimalRebuildCache minimalRebuildCache, Set<String> expectedProcessedStaleTypeNames,
      JsOutputOption output) throws IOException, UnableToCompleteException, InterruptedException {

    PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
    logger.setMaxDetail(TreeLogger.ERROR);
    return compileToJs(logger, compilerOptions, applicationDir, moduleName, applicationResources,
        minimalRebuildCache, expectedProcessedStaleTypeNames, output);
  }

  private String compileToJs(TreeLogger logger, CompilerOptions compilerOptions, File applicationDir,
      String moduleName, List<MockResource> applicationResources,
      MinimalRebuildCache minimalRebuildCache, Set<String> expectedProcessedStaleTypeNames,
      JsOutputOption output) throws IOException, UnableToCompleteException, InterruptedException {
    // Make sure we're using a MemoryUnitCache.
    System.setProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE, "false");
    // Wait 1 second so that any new file modification times are actually different.
    Thread.sleep(1001);
    // We might be reusing the same application dir but we want to make sure that the output dir is
    // clean to avoid confusion when returning the output JS.
    File outputDir = new File(applicationDir.getPath() + File.separator + moduleName);
    if (outputDir.exists()) {
      Util.recursiveDelete(outputDir, true);
    }

    // Fake out the resource loader to read resources both from the normal classpath as well as this
    // new application directory.
    ResourceLoader resourceLoader = ResourceLoaders.fromContextClassLoader();
    resourceLoader =
        ResourceLoaders.forPathAndFallback(ImmutableList.of(applicationDir), resourceLoader);

    // Setup options to perform a per-file compile, output to this new application directory and
    // compile the given module.
    compilerOptions.setIncrementalCompileEnabled(true);
    compilerOptions.setWarDir(applicationDir);
    compilerOptions.setModuleNames(ImmutableList.of(moduleName));
    compilerOptions.setOutput(output);

    // Write the Java/XML/etc resources that make up the test application.
    for (MockResource applicationResource : applicationResources) {
      writeResourceTo(applicationResource, applicationDir);
    }

    // Cause the module to be cached with a reference to the prefixed resource loader so that the
    // compile process will see those resources.
    ModuleDefLoader.clearModuleCache();
    ModuleDef moduleDef = ModuleDefLoader.loadFromResources(logger, moduleName, resourceLoader, true);

    // Run the compile.
    Compiler.compile(logger, compilerOptions, minimalRebuildCache, moduleDef);

    // Find, read and return the created JS.
    File outputJsFile = null;
    outputDir = new File(applicationDir.getPath() + File.separator + moduleName);
    if (outputDir.exists()) {
      for (File outputFile : outputDir.listFiles()) {
        if (outputFile.getPath().endsWith(".cache.js")) {
          outputJsFile = outputFile;
          break;
        }
      }
    }

    if (outputJsFile == null) {
      throw new UnableToCompleteException();
    }

    if (expectedProcessedStaleTypeNames != null) {
      assertEquals(expectedProcessedStaleTypeNames, getStaleTypeNames(minimalRebuildCache));
    }
    return Files.toString(outputJsFile, Charsets.UTF_8);
  }

  private Set<String> getStaleTypeNames(MinimalRebuildCache relinkMinimalRebuildCache) {
    Set<String> staleTypeNames =
        new HashSet<>(relinkMinimalRebuildCache.getProcessedStaleTypeNames());
    // List of JRE types that provide JsInterop entry points and jre native JsTypes. These are
    // always traversed fully and polute the tests, so they will be removed from stale type
    // comparisons.
    staleTypeNames.removeAll(Arrays.asList(
        "java.io.HasSerializableTypeMarker",
        "java.io.Serializable",
        "java.lang.Boolean",
        "java.lang.CharSequence",
        "java.lang.Cloneable",
        "java.lang.Comparable",
        "java.lang.Double",
        "java.lang.HasCharSequenceTypeMarker",
        "java.lang.HasCloneableTypeMarker",
        "java.lang.HasComparableTypeMarker",
        "java.lang.Integer$NativeNumber",
        "java.lang.Number",
        "java.lang.Number$JavaLangNumber",
        "java.lang.String",
        "java.lang.String$NativeFunction",
        "java.lang.String$NativeString",
        "java.lang.Throwable",
        "java.lang.Throwable$HasJavaThrowable",
        "java.lang.Throwable$NativeError",
        "java.lang.Throwable$NativeTypeError",
        "javaemul.internal.NativeRegExp",
        "javaemul.internal.NativeRegExp$Match"));
    return staleTypeNames;
  }

  private String getEntryMethodHolderTypeName(String typeName) {
    return "com.google.gwt.lang." +
        EntryMethodHolderGenerator.getEntryMethodHolderTypeName(typeName);
  }

  private Set<String> stringSet(String... strings) {
    return Sets.newHashSet(strings);
  }

  private void writeResourceTo(MockResource mockResource, File applicationDir) throws IOException {
    File resourceFile =
        new File(applicationDir.getAbsolutePath() + File.separator + mockResource.getPath());
    resourceFile.getParentFile().mkdirs();
    Files.write(mockResource.getContent(), resourceFile, Charsets.UTF_8);
  }
}
