// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.google.dart.compiler.end2end.inc;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.dart.compiler.CompilerTestCase;
import com.google.dart.compiler.DartCompilationError;
import com.google.dart.compiler.DartCompiler;
import com.google.dart.compiler.DartCompilerErrorCode;
import com.google.dart.compiler.DartCompilerListener;
import com.google.dart.compiler.DartSource;
import com.google.dart.compiler.DefaultCompilerConfiguration;
import com.google.dart.compiler.LibrarySource;
import com.google.dart.compiler.MockArtifactProvider;
import com.google.dart.compiler.PackageLibraryManager;
import com.google.dart.compiler.Source;
import com.google.dart.compiler.UrlSource;
import com.google.dart.compiler.ast.DartUnit;
import com.google.dart.compiler.ast.LibraryUnit;
import com.google.dart.compiler.common.ErrorExpectation;
import com.google.dart.compiler.resolver.ResolverErrorCode;
import com.google.dart.compiler.resolver.TypeErrorCode;
import com.google.dart.compiler.type.TypeQuality;

import static com.google.dart.compiler.DartCompiler.EXTENSION_DEPS;
import static com.google.dart.compiler.DartCompiler.EXTENSION_TIMESTAMP;
import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
import static com.google.dart.compiler.common.ErrorExpectation.errEx;

import junit.framework.AssertionFailedError;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;

// TODO(zundel): update this test not to rely on code generation
public class IncrementalCompilation2Test extends CompilerTestCase {
  private static final String APP = "Application.dart";

  private static class IncMockArtifactProvider extends MockArtifactProvider {
    Set<String> reads = new ConcurrentSkipListSet<String>();
    Set<String> writes = new ConcurrentSkipListSet<String>();

    @Override
    public Reader getArtifactReader(Source source, String part, String extension) {
      reads.add(source.getName() + "/" + extension);
      return super.getArtifactReader(source, part, extension);
    }

    @Override
    public Writer getArtifactWriter(Source source, String part, String extension) {
      writes.add(source.getName() + "/" + extension);
      return super.getArtifactWriter(source, part, extension);
    }

    void resetReadsAndWrites() {
      reads.clear();
      writes.clear();
    }
  }

  private DefaultCompilerConfiguration config;
  private IncMockArtifactProvider provider;
  private MemoryLibrarySource appSource;
  private final List<DartCompilationError> errors = Lists.newArrayList();
  private final Map<String, DartUnit> units = Maps.newHashMap();

  @Override
  protected void setUp() throws Exception {
    config = new DefaultCompilerConfiguration() {
      @Override
      public boolean incremental() {
        return true;
      }
    };
    provider = new IncMockArtifactProvider();
    appSource = new MemoryLibrarySource(APP);
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "part 'A.dart';",
            "part 'B.dart';",
            "part 'C.dart';",
            ""));
    appSource.setContent("A.dart", "part of application;");
    appSource.setContent("B.dart", "part of application;");
    appSource.setContent("C.dart", "part of application;");
  }

  @Override
  protected void tearDown() {
    config = null;
    provider = null;
    appSource = null;
    errors.clear();
    units.clear();
  }

  /**
   * "not_hole" is referenced using "super" qualifier, so is not affected by declaring top-level
   * field with same name.
   */
  public void test_useQualifiedFieldReference_ignoreTopLevelDeclaration() {
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "  int not_hole;",
            "}",
            ""));
    appSource.setContent(
        "C.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class B extends A {",
            "  int bar() {",
            "    return super.not_hole;", // qualified reference
            "  }",
            "}",
            ""));
    compile();
    assertErrors(errors);
    // Update units and compile.
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "int not_hole;",
            ""));
    compile();
    // TODO(scheglov) Fix this after 1159
    //assertErrors(errors, errEx(ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_WARNING, -1, 7, 20));
    // B should be compiled because it now conflicts with A.
    // C should not be compiled, because it reference "not_hole" field, not top-level variable.
    didWrite("A.dart", EXTENSION_TIMESTAMP);
    didWrite("B.dart", EXTENSION_TIMESTAMP);
    didNotWrite("C.dart", EXTENSION_TIMESTAMP);
    assertAppBuilt();
  }

  /**
   * Referenced "hole" identifier can not be resolved, but when we declare it in A, then B should be
   * recompiled and error message disappear.
   */
  public void test_useUnresolvedField_recompileOnTopLevelDeclaration() {
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "  int foo() {",
            "    return hole;", // no such field
            "  }",
            "}",
            ""));
    compile();
    assertErrors(errors, errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 12, 4));
    // Update units and compile.
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "int hole;",
            ""));
    compile();
    // A and B should be compiled.
    didWrite("A.dart", EXTENSION_TIMESTAMP);
    didWrite("B.dart", EXTENSION_TIMESTAMP);
    assertAppBuilt();
    // "hole" was filled with top-level field.
    assertErrors(errors);
  }

  /**
   * Test for "hole" feature. If we use unqualified invocation and add/remove top-level method, this
   * should cause compilation of invocation unit.
   */
  public void test_isMethodHole_useUnqualifiedInvocation() throws Exception {
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "  foo() {}",
            "}",
            ""));
    appSource.setContent(
        "C.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class B extends A {",
            "  int bar() {",
            "    foo();", // unqualified invocation
            "  }",
            "}",
            ""));
    compile();
    assertErrors(errors);
    // Declare top-level foo(), now invocation of foo() in B should be bound to this top-level.
    {
      appSource.setContent(
          "A.dart",
          makeCode(
              "// filler filler filler filler filler filler filler filler filler filler filler",
              "part of application;",
              "foo() {}",
              ""));
      compile();
      // B should be compiled because it also declares foo(), so produces "shadow" conflict.
      // C should be compiled because it has unqualified invocation which was declared in A.
      didWrite("A.dart", EXTENSION_TIMESTAMP);
      didWrite("B.dart", EXTENSION_TIMESTAMP);
      didWrite("C.dart", EXTENSION_TIMESTAMP);
      assertAppBuilt();
    }
    // Wait, because analysis is so fast that may be A will have same time as old artifact.
    Thread.sleep(5);
    // Remove top-level foo(), so invocation of foo() in B should be bound to the super class.
    {
      appSource.setContent("A.dart", "part of application;");
      compile();
      // B should be compiled because it also declares foo(), so produces "shadow" conflict.
      // C should be compiled because it has unqualified invocation which was declared in A.
      didWrite("A.dart", EXTENSION_TIMESTAMP);
      didWrite("B.dart", EXTENSION_TIMESTAMP);
      didWrite("C.dart", EXTENSION_TIMESTAMP);
    }
  }

  /**
   * Test for "hole" feature. If we use qualified invocation and add/remove top-level method, this
   * should not cause compilation of invocation unit.
   */
  public void test_notMethodHole_useQualifiedInvocation() {
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "  foo() {}",
            "}",
            ""));
    appSource.setContent(
        "C.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class B extends A {",
            "  int bar() {",
            "    super.foo();", // qualified invocation
            "  }",
            "}",
            ""));
    compile();
    assertErrors(errors);
    // Declare top-level foo(), but it is ignored.
    {
      appSource.setContent(
          "A.dart",
          makeCode(
              "// filler filler filler filler filler filler filler filler filler filler filler",
              "part of application;",
              "foo() {}",
              ""));
      compile();
      // B should be compiled because it also declares foo(), so produces "shadow" conflict.
      // C should not be compiled because.
      didWrite("A.dart", EXTENSION_TIMESTAMP);
      didWrite("B.dart", EXTENSION_TIMESTAMP);
      didNotWrite("C.dart", EXTENSION_TIMESTAMP);
      assertAppBuilt();
    }
  }

  /**
   * Test for "hole" feature. If we use unqualified access and add/remove top-level field, this
   * should cause compilation of invocation unit.
   */
  public void test_fieldHole_useUnqualifiedAccess() throws Exception {
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "  var foo;",
            "}",
            ""));
    appSource.setContent(
        "C.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class B extends A {",
            "  int bar() {",
            "    foo = 0;", // unqualified access
            "  }",
            "}",
            ""));
    compile();
    assertErrors(errors);
    // Declare top-level "foo", now access to "foo" in B should be bound to this top-level.
    {
      appSource.setContent(
          "A.dart",
          makeCode(
              "// filler filler filler filler filler filler filler filler filler filler filler",
              "part of application;",
              "var foo;",
              ""));
      compile();
      // B should be compiled because it also declares "foo", so produces "shadow" conflict.
      // C should be compiled because it has unqualified invocation which was declared in A.
      didWrite("A.dart", EXTENSION_TIMESTAMP);
      didWrite("B.dart", EXTENSION_TIMESTAMP);
      didWrite("C.dart", EXTENSION_TIMESTAMP);
      assertAppBuilt();
    }
    // Wait, because analysis is so fast that may be A will have same time as old artifact.
    Thread.sleep(5);
    // Remove top-level "foo", so access to "foo" in B should be bound to the super class.
    {
      appSource.setContent("A.dart", "part of application;");
      compile();
      // B should be compiled because it also declares "foo", so produces "shadow" conflict.
      // C should be compiled because it has unqualified access which was declared in A.
      didWrite("A.dart", EXTENSION_TIMESTAMP);
      didWrite("B.dart", EXTENSION_TIMESTAMP);
      didWrite("C.dart", EXTENSION_TIMESTAMP);
    }
  }

  /**
   * Test for "hole" feature. If we use qualified access and add/remove top-level field, this should
   * not cause compilation of invocation unit.
   */
  public void test_fieldHole_useQualifiedAccess() {
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "  var foo;",
            "}",
            ""));
    appSource.setContent(
        "C.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class B extends A {",
            "  int bar() {",
            "    super.foo = 0;", // qualified access
            "  }",
            "}",
            ""));
    compile();
    assertErrors(errors);
    // Declare top-level "foo", but it is ignored.
    {
      appSource.setContent(
          "A.dart",
          makeCode(
              "// filler filler filler filler filler filler filler filler filler filler filler",
              "part of application;",
              "var foo;",
              ""));
      compile();
      // B should be compiled because it also declares "foo", so produces "shadow" conflict.
      // C should not be compiled because it has qualified access to "foo".
      didWrite("A.dart", EXTENSION_TIMESTAMP);
      didWrite("B.dart", EXTENSION_TIMESTAMP);
      didNotWrite("C.dart", EXTENSION_TIMESTAMP);
      assertAppBuilt();
    }
  }

  public void test_declareTopLevel_conflictWithLocalVariable() {
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "methodB() {",
            "  var symbolDependency_foo;",
            "}"));
    compile();
    assertErrors(errors);
    // Update units and compile.
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "var symbolDependency_foo;"));
    compile();
    // Now there is top-level declarations conflict between A and B.
    // So, B should be compiled.
    didWrite("B.dart", EXTENSION_TIMESTAMP);
    // But application should be build.
    assertAppBuilt();
  }

  public void test_undeclareTopLevel_conflictWithLocalVariable() {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "var duplicate;"));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "bar() {",
            "  var duplicate;",
            "}"));
    compile();
    // Update units and compile.
    appSource.setContent("A.dart", "part of application;");
    compile();
    // Top-level declaration in A was removed, so no conflict.
    // So:
    // ... B should be recompiled.
    didWrite("B.dart", EXTENSION_TIMESTAMP);
    // ... but application should be rebuild.
    assertAppBuilt();
  }

  /**
   * Removes A, so changes set of top level units and forces compilation.
   */
  public void test_removeOneSource() {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "var duplicate;"));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "bar() {",
            "  var duplicate;",
            "}"));
    compile();
    // Exclude A and compile.
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library app;",
            "part 'B.dart';",
            ""));
    compile();
    // Now there is top-level declarations conflict between A and B.
    // So:
    // ... B should be recompiled.
    didWrite("B.dart", EXTENSION_TIMESTAMP);
    // ... but application should be rebuild.
    didWrite(APP, EXTENSION_DEPS);
  }

  public void test_declareField_conflictWithLocalVariable() {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "}",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class B extends A {",
            "  foo() {",
            "    var bar;",
            "  }",
            "}",
            ""));
    compile();
    assertErrors(errors);
    // Update units and compile.
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "class A {",
            "  var bar;",
            "}",
            ""));
    compile();
    // B depends on A class, so compiled.
    didWrite("B.dart", EXTENSION_TIMESTAMP);
    assertAppBuilt();
  }

  public void test_declareTopLevelVariable_conflictOtherTopLevelVariable() {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "var conflict;",
            ""));
    compile();
    assertErrors(errors);
    // Update units and compile.
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "var conflict;",
            ""));
    compile();
    // A symbols intersect with new B symbols, so we compile A too.
    // Both A and B have errors.
    assertErrors(
        errors,
        errEx("A.dart", ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 8),
        errEx("B.dart", ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 8));
  }

  /**
   * Test that invalid "import" is reported as any other error between "unitAboutToCompile" and
   * "unitCompiled".
   */
  public void test_reportMissingImport() throws Exception {
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library app;",
            "import 'dart:noSuchLib.dart';",
            ""));
    // Remember errors only between unitAboutToCompile/unitCompiled.
    errors.clear();
    DartCompilerListener listener = new DartCompilerListener.Empty() {
      boolean isCompiling = false;

      @Override
      public void unitAboutToCompile(DartSource source, boolean diet) {
        isCompiling = true;
      }

      @Override
      public void onError(DartCompilationError event) {
        if (isCompiling) {
          errors.add(event);
        }
      }

      @Override
      public void unitCompiled(DartUnit unit) {
        isCompiling = false;
      }
    };
    DartCompiler.compileLib(appSource, config, provider, listener);
    // Check that errors where reported (and in correct time).
    assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 29));
  }

  /**
   * Test that same prefix can be used to import several libraries.
   */
  public void test_samePrefix_severalLibraries() throws Exception {
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart' as p;",
            "import 'B.dart' as p;",
            "f() {",
            "  p.a = 1;",
            "  p.b = 2;",
            "}",
            ""));
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            "var a;",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library B;",
            "var b;",
            ""));
    // do compile, no errors expected
    compile();
    assertErrors(errors);
  }

  /**
   * It is neither an error nor a warning if N is introduced by two or more imports but never
   * referred to.
   */
  public void test_importConflict_notUsed() throws Exception {
    prepare_importConflictAB();
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'A.dart';",
            "import 'B.dart';",
            "main() {",
            "}",
            ""));
    compile();
    assertErrors(errors);
  }
  
  public void test_importConflict_used_asTypeAnnotation() throws Exception {
    prepare_importConflictAB();
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'A.dart';",
            "import 'B.dart';",
            "typedef Test MyTypeDef(Test p);",
            "Test myFunction(Test p) {",
            "  Test test;",
            "}",
            ""));
    compile();
    assertErrors(
        errors,
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 5, 24, 4),
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 5, 9, 4),
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 6, 17, 4),
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 6, 1, 4),
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 7, 3, 4));
  }

  public void test_importConflict_used_notTypeAnnotation_1() throws Exception {
    prepare_importConflictAB();
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'A.dart';",
            "import 'B.dart';",
            "class A extends Test {}",
            "main() {",
            "}",
            ""));
    compile();
    assertErrors(
        errors,
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 5, 17, 4));
  }
  
  public void test_importConflict_used_notTypeAnnotation_2() throws Exception {
    prepare_importConflictAB();
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'A.dart';",
            "import 'B.dart';",
            "main() {",
            "  Test();",
            "  Test.FOO;",
            "  Test = 0;",
            "  0 is Test;",
            "}",
            ""));
    compile();
    assertErrors(
        errors,
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 6, 3, 4),
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 7, 3, 4),
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 8, 3, 4),
        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 9, 8, 4));
  }

  public void test_importConflict_used_notTypeAnnotation_3() throws Exception {
    prepare_importConflictAB();
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'A.dart' hide Test;",
            "import 'B.dart';",
            "class A extends Test {}",
            "main() {",
            "}",
            ""));
    compile();
    assertErrors(errors);
  }

  private void prepare_importConflictAB() {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library lib_a;",
            "class Test {}",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library lib_b;",
            "class Test {}",
            ""));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5735
   */
  public void test_importConflict_hideNoPrefix_importAgainWithPrefix() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library lib_a;",
            "var E = 2.7;",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library lib_b;",
            "export 'A.dart' show E;",
            "var E = 'E';",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'B.dart';",
            "import 'A.dart' as M show E;",
            "main() {",
            "  print(E);",
            "  print(M.E);",
            "}",
            ""));
    compile();
    assertErrors(errors);
  }

  public void test_reportMissingSource() throws Exception {
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library app;",
            "part 'noSuchUnit.dart';",
            ""));
    compile();
    // Check that errors where reported (and in correct time).
    assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 23));
  }
  
  public void test_reportMissingSource_withSchema_file() throws Exception {
    URI uri = new URI("file:noSuchSource.dart");
    Source source = new UrlSource(uri) {
      @Override
      public String getName() {
        return null;
      }
    };
    // should not cause exception
    assertFalse(source.exists());
  }
  
  public void test_reportMissingSource_withSchema_dart() throws Exception {
    URI uri = new URI("dart:noSuchSource");
    Source source = new UrlSource(uri, new PackageLibraryManager()) {
      @Override
      public String getName() {
        return null;
      }
    };
    // should not cause exception
    assertFalse(source.exists());
  }
  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3532
   */
  public void test_includeSameUnitTwice() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "part 'A.dart';",
            "part 'A.dart';",
            ""));
    // do compile, no errors expected
    compile();
    assertErrors(errors, errEx(DartCompilerErrorCode.UNIT_WAS_ALREADY_INCLUDED, 4, 1, 14));
  }

  /**
   * There was bug that we added <code>null</code> into {@link LibraryUnit#getImports()}. Here trick
   * is that we reference "existing" {@link Source}, which can not be read.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=2693
   */
  public void test_ignoreNullLibrary() throws Exception {
    appSource.setContent("canNotRead.dart", MemoryLibrarySource.IO_EXCEPTION_CONTENT);
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library app;",
            "import 'canNotRead.dart';",
            ""));
    // use same config as Editor - resolve despite of errors
    config = new DefaultCompilerConfiguration() {
      @Override
      public boolean resolveDespiteParseErrors() {
        return true;
      }
    };
    // Ignore errors, but we should not get exceptions.
    compile();
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4072
   */
  public void test_inaccessibleMethod_fromOtherLibrary_static() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            "class A {",
            "  static _privateStatic() {}",
            "}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart';",
            "main() {",
            "  A._privateStatic();",
            "}",
            ""));
    // do compile, check errors
    compile();
    assertErrors(
        errors,
        errEx(ResolverErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, 5, 5, 14));
  }
  
  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4072
   */
  public void test_inaccessibleMethod_fromOtherLibrary_instance() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            "class A {",
            "  _privateInstance() {}",
            "}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart';",
            "main() {",
            "  A a = new A();",
            "  a._privateInstance();",
            "}",
            ""));
    // do compile, check errors
    compile();
    assertErrors(
        errors,
        errEx(TypeErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, 6, 5, 16));
  }
  
  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3266
   */
  public void test_inaccessibleSuperMethod_fromOtherLibrary() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            "class A {",
            "  _method() {}",
            "}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart';",
            "class B extends A {",
            "  test1() {",
            "    _method();",
            "  }",
            "  test2() {",
            "    super._method();",
            "  }",
            "}",
            ""));
    // do compile, check errors
    compile();
    assertErrors(
        errors,
        errEx(ResolverErrorCode.CANNOT_ACCESS_METHOD, 6, 5, 7),
        errEx(ResolverErrorCode.CANNOT_ACCESS_METHOD, 9, 11, 7));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3340
   */
  public void test_useImportPrefix_asVariableName() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart' as prf;",
            "main() {",
            "  var prf;",
            "}",
            ""));
    // do compile, no errors expected
    compile();
    assertErrors(errors, errEx(ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, 5, 7, 3));
  }
  
  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3340
   */
  public void test_useImportPrefix_asTopLevelFieldName() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart' as prf;",
            "var prf;",
            "main() {",
            "}",
            ""));
    // do compile, no errors expected
    compile();
    assertErrors(errors, errEx(ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, 4, 5, 3));
  }

  public void test_newLibrarySyntax_show() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.A;",
            "class TypeA {}",
            "class TypeB {}",
            "class TypeC {}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'A.dart' as libA show TypeA, TypeB;",
            "main() {",
            "  libA.TypeA v1;",
            "  libA.TypeB v2;",
            "  libA.TypeC v3;",
            "}",
            ""));
    // TypeC not listed in "show"
    compile();
    assertErrors(errors, errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 10));
  }
  
  public void test_newLibrarySyntax_hide() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.A;",
            "class TypeA {}",
            "class TypeB {}",
            "class TypeC {}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'A.dart' as libA hide TypeC;",
            "main() {",
            "  libA.TypeA v1;",
            "  libA.TypeB v2;",
            "  libA.TypeC v3;",
            "}",
            ""));
    // TypeC is listed in "hide"
    compile();
    assertErrors(errors, errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 10));
  }

  public void test_newLibrarySyntax_export_show() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.A;",
            "class TypeAA {}",
            "class TypeAB {}",
            "class TypeAC {}",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.B;",
            "export 'A.dart' show TypeAA, TypeAB;",
            "class TypeBA {}",
            "class TypeBB {}",
            "class TypeBC {}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'B.dart' as libB hide TypeAA, TypeBB;",
            "main() {",
            "  libB.TypeAA aa;",
            "  libB.TypeAB ab;",
            "  libB.TypeAC ac;",
            "  libB.TypeBA ba;",
            "  libB.TypeBB bb;",
            "  libB.TypeBC bc;",
            "}",
            ""));
    compile();
    assertErrors(
        errors,
        errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 9, 3, 11));
    assertTrue(errors.toString().contains("libB.TypeAA"));
    assertTrue(errors.toString().contains("libB.TypeAC"));
    assertTrue(errors.toString().contains("libB.TypeBB"));
  }
  
  public void test_newLibrarySyntax_export2() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library libA;",
            "class SourceString {}",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library libB;",
            "import 'C.dart';",
            "export 'A.dart' show SourceString;",
            ""));
    appSource.setContent(
        "C.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library libC;",
            "import 'B.dart';",
            "foo() {",
            "  SourceString s;",
            "}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library app;",
            "import 'B.dart';",
            ""));
    compile();
    assertErrors(errors);
  }

  public void test_newLibrarySyntax_export3() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library libA;",
            "class SourceString {}",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library libB;",
            "export 'C.dart';",
            "export 'A.dart' show SourceString;",
            ""));
    appSource.setContent(
        "C.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library libC;",
            "import 'B.dart';",
            "foo() {",
            "  SourceString s;",
            "}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library app;",
            "import 'B.dart';",
            ""));
    compile();
    assertErrors(errors);
  }
  
  public void test_newLibrarySyntax_export4() throws Exception {
    appSource.setContent(
        "p1.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library lib1;",
            "export 'p3.dart';",
            ""));
    appSource.setContent(
        "p2.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library lib2;",
            "export 'p3.dart';",
            ""));
    appSource.setContent(
        "p3.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library lib3;",
            "class MyClass {}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library app;",
            "import 'p1.dart' hide MyClass;",
            "import 'p2.dart';",
            "MyClass topLevelField;",
            ""));
    compile();
    assertErrors(errors);
  }
  
  public void test_newLibrarySyntax_export_hide() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.A;",
            "class TypeAA {}",
            "class TypeAB {}",
            "class TypeAC {}",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.B;",
            "export 'A.dart' hide TypeAC;",
            "class TypeBA {}",
            "class TypeBB {}",
            "class TypeBC {}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'B.dart' as libB hide TypeAA, TypeBB;",
            "main() {",
            "  libB.TypeAA aa;",
            "  libB.TypeAB ab;",
            "  libB.TypeAC ac;",
            "  libB.TypeBA ba;",
            "  libB.TypeBB bb;",
            "  libB.TypeBC bc;",
            "}",
            ""));
    compile();
    assertErrors(
        errors,
        errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 9, 3, 11));
    assertTrue(errors.toString().contains("libB.TypeAA"));
    assertTrue(errors.toString().contains("libB.TypeAC"));
    assertTrue(errors.toString().contains("libB.TypeBB"));
  }
  
  public void test_newLibrarySyntax_noExport() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.A;",
            "class TypeAA {}",
            "class TypeAB {}",
            "class TypeAC {}",
            ""));
    appSource.setContent(
        "B.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.B;",
            "import 'A.dart' as libA;",
            "class TypeBA {}",
            "class TypeBB {}",
            "class TypeBC {}",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library test.app;",
            "import 'B.dart' as libB;",
            "main() {",
            "  libB.TypeAA aa;",
            "  libB.TypeAB ab;",
            "  libB.TypeAC ac;",
            "  libB.TypeBA ba;",
            "  libB.TypeBB bb;",
            "  libB.TypeBC bc;",
            "}",
            ""));
    compile();
    assertErrors(
        errors,
        errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 6, 3, 11),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11));
    assertTrue(errors.toString().contains("libB.TypeAA"));
    assertTrue(errors.toString().contains("libB.TypeAB"));
    assertTrue(errors.toString().contains("libB.TypeAC"));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4238
   */
  public void test_typesPropagation_html_query() throws Exception {
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'dart:html';",
            "main() {",
            "  var v1 = query('a');",
            "  var v2 = query('A');",
            "  var v3 = query('body:active');",
            "  var v4 = query('button[foo=\"bar\"]');",
            "  var v5 = query('div.class');",
            "  var v6 = query('input#id');",
            "  var v7 = query('select#id');",
            "  // invocation of method",
            "  var m1 = document.query('div');",
            "  // unsupported currently",
            "  var b1 = query('noSuchTag');",
            "  var b2 = query('DART_EDITOR_NO_SUCH_TYPE');",
            "  var b3 = query('body div');",
            "}",
            ""));
    // do compile, no errors expected
    compile();
    assertErrors(errors);
    // validate types
    DartUnit unit = units.get(APP);
    assertNotNull(unit);
    assertInferredElementTypeString(unit, "v1", "AnchorElement", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "v2", "AnchorElement", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "v3", "BodyElement", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "v4", "ButtonElement", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "v5", "DivElement", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "v6", "InputElement", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "v7", "SelectElement", TypeQuality.INFERRED);
    // invocation of method
    assertInferredElementTypeString(unit, "m1", "DivElement", TypeQuality.INFERRED);
    // bad cases, or unsupported now
    assertInferredElementTypeString(unit, "b1", "Element", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "b2", "Element", TypeQuality.INFERRED);
    assertInferredElementTypeString(unit, "b3", "Element", TypeQuality.INFERRED);
  }

  /**
   * Libraries "dart:io" and "dart:html" can not be used together in single application.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3839
   */
  public void test_consoleWebMix() throws Exception {
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'dart:io';",
            "import 'dart:html';",
            ""));
    // do compiled
    compile();
    // find expected error
    boolean found = false;
    for (DartCompilationError error : errors) {
      found |= error.getErrorCode() == DartCompilerErrorCode.CONSOLE_WEB_MIX;
    }
    assertTrue(found);
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3531
   */
  public void test_builtInIdentifier_asTypeAnnotation() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart' as abstract;",
            "import 'A.dart' as as;",
            "import 'A.dart' as dynamic;",
            "import 'A.dart' as export;",
            "import 'A.dart' as external;",
            "import 'A.dart' as factory;",
            "import 'A.dart' as get;",
            "import 'A.dart' as implements;",
            "import 'A.dart' as import;",
            "import 'A.dart' as library;",
            "import 'A.dart' as operator;",
            "import 'A.dart' as part;",
            "import 'A.dart' as set;",
            "import 'A.dart' as static;",
            "import 'A.dart' as typedef;",
            "main() {",
            "  var prf;",
            "}",
            ""));
    // do compile, no errors expected
    compile();
    {
      assertEquals(15, errors.size());
      for (DartCompilationError error : errors) {
        assertEquals(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_IMPORT_PREFIX, error.getErrorCode());
      }
    }
  }
  
  public void test_implicitlyImportCore() throws Exception {
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'dart:core';",
            ""));
    compile();
    ErrorExpectation.assertErrors(errors);
  }

  /**
   * Investigation of failing "language/ct_const4_test".
   */
  public void test_useConstFromLib() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            "final B = 1;",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "import 'A.dart' as mylib;",
            "final A = mylib.B;",
            ""));
    // do compile, no errors expected
    compile();
    assertErrors(errors);
  }

  /**
   * Part should have one and only one directive - "part of".
   */
  public void test_partDirectives_otherThenPartOf() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "part 'A.dart';",
            ""));
    // do compile
    compile();
    assertErrors(errors, errEx(DartCompilerErrorCode.ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT, 2, 1, 10));
  }
  
  /**
   * Part should have one and only one directive - "part of".
   */
  public void test_partDirectives_otherThenPartOf2() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of application;",
            "part 'A.dart';",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "part 'A.dart';",
            ""));
    // do compile
    compile();
    assertErrors(errors, errEx(DartCompilerErrorCode.ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT, 2, 1, 20));
  }
  
  /**
   * Part should have one and only one directive - "part of".
   */
  public void test_partDirectives_noPartOf() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "part 'A.dart';",
            ""));
    // do compile
    compile();
    assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_PART_OF_DIRECTIVE, -1, -1, 0));
  }
  
  /**
   * Part should have one and only one directive - "part of".
   */
  public void test_partDirectives_wrongNameInPartOf() throws Exception {
    appSource.setContent(
        "A.dart",
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "part of Z;",
            ""));
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library application;",
            "part 'A.dart';",
            ""));
    // do compile
    compile();
    assertErrors(
        errors,
        errEx(DartCompilerErrorCode.WRONG_PART_OF_NAME, 2, 1, 10),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 2, 9, 1));
  }

  /**
   * Internals of Dart use "dart-ext:" import scheme, and these libraries are allowed to use
   * "native". New import syntax.
   */
  public void test_useNative_withDartExt_new() throws Exception {
    appSource.setContent(
        APP,
        makeCode(
            "// filler filler filler filler filler filler filler filler filler filler filler",
            "library A;",
            "import 'dart-ext:test_extension';",
            "class A {",
            "  static int ifNull(a, b) native 'TestExtension_IfNull';",
            "}",
            ""));
    // do compile, no errors expected
    compile();
    assertErrors(errors);
  }
  
  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6077
   */
  public void test_dartMirrors_notFullyImplemented() throws Exception {
    appSource.setContent(
        APP,
        makeCode("// filler filler filler filler filler filler filler filler filler filler filler",
            "import 'dart:mirrors';"));
    // do compile, no errors expected
    compile();
    assertErrors(errors, errEx(DartCompilerErrorCode.MIRRORS_NOT_FULLY_IMPLEMENTED, 2, 1, 22));
  }

  private void assertAppBuilt() {
    didWrite(APP, EXTENSION_DEPS);
  }

  private void compile() {
    compile(appSource);
  }

  private void compile(LibrarySource lib) {
    try {
      provider.resetReadsAndWrites();
      errors.clear();
      DartCompilerListener listener = new DartCompilerListener.Empty() {
        Set<URI> compilingUris = Sets.newHashSet();

        @Override
        public void unitAboutToCompile(DartSource source, boolean diet) {
          compilingUris.add(source.getUri());
        }

        @Override
        public void onError(DartCompilationError event) {
          // Remember errors only between unitAboutToCompile/unitCompiled.
          Source source = event.getSource();
          if (source != null && compilingUris.contains(source.getUri())) {
            errors.add(event);
          }
        }

        @Override
        public void unitCompiled(DartUnit unit) {
          compilingUris.remove(unit.getSourceInfo().getSource().getUri());
          units.put(unit.getSourceName(), unit);
        }
      };
      DartCompiler.compileLib(lib, config, provider, listener);
    } catch (IOException e) {
      throw new AssertionFailedError("Unexpected IOException: " + e.getMessage());
    }
  }

  private void didWrite(String sourceName, String extension) {
    String spec = sourceName + "/" + extension;
    assertTrue("Expected write: " + spec, provider.writes.contains(spec));
  }

  private void didNotWrite(String sourceName, String extension) {
    String spec = sourceName + "/" + extension;
    assertFalse("Didn't expect write: " + spec, provider.writes.contains(spec));
  }
}
