// 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.type;

import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
import com.google.dart.compiler.CompilerTestCase;
import com.google.dart.compiler.DartCompilationError;
import com.google.dart.compiler.DartCompilerErrorCode;
import com.google.dart.compiler.DefaultCompilerConfiguration;
import com.google.dart.compiler.ast.ASTVisitor;
import com.google.dart.compiler.ast.DartArrayAccess;
import com.google.dart.compiler.ast.DartBinaryExpression;
import com.google.dart.compiler.ast.DartClass;
import com.google.dart.compiler.ast.DartCommentNewName;
import com.google.dart.compiler.ast.DartCommentRefName;
import com.google.dart.compiler.ast.DartDeclaration;
import com.google.dart.compiler.ast.DartExprStmt;
import com.google.dart.compiler.ast.DartExpression;
import com.google.dart.compiler.ast.DartField;
import com.google.dart.compiler.ast.DartFieldDefinition;
import com.google.dart.compiler.ast.DartForInStatement;
import com.google.dart.compiler.ast.DartFunctionExpression;
import com.google.dart.compiler.ast.DartIdentifier;
import com.google.dart.compiler.ast.DartInvocation;
import com.google.dart.compiler.ast.DartMapLiteralEntry;
import com.google.dart.compiler.ast.DartMethodDefinition;
import com.google.dart.compiler.ast.DartMethodInvocation;
import com.google.dart.compiler.ast.DartNewExpression;
import com.google.dart.compiler.ast.DartNode;
import com.google.dart.compiler.ast.DartPropertyAccess;
import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
import com.google.dart.compiler.ast.DartTypeNode;
import com.google.dart.compiler.ast.DartUnaryExpression;
import com.google.dart.compiler.ast.DartUnit;
import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
import com.google.dart.compiler.parser.ParserErrorCode;
import com.google.dart.compiler.resolver.ClassElement;
import com.google.dart.compiler.resolver.ConstructorElement;
import com.google.dart.compiler.resolver.ConstructorNodeElement;
import com.google.dart.compiler.resolver.Element;
import com.google.dart.compiler.resolver.ElementKind;
import com.google.dart.compiler.resolver.EnclosingElement;
import com.google.dart.compiler.resolver.FieldElement;
import com.google.dart.compiler.resolver.LibraryElement;
import com.google.dart.compiler.resolver.MethodElement;
import com.google.dart.compiler.resolver.ResolverErrorCode;
import com.google.dart.compiler.resolver.TypeErrorCode;
import com.google.dart.compiler.resolver.VariableElement;

import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
import static com.google.dart.compiler.common.ErrorExpectation.errEx;
import static com.google.dart.compiler.type.TypeQuality.EXACT;
import static com.google.dart.compiler.type.TypeQuality.INFERRED;
import static com.google.dart.compiler.type.TypeQuality.INFERRED_EXACT;

import java.net.URI;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Variant of {@link TypeAnalyzerTest}, which is based on {@link CompilerTestCase}. It is probably
 * slower, not actually unit test, but easier to use if you need access to DartNode's.
 */
public class TypeAnalyzerCompilerTest extends CompilerTestCase {

  /**
   * Top-level "main" function should not have parameters.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3271
   */
  public void test_topLevelMainFunction() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main(var p) {}",
        "class A {",
        "  main(var p) {}",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.MAIN_FUNCTION_PARAMETERS, 2, 1, 4));
  }

  /**
   * A setter definition that is prefixed with the static modifier defines a static setter.
   * Otherwise, it defines an instance setter. The name of a setter is obtained by appending the
   * string `=' to the identifier given in its signature.
   * <p>
   * Hence, a setter name can never conflict with, override or be overridden by a getter or method.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5153
   */
  public void test_setterNameImplicitEquals() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  set foo(x) {}",
        "  foo(x) {}",
        "}",
        "main() {",
        "  A a = new A();",
        "  a.foo = 0;",
        "  a.foo(0);",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4785
   */
  public void test_labelForBlockInSwitchCase() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  switch (0) {",
        "    case 0: qwerty: {",
        "      break qwerty;",
        "    }",
        "    break;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * We should support resolving to the method "call".
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=1355
   */
  public void test_resolveCallMethod() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  call() => 42;",
        "}",
        "main() {",
        "  A a = new A();",
        "  a();",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    // find a()
    DartIdentifier aVar = findNode(DartIdentifier.class, "a()");
    assertNotNull(aVar);
    DartUnqualifiedInvocation invocation = (DartUnqualifiedInvocation) aVar.getParent();
    // analyze a() element
    MethodElement element = (MethodElement) invocation.getElement();
    assertNotNull(element);
    assertEquals("call", element.getName());
    assertEquals(
        libraryResult.source.indexOf("call() => 42"),
        element.getNameLocation().getOffset());
  }

  /**
   * If a type I includes a method named call(), and the type of call() is the function type F, then
   * I is considered to be a subtype of F.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=7271
   */
  public void test_classWithCallMethod_isFunction() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class X {",
        "  call() => 42;",
        "}",
        "",
        "class Y {",
        "  call(int x) => 87;",
        "}",
        "",
        "typedef F(int x);",
        "typedef G(String y);",
        "",
        "main() {",
        "  X x = new X();",
        "  Y y = new Y();",
        "  Function f = x;", // OK
        "  Function g = y;", // OK
        "  F f0 = x;", // WARN
        "  F f1 = y;", // OK
        "  G g0 = x;", // WARN
        "  G g1 = y;", // WARN
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 18, 10, 1),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 20, 10, 1),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 21, 10, 1));
  }

  /**
   * It is a compile-time error if a typedef refers to itself via a chain of references that does
   * not include a class or interface type.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3534
   */
  public void test_functionTypeAlias_selfRerences_direct() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "typedef A A();",
        "typedef B(B b);",
        "typedef C([C c]);",
        "typedef D({D d});",
        "typedef E<T extends E>();",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 2, 1, 14),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 3, 1, 15),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 4, 1, 17),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 5, 1, 17),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 6, 1, 25));
  }

  /**
   * It is a compile-time error if a typedef refers to itself via a chain of references that does
   * not include a class or interface type.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3534
   */
  public void test_functionTypeAlias_selfRerences_indirect() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "typedef B1 A1();",
        "typedef A1 B1();",
        "typedef B2 A2();",
        "typedef B2(A2 a);",
        "typedef B3 A3();",
        "typedef B3([A3 a]);",
        "typedef B4 A4();",
        "typedef B4({A4 a});",
        "typedef A5<T extends B5>();",
        "typedef B5(A5 a);",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 2, 1, 16),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 3, 1, 16),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 4, 1, 16),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 5, 1, 17),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 6, 1, 16),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 7, 1, 19),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1, 16),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 9, 1, 19),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 10, 1, 27),
        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 11, 1, 17));
  }

  /**
   * Type parameters should not conflict with formal parameters.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5302
   */
  public void test_functionTypeAlias_typePaarameter_scope() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "typedef f<f>(f);",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * It is a compile-time error if initializer list contains an initializer for a variable that
   * is not an instance variable declared in the immediately surrounding class.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3181
   */
  public void test_initializerForNotField() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "var x;",
        "class A {",
        "  A() : x = 5 {}",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.INIT_FIELD_ONLY_IMMEDIATELY_SURROUNDING_CLASS, 4, 9, 1));
  }

  /**
   * Tests that we correctly provide {@link Element#getEnclosingElement()} for method of class.
   */
  public void test_resolveClassMethod() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "class Object {}",
                "class Test {",
                "  foo() {",
                "    f();",
                "  }",
                "  f() {",
                "  }",
                "}");
    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
    // find f() invocation
    DartInvocation invocation = findInvocationSimple(unit, "f()");
    assertNotNull(invocation);
    // referenced Element should be resolved to MethodElement
    Element methodElement = invocation.getElement();
    assertNotNull(methodElement);
    assertSame(ElementKind.METHOD, methodElement.getKind());
    assertEquals("f", ((MethodElement) methodElement).getOriginalName());
    // enclosing Element of MethodElement is ClassElement
    Element classElement = methodElement.getEnclosingElement();
    assertNotNull(classElement);
    assertSame(ElementKind.CLASS, classElement.getKind());
    assertEquals("Test", ((ClassElement) classElement).getOriginalName());
  }

  /**
   * Test that local {@link DartFunctionExpression} has {@link Element} with enclosing
   * {@link Element}.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=145
   */
  public void test_resolveLocalFunction() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "class Object {}",
            "class Test {",
            "  foo() {",
            "    f() {",
            "    }",
            "    f();",
            "  }",
            "}");
    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
    // find f() invocation
    DartInvocation invocation = findInvocationSimple(unit, "f()");
    assertNotNull(invocation);
    // referenced Element should be resolved to MethodElement
    Element functionElement = invocation.getElement();
    assertNotNull(functionElement);
    assertSame(ElementKind.FUNCTION_OBJECT, functionElement.getKind());
    assertEquals("f", ((MethodElement) functionElement).getOriginalName());
    // enclosing Element of this FUNCTION_OBJECT is enclosing method
    MethodElement methodElement = (MethodElement) functionElement.getEnclosingElement();
    assertNotNull(methodElement);
    assertSame(ElementKind.METHOD, methodElement.getKind());
    assertEquals("foo", methodElement.getName());
    // use EnclosingElement methods implementations in MethodElement
    assertEquals(false, methodElement.isInterface());
    assertEquals(true, Iterables.isEmpty(methodElement.getMembers()));
    assertEquals(null, methodElement.lookupLocalElement("f"));
  }

  /**
   * It is a static warning if the type of "switch expression" may not be assigned to the type of
   * "case expression".
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3269
   */
  public void test_switchExpression_case_switchTypeMismatch() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  int v = 1;",
        "  switch (v) {",
        "    case 0: break;",
        "  }",
        "  switch (v) {",
        "    case 'a': break;",
        "  }",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 8, 10, 3));
  }

  /**
   * It is a compile-time error if the values of the case expressions are not compile-time
   * constants.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4553
   */
  public void test_switchExpression_case_anyConst() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  const A();",
        "}",
        "const A CONST_1 = const A();",
        "const A CONST_2 = const A();",
        "foo(var v) {",
        "  switch (v) {",
        "    case 0: break;",
        "  }",
        "  switch (v) {",
        "    case '0': break;",
        "  }",
        "  switch (v) {",
        "    case 0.0: break;",
        "  }",
        "  switch (v) {",
        "    case CONST_1: break;",
        "    case CONST_2: break;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * It is a compile-time error if the values of the case expressions are not compile-time
   * constants.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4553
   */
  public void test_switchExpression_case_notConst() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "foo(var v) {",
        "  A notConst = new A();",
        "  switch (v) {",
        "    case notConst: break;",
        "  }",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 6, 10, 8));
  }

  /**
   * It is a compile-time error if the class C implements the operator ==.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4553
   */
  public void test_switchExpression_case_hasOperatorEquals() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {",
        "  const C();",
        "  operator ==(other) => false;",
        "}",
        "const C CONST = const C();",
        "foo(var v) {",
        "  switch (v) {",
        "    case CONST: break;",
        "  }",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CASE_EXPRESSION_TYPE_SHOULD_NOT_HAVE_EQUALS, 9, 10, 5));
  }

  /**
   * It is a compile-time error if the values of the case expressions do not all have the same type.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3528
   */
  public void test_switchExpression_case_differentTypes() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "foo(var v) {",
        "  switch (v) {",
        "    case 0: break;",
        "    case 'a': break;",
        "  }",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CASE_EXPRESSIONS_SHOULD_BE_SAME_TYPE, 5, 10, 3));
  }

  public void test_switchExpression_case_constLocalVariable() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "foo(var v) {",
        "  const int VALUE = 0;",
        "  switch (v) {",
        "    case VALUE: break;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=2862
   */
  public void test_switchCase_fallThrough() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "foo(int x) {",
        "  while (true) {",
        "    switch (x) {",
        "      case 0:",
        "        break;",
        "      case 1:",
        "        continue;",
        "      case 2:",
        "        return;",
        "      case 3:",
        "        throw new Exception();",
        "      case 4:",
        "        bar();",
        "      default:",
        "        bar();",
        "    }",
        "  }",
        "}",
        "bar() {}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.SWITCH_CASE_FALL_THROUGH, 14, 9, 6));
  }

  /**
   * Language specification requires that factory should be declared in class. However declaring
   * factory on top level should not cause exceptions in compiler.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=345
   */
  public void test_badTopLevelFactory() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary("factory foo() {}");
    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
    DartMethodDefinition factory = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
    assertNotNull(factory);
    // this factory has name, which is allowed for normal method
    assertEquals(true, factory.getName() instanceof DartIdentifier);
    assertEquals("foo", ((DartIdentifier) factory.getName()).getName());
    // compilation error expected
    assertBadTopLevelFactoryError(libraryResult);
  }

  /**
   * Asserts that given {@link AnalyzeLibraryResult} contains {@link DartCompilationError} for
   * invalid factory on top level.
   */
  private void assertBadTopLevelFactoryError(AnalyzeLibraryResult libraryResult) {
    List<DartCompilationError> compilationErrors = libraryResult.getCompilationErrors();
    assertEquals(1, compilationErrors.size());
    DartCompilationError compilationError = compilationErrors.get(0);
    assertEquals(ParserErrorCode.FACTORY_CANNOT_BE_TOP_LEVEL, compilationError.getErrorCode());
    assertEquals(1, compilationError.getLineNumber());
    assertEquals(1, compilationError.getColumnNumber());
    assertEquals("factory".length(), compilationError.getLength());
  }

  /**
   * @return the {@link DartInvocation} with given source. This is inaccurate approach, but good
   *         enough for specific tests.
   */
  private static DartInvocation findInvocationSimple(DartNode rootNode,
      final String invocationString) {
    final DartInvocation invocationRef[] = new DartInvocation[1];
    rootNode.accept(new ASTVisitor<Void>() {
      @Override
      public Void visitInvocation(DartInvocation node) {
        if (node.toSource().equals(invocationString)) {
          invocationRef[0] = node;
        }
        return super.visitInvocation(node);
      }
    });
    return invocationRef[0];
  }

  /**
   * In contrast, if A is intended to be concrete, the checker should warn about all unimplemented
   * methods, but allow clients to instantiate it freely.
   */
  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_method_fromInterface()
      throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "abstract class Foo {",
            "  int fooA;",
            "  void fooB();",
            "}",
            "abstract class Bar {",
            "  void barA();",
            "}",
            "class A implements Foo, Bar {",
            "}",
            "main() {",
            "  new A();",
            "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 8, 7, 1));
    {
      DartCompilationError typeError = libraryResult.getErrors().get(0);
      String message = typeError.getMessage();
      assertTrue(message.contains("# From Foo:"));
      assertTrue(message.contains("int fooA"));
      assertTrue(message.contains("void fooB()"));
      assertTrue(message.contains("# From Bar:"));
      assertTrue(message.contains("void barA()"));
    }
  }

  /**
   * In contrast, if A is intended to be concrete, the checker should warn about all unimplemented
   * methods, but allow clients to instantiate it freely.
   */
  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_method_inherited()
      throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "abstract class A {",
                "  void foo();",
                "}",
                "class B extends A {",
                "}",
                "main() {",
                "  new B();",
                "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 4, 7, 1));
    {
      DartCompilationError typeError = libraryResult.getErrors().get(0);
      String message = typeError.getMessage();
      assertTrue(message.contains("# From A:"));
      assertTrue(message.contains("void foo()"));
    }
  }

  /**
   * In contrast, if A is intended to be concrete, the checker should warn about all unimplemented
   * methods, but allow clients to instantiate it freely.
   */
  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_method_self()
      throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "class A {",
            "  void foo();",
            "}",
            "main() {",
            "  new A();",
            "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
    {
      DartCompilationError typeError = libraryResult.getErrors().get(0);
      String message = typeError.getMessage();
      assertTrue(message.contains("# From A:"));
      assertTrue(message.contains("void foo()"));
    }
  }

  /**
   * When class implements "noSuchMethod", we presume that it will handle unimplemented methods.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6964
   */
  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplementedMethod_noSuchMethod()
      throws Exception {
    // report by default
    {
      AnalyzeLibraryResult libraryResult =
          analyzeLibrary(
              "class A {",
              "  void foo();",
              "  noSuchMethod(Invocation m) {}",
              "}",
              "main() {",
              "  new A();",
              "}");
      assertErrors(
          libraryResult.getErrors(),
          errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
    }
    // disable warnings if has "noSuchMethod"
    {
      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
        @Override
        public boolean reportNoMemberWhenHasInterceptor() {
          return false;
        }
      });
      AnalyzeLibraryResult libraryResult =
          analyzeLibrary(
              "class A {",
              "  void foo();",
              "  noSuchMethod(Invocation m) {}",
              "}",
              "main() {",
              "  new A();",
              "}");
      assertErrors(libraryResult.getErrors());
    }
  }

  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_getter()
      throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "class A {",
                "  get x;",
                "}",
                "main() {",
                "  new A();",
                "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
  }

  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_mixin() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "abstract class A {",
        "  foo();",
        "}",
        "class B extends Object with A {",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 5, 7, 1));
  }

  /**
   * Class "B" has implementation for "bVal" and "bVal=", so we don't need any warning.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=7605
   */
  public void test_warnAbstract_onConcreteClassDeclaration_inheritedGetter_abstractGetter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "abstract class A {",
        "  get bVal {}",
        "  set bVal(var val);",
        "}",
        "class B extends A {",
        "  set bVal(var val) {}",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * There was bug that implementing setter still caused warning.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5327
   */
  public void test_warnAbstract_whenInstantiate_implementSetter() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "abstract class I {",
        "  set foo(x);",
        "}",
        "class A implements I {",
        "  set foo(x) {}",
        "}",
        "main() {",
        "  new A();",
        "}");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * When both getter and setter were abstract and only getter implemented, we should report error.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5327
   */
  public void test_warnAbstract_whenInstantiate_implementsOnlyGetter() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "abstract class I {",
        "  get foo;",
        "  set foo(x);",
        "}",
        "class A implements I {",
        "  get foo => 0;",
        "}",
        "main() {",
        "  new A();",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 5, 7, 1));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5327
   */
  public void test_warnAbstract_whenInstantiate_implementsSetter_inSuperClass() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "abstract class I {",
        "  get foo;",
        "  set foo(x);",
        "}",
        "abstract class A implements I {",
        "  get foo;",
        "  set foo(x) {}",
        "}",
        "class B extends A {",
        "  get foo => 0;",
        "}",
        "main() {",
        "  new B();",
        "}");
    assertErrors(libraryResult.getErrors());
  }

  public void test_warnAbstract_onAbstractClass_whenInstantiate_normalConstructor()
      throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "abstract class A {",
            "  void bar();",
            "}",
            "main() {",
            "  new A();",
            "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 5, 7, 1));
  }

  /**
   * Factory constructor can instantiate any class and return it non-abstract class instance, Even
   * thought this is an abstract class, there should be no warnings for the invocation of the
   * factory constructor.
   */
  public void test_warnAbstract_onAbstractClass_whenInstantiate_factoryConstructor()
      throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "abstract class A {", // explicitly abstract
        "  factory A() {",
        "    return null;",
        "  }",
        "}",
        "class C {",
        "  foo() {",
        "    return new A();", // no error - factory constructor
        "  }",
        "}");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * Factory constructor can instantiate any class and return it non-abstract class instance, Even
   * thought this is an abstract class, there should be no warnings for the invocation of the
   * factory constructor.
   */
  public void test_wanrAbstract_onAbstractClass_whenInstantiate_factoryConstructor2()
      throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "abstract class A {", // class is abstract
            "  factory A() {",
            "    return null;",
            "  }",
            "  method();",
            "}",
            "class C {",
            "  foo() {",
            "    return new A();",  // no error, factory constructor
            "  }",
            "}");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * Spec 7.3 It is a static warning if a setter declares a return type other than void.
   */
  public void testWarnOnNonVoidSetter() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "class A {",
                "  void set foo(bool a) {}",
                "  set bar(bool a) {}",
                "  dynamic set baz(bool a) {}",
                "  bool set bob(bool a) {}",
                "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.SETTER_RETURN_TYPE, 4, 3, 7),
        errEx(TypeErrorCode.SETTER_RETURN_TYPE, 5, 3, 4));
  }

  public void test_callUnknownFunction() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  foo();",
        "}",
        "");
    assertErrors(libraryResult.getErrors(), errEx(ResolverErrorCode.CANNOT_RESOLVE_METHOD, 3, 3, 3));
  }

  /**
   * We should be able to call <code>Function</code> even if it is in the field.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=933
   */
  public void test_callFunctionFromField() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "class WorkElement {",
            "  Function run;",
            "}",
            "foo(WorkElement e) {",
            "  e.run();",
            "}");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * When we attempt to use function as type, we should report only one error.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3309
   */
  public void test_useFunctionAsType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "func() {}",
        "main() {",
        "  new func();",
        "}",
        "");
    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.NOT_A_TYPE, 4, 7, 4));
  }

  /**
   * There was problem that {@link DartForInStatement} visits "iterable" two times. At first time we
   * set {@link MethodElement}, because we resolve it to getter. However because of this at second
   * time we can not resolve. Solution - don't try to resolve second time, we already done at first
   * time. Note: double getter is important.
   */
  public void test_doubleGetterAccess_inForEach() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
            "class Test {",
            "  Iterable get iter {}",
            "}",
            "Test get test {}",
            "f() {",
            "  for (var v in test.iter) {}",
            "}",
            "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * Test for errors and warnings related to positional and named arguments for required and
   * optional parameters.
   */
  public void test_invocationArguments() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "/* 01 */ foo() {",
                "/* 02 */   f_0_0();",
                "/* 03 */   f_0_0(-1);",
                "/* 04 */",
                "/* 05 */   f_1_0();",
                "/* 06 */   f_1_0(-1);",
                "/* 07 */   f_1_0(-1, -2, -3);",
                "/* 08 */",
                "/* 09 */   f_2_0();",
                "/* 10 */",
                "/* 11 */   f_0_1();",
                "/* 12 */   f_0_1(1);",
                "/* 13 */   f_0_1(0, 0);",
                "/* 14 */   f_0_1(n1: 1);",
                "/* 15 */   f_0_1(x: 1);",
                "/* 16 */   f_0_1(n1: 1, n1: 2);",
                "}",
                "",
                "f_0_0() {}",
                "f_1_0(r1) {}",
                "f_2_0(r1, r2) {}",
                "f_0_1({n1}) {}",
                "f_0_2({n1, n2}) {}",
                "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.EXTRA_ARGUMENT, 3, 18, 2),
        errEx(TypeErrorCode.MISSING_ARGUMENT, 5, 12, 5),
        errEx(TypeErrorCode.EXTRA_ARGUMENT, 7, 22, 2),
        errEx(TypeErrorCode.EXTRA_ARGUMENT, 7, 26, 2),
        errEx(TypeErrorCode.MISSING_ARGUMENT, 9, 12, 5),
        errEx(TypeErrorCode.EXTRA_ARGUMENT, 12, 18, 1),
        errEx(TypeErrorCode.EXTRA_ARGUMENT, 13, 18, 1),
        errEx(TypeErrorCode.EXTRA_ARGUMENT, 13, 21, 1),
        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 15, 18, 4),
        errEx(ResolverErrorCode.DUPLICATE_NAMED_ARGUMENT, 16, 25, 5));
  }

  /**
   * Test that optional positional and named parameters are handled separately.
   */
  public void test_invocationArguments2() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "func([int np1, int np2, int np3]) {}",
        "main() {",
        "  func(np1: 1, np2: 2, np3: 2);",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 8, 6),
        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 16, 6),
        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 24, 6));
  }

  /**
   * We should return correct {@link Type} for {@link DartNewExpression}.
   */
  public void test_DartNewExpression_getType() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {",
            "  A() {}",
            "  A.foo() {}",
            "}",
            "var a1 = new A();",
            "var a2 = new A.foo();",
            "");
    assertErrors(libraryResult.getErrors());
    // new A()
    {
      DartNewExpression newExpression = (DartNewExpression) getTopLevelFieldInitializer(testUnit, 1);
      Type newType = newExpression.getType();
      assertEquals("A", newType.getElement().getName());
    }
    // new A.foo()
    {
      DartNewExpression newExpression = (DartNewExpression) getTopLevelFieldInitializer(testUnit, 2);
      Type newType = newExpression.getType();
      assertEquals("A", newType.getElement().getName());
    }
  }

  /**
   * Expects that given {@link DartUnit} has {@link DartFieldDefinition} as <code>index</code> top
   * level node and return initializer of first {@link DartField}.
   */
  private static DartExpression getTopLevelFieldInitializer(DartUnit unit, int index) {
    DartFieldDefinition fieldDefinition = (DartFieldDefinition) unit.getTopLevelNodes().get(index);
    DartField field = fieldDefinition.getFields().get(0);
    return field.getValue();
  }

  /**
   * If property has only setter, no getter, then attempt to use getter should cause static type
   * warning.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=1251
   */
  public void test_setterOnlyProperty_noGetter() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "class SetOnly {",
            "  set foo(arg) {}",
            "}",
            "class SetOnlyWrapper {",
            "  SetOnly setOnly;",
            "}",
            "",
            "main() {",
            "  SetOnly setOnly = new SetOnly();",
            "  setOnly.foo = 1;", // 10: OK, use setter
            "  setOnly.foo += 2;", // 11: ERR, no getter
            "  print(setOnly.foo);", // 12: ERR, no getter
            "  var bar;",
            "  bar = setOnly.foo;", // 14: ERR, assignment, but we are not LHS
            "  bar = new SetOnlyWrapper().setOnly.foo;", // 15: ERR, even in chained expression
            "  new SetOnlyWrapper().setOnly.foo = 3;", // 16: OK
            "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 11, 11, 3),
        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 12, 17, 3),
        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 14, 17, 3),
        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 15, 38, 3));
  }

  public void test_setterOnlyProperty_normalField() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
            "class A {",
            "  var foo;",
            "}",
            "",
            "main() {",
            "  A a = new A();",
            "  a.foo = 1;",
            "  a.foo += 2;",
            "  print(a.foo);",
            "}");
    assertErrors(libraryResult.getErrors());
  }

  public void test_setterOnlyProperty_getterInSuper() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "class A {",
                "  get foo {}",
                "}",
                "class B extends A {",
                "  set foo(arg) {}",
                "}",
                "",
                "main() {",
                "  B b = new B();",
                "  b.foo = 1;",
                "  b.foo += 2;",
                "  print(b.foo);",
                "}");
    assertErrors(libraryResult.getErrors());
  }

  public void test_setterOnlyProperty_getterInInterface() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "abstract class A {",
                "  get foo {}",
                "}",
                "abstract class B implements A {",
                "  set foo(arg) {}",
                "}",
                "",
                "main() {",
                "  B b = new B();",
                "  b.foo = 1;",
                "  b.foo += 2;",
                "  print(b.foo);",
                "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 9, 13, 1));
  }

  public void test_getterOnlyProperty_noSetter() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "class GetOnly {",
                "  get foo {}",
                "}",
                "class GetOnlyWrapper {",
                "  GetOnly getOnly;",
                "}",
                "",
                "main() {",
                "  GetOnly getOnly = new GetOnly();",
                "  print(getOnly.foo);", // 10: OK, use getter
                "  getOnly.foo = 1;", // 11: ERR, no setter
                "  getOnly.foo += 2;", // 12: ERR, no setter
                "  var bar;",
                "  bar = getOnly.foo;", // 14: OK, use getter
                "  new GetOnlyWrapper().getOnly.foo = 3;", // 15: ERR, no setter
                "  bar = new GetOnlyWrapper().getOnly.foo;", // 16: OK, use getter
                "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 11, 11, 3),
        errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 12, 11, 3),
        errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 15, 32, 3));
  }

  public void test_getterOnlyProperty_setterInSuper() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "class A {",
                "  set foo(arg) {}",
                "}",
                "class B extends A {",
                "  get foo {}",
                "}",
                "",
                "main() {",
                "  B b = new B();",
                "  b.foo = 1;",
                "  b.foo += 2;",
                "  print(b.foo);",
                "}");
    assertErrors(libraryResult.getErrors());
  }

  public void test_getterOnlyProperty_setterInInterface() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "abstract class A {",
                "  set foo(arg) {}",
                "}",
                "abstract class B implements A {",
                "  get foo {}",
                "}",
                "",
                "main() {",
                "  B b = new B();",
                "  b.foo = 1;",
                "  b.foo += 2;",
                "  print(b.foo);",
                "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 9, 13, 1));
  }

  public void test_assert_notUserFunction() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  assert(true);",
        "  assert(false);",
        "  assert('message');", // not 'bool'
        "  assert('null');", // not 'bool'
        "  assert(0);", // not 'bool'
        "  assert(f1);", // OK, dynamic
        "  assert(f2);", // OK, '() -> bool'
        "  assert(f3);", // OK, 'Object' compatible with 'bool'
        "  assert(f4);", // not '() -> bool', return type
        "  assert(f5);", // not '() -> bool', parameter
        "  assert(true, false);", // not single argument
        "  assert;", // incomplete
        "}",
        "f1() {}",
        "bool f2() {}",
        "Object f3() {}",
        "String f4() {}",
        "bool f5(x) {}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ParserErrorCode.EXPECTED_TOKEN, 13, 10, 4),
        errEx(ParserErrorCode.EXPECTED_TOKEN, 14, 9, 1),
        errEx(TypeErrorCode.ASSERT_BOOL, 5, 10, 9),
        errEx(TypeErrorCode.ASSERT_BOOL, 6, 10, 6),
        errEx(TypeErrorCode.ASSERT_BOOL, 7, 10, 1),
        errEx(TypeErrorCode.ASSERT_BOOL, 11, 10, 2),
        errEx(TypeErrorCode.ASSERT_BOOL, 12, 10, 2));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3264
   */
  public void test_initializingFormalType_useFieldType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  final double f;",
        "  A(this.f);",
        "}",
        "class B {",
        "  B(this.f);",
        "  final double f;",
        "}",
        "",
        "main() {",
        "  new A('0');",
        "  new B('0');",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 12, 9, 3),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 13, 9, 3));
  }

  /**
   * If "this.field" parameter has declared type, it should be assignable to the field.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3264
   */
  public void test_initializingFormalType_compatilityWithFieldType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  final double f;",
        "  A.useDynamic(dynamic this.f);",
        "  A.useNum(num this.f);",
        "  A.useString(String this.f);",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 6, 15, 13));
  }

  public void test_finalField_inClass() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  final f = 0;",
        "}",
        "main() {",
        "  A a = new A();",
        "  a.f = 0;", // 6: ERR, is final
        "  a.f += 1;", // 7: ERR, is final
        "  print(a.f);", // 8: OK, can read
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.FIELD_IS_FINAL, 7, 5, 1),
        errEx(TypeErrorCode.FIELD_IS_FINAL, 8, 5, 1));
  }

  public void test_notFinalField() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var f;",
        "}",
        "main() {",
        "  A a = new A();",
        "  a.f = 0;", // 6: OK, field "f" is not final
        "  a.f += 1;", // 7: OK, field "f" is not final
        "  print(a.f);", // 8: OK, can read
        "}");
    assertErrors(libraryResult.getErrors());
  }

  public void test_constField() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const f = 1;",
        "class A {",
        "  const f = 1;",
        "  method() {",
        "    f = 2;",
        "    this.f = 2;",
        "  }",
        "}",
        "main() {",
        "  f = 2;",
        "  A a = new A();",
        "  a.f = 2;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 6, 5, 1),
        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 7, 5, 6),
        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 11, 3, 1),
        errEx(TypeErrorCode.FIELD_IS_FINAL, 13, 5, 1));
  }

  public void test_assignConst_topLevelVariable() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const f = 1;",
        "main() {",
        "  f = 2;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 4, 3, 1));
  }

  public void test_assignFinal_topLevelVariable() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "final f = 1;",
        "main() {",
        "  f = 2;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 4, 3, 1));
  }

  public void test_assignFinal_instanceVariable_inConstructor() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  final f = 1;",
        "  A() {",
        "    f = 2;",
        "    f += 3;",
        "    print(f);",
        "  }",
        "",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL_ERROR, 5, 5, 1),
        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL_ERROR, 6, 5, 1));
  }

  public void test_identicalFunction() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const A = 1;",
        "const B = 2;",
        "const C = identical(A, B);",
        "const D = !identical(A, B);",
        "");
    assertErrors(libraryResult.getErrors());
  }

  public void test_constantEvaluationException_divZero() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const C1 = 1 ~/ 0;",
        "const C2 = 1 % 0;",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CONSTANTS_EVALUATION_EXCEPTION, 2, 12, 6),
        errEx(ResolverErrorCode.CONSTANTS_EVALUATION_EXCEPTION, 3, 12, 5));
  }

  /**
   * It is a compile-time error to use type variables in "const" instance creation.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=2379
   */
  public void test_constInstantiation_withTypeVariable() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> {",
        "  const A();",
        "  const A.name();",
        "}",
        "class B<U> {",
        "  test() {",
        "    const A<U>();",
        "    const A<U>.name();",
        "  }",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CONST_WITH_TYPE_VARIABLE, 8, 13, 1),
        errEx(ResolverErrorCode.CONST_WITH_TYPE_VARIABLE, 9, 13, 1));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3182
   */
  public void test_extendNotType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "int A;",
        "class B extends A {",
        "}",
        "",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.NOT_A_TYPE, 3, 17, 1));
  }

  public void test_constInstanceCreation_noSuchType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  const NoSuchType();",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.NO_SUCH_TYPE_CONST, 3, 9, 10));
  }

  public void test_constInstanceCreation_noSuchConstructor() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "main() {",
        "  const A.noSuchName();",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.NEW_EXPRESSION_NOT_CONST_CONSTRUCTOR, 4, 11, 10));
  }

  public void test_constInstanceCreation_notType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "var notType;",
        "main() {",
        "  const notType();",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.NOT_A_TYPE, 4, 9, 7));
  }

  /**
   * Test for variants of {@link DartMethodDefinition} return types.
   */
  public void test_methodReturnTypes() throws Exception {
    AnalyzeLibraryResult libraryResult =
        analyzeLibrary(
                "// filler filler filler filler filler filler filler filler filler filler",
                "int fA() {}",
                "dynamic fB() {}",
                "void fC() {}",
                "fD() {}",
                "");
    assertErrors(libraryResult.getErrors());
    {
      DartMethodDefinition fA = (DartMethodDefinition) testUnit.getTopLevelNodes().get(0);
      assertEquals("int", fA.getElement().getReturnType().getElement().getName());
    }
    {
      DartMethodDefinition fB = (DartMethodDefinition) testUnit.getTopLevelNodes().get(1);
      assertEquals("dynamic", fB.getElement().getReturnType().getElement().getName());
    }
    {
      DartMethodDefinition fC = (DartMethodDefinition) testUnit.getTopLevelNodes().get(2);
      assertEquals("void", fC.getElement().getReturnType().getElement().getName());
    }
    {
      DartMethodDefinition fD = (DartMethodDefinition) testUnit.getTopLevelNodes().get(3);
      assertEquals("dynamic", fD.getElement().getReturnType().getElement().getName());
    }
  }

  public void test_bindToLibraryFunctionFirst() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "foo() {}",
        "class A {",
        " foo() {}",
        "}",
        "class B extends A {",
        "  bar() {",
        "    foo();",
        "  }",
        "}",
        "");
    // Find foo() invocation.
    DartUnqualifiedInvocation invocation;
    {
      DartClass classB = (DartClass) testUnit.getTopLevelNodes().get(2);
      DartMethodDefinition methodBar = (DartMethodDefinition) classB.getMembers().get(0);
      DartExprStmt stmt = (DartExprStmt) methodBar.getFunction().getBody().getStatements().get(0);
      invocation = (DartUnqualifiedInvocation) stmt.getExpression();
    }
    // Check that unqualified foo() invocation is resolved to the top-level (library) function.
    Element element = invocation.getTarget().getElement();
    assertNotNull(element);
    assertTrue(element.getEnclosingElement() instanceof LibraryElement);
  }

  /**
   * If there was <code>import</code> with invalid {@link URI}, it should be reported as error, not
   * as an exception.
   */
  public void test_invalidImportUri() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "library test;",
        "import 'badURI';",
        "");
    assertErrors(libraryResult.getErrors(), errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 16));
  }

  /**
   * If there was <code>part</code> with invalid {@link URI}, it should be reported as error, not
   * as an exception.
   */
  public void test_invalidSourceUri() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "library test;",
        "part 'badURI';",
        "");
    assertErrors(libraryResult.getErrors(), errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 14));
  }

  public void test_mapLiteralKeysUnique() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "var m = {'a' : 0, 'b': 1, 'a': 2};",
        "");
    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.MAP_LITERAL_KEY_UNIQUE, 2, 27, 3));
  }

  /**
   * No required parameter "x".
   */
  public void test_implementsAndOverrides_noRequiredParameter() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "abstract class I {",
            "  foo(x);",
            "}",
            "class C implements I {",
            "  foo() {}",
            "}");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS, 5, 3, 3));
  }

  /**
   * It is OK to add more named parameters, if list prefix is same as in "super".
   */
  public void test_implementsAndOverrides_additionalNamedParameter() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "abstract class I {",
            "  foo({x});",
            "}",
            "class C implements I {",
            "  foo({x,y}) {}",
            "}");
    assertErrors(result.getErrors());
  }

  public void test_implementsAndOverrides_lessNamedParameter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "abstract class A {",
        "  foo({x, y});",
        "}",
        "abstract class B extends A {",
        "  foo({x});",
        "}");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, 5, 3, 3));
  }

  /**
   * We override "foo" with method that has named parameter. So, this method is not abstract and
   * class is not abstract too, so no warning.
   */
  public void test_implementsAndOverrides_additionalNamedParameter_notAbstract() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "abstract class A {",
            "  foo();",
            "}",
            "class B extends A {",
            "  foo({x}) {}",
            "}",
            "bar() {",
            "  new B();",
            "}",
            "");
    assertErrors(result.getErrors());
  }

  public void test_implementsAndOverrides_lessOptionalPositionalParameter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "abstract class A {",
        "  foo([x, y]);",
        "}",
        "abstract class B extends A {",
        "  foo([x]);",
        "}");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_OPTIONAL_PARAMS, 5, 3, 3));
  }

  public void test_implementsAndOverrides_moreOptionalPositionalParameter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "abstract class A {",
        "  foo([x]);",
        "}",
        "abstract class B extends A {",
        "  foo([a, b]);",
        "}");
    assertErrors(result.getErrors());
  }

  /**
   * No required parameter "x". Named parameter "x" is not enough.
   */
  public void test_implementsAndOverrides_extraRequiredParameter() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "abstract class I {",
            "  foo();",
            "}",
            "class C implements I {",
            "  foo(x) {}",
            "}");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS, 5, 3, 3));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3183
   */
  public void test_implementsAndOverrides_differentDefaultValue_optional() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {",
            "  f1([x]) {}",
            "  f2([x = 1]) {}",
            "  f3([x = 1]) {}",
            "  f4([x = 1]) {}",
            "}",
            "class B extends A {",
            "  f1([x = 2]) {}",
            "  f2([x]) {}",
            "  f3([x = 2]) {}",
            "  f4([x = '2']) {}",
            "}",
            "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 10, 7, 1),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 11, 7, 5),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 12, 7, 7));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3183
   */
  public void test_implementsAndOverrides_differentDefaultValue_named() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {",
            "  f1({x}) {}",
            "  f2({x: 1}) {}",
            "  f3({x: 1}) {}",
            "  f4({x: 1}) {}",
            "}",
            "class B extends A {",
            "  f1({x: 2}) {}",
            "  f2({x]) {}",
            "  f3({x: 2}) {}",
            "  f4({x: '2'}) {}",
            "}",
            "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 10, 7, 1),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 11, 7, 4),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 12, 7, 6));
  }

  /**
   * It is a compile-time error if an instance method m1 overrides an instance member m2 and m1 does
   * not declare all the named parameters declared by m2 in the same order.
   * <p>
   * Here: no "y" parameter.
   */
  public void test_implementsAndOverrides_noNamedParameter() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "abstract class I {",
            "  foo({x,y});",
            "}",
            "class C implements I {",
            "  foo({x}) {}",
            "}");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, 5, 3, 3));
  }

  public void test_metadataCommentOverride_OK_method() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  foo() {}",
        "}",
        "class B extends A {",
        "  // @override",
        "  foo() {}",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  public void test_metadataCommentOverride_Bad_method() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const override = 0;",
        "class A {",
        "}",
        "class B extends A {",
        "  @override",
        "  foo() {}",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.INVALID_OVERRIDE_METADATA, 7, 3, 3));
  }

  public void testImplementsAndOverrides5() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "abstract class I {",
            "  foo({y,x});",
            "}",
            "class C implements I {",
            "  foo({x,y}) {}",
            "}");
    assertErrors(result.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=1936
   */
  public void test_propertyAccess_whenExtendsUnknown() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class C extends Unknown {",
            "  foo() {",
            "    this.elements;",
            "  }",
            "}");
    assertErrors(result.getErrors(), errEx(ResolverErrorCode.NO_SUCH_TYPE, 2, 17, 7));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3860
   */
  public void test_setterGetterDifferentStatic() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {",
            "  static get field => 0;",
            "         set field(var v) {}",
            "}",
            "class B {",
            "         get field => 0;",
            "  static set field(var v) {}",
            "}",
            "");
    assertErrors(result.getErrors(),
        errEx(TypeErrorCode.FIELD_GETTER_SETTER_SAME_STATIC, 4, 14, 5),
        errEx(TypeErrorCode.FIELD_GETTER_SETTER_SAME_STATIC, 8, 14, 5));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=380
   */
  public void test_setterGetterDifferentType() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {} ",
            "class B extends A {}",
            "class C {",
            "  A getterField; ",
            "  B setterField; ",
            "  A get field { return getterField; }",
            "  void set field(B arg) { setterField = arg; }",
            "}",
            "main() {",
            "  C instance = new C();",
            "  instance.field = new B();",
            "  A resultA = instance.field;",
            "  instance.field = new A();",
            "  B resultB = instance.field;",
            "}");
    assertErrors(result.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=7597
   */
  public void test_setterIsNotOverriddenByMethod() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {",
            "  set foo(var v) {}",
            "}",
            "class C extends A {",
            "  foo(value) {}",
            "}",
            "main() {",
            "  C c = new C();",
            "  c.foo(1);",
            "  c.foo = 1;",
            "}");
    assertErrors(result.getErrors());
  }


  public void test_setterGetterAssignable1() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {} ",
            "A topGetterField; ",
            "var topSetterField; ",
            "A get topField { return topGetterField; }",
            "void set topField(arg) { topSetterField = arg; }",
            "class C {",
            "  A getterField; ",
            "  var setterField; ",
            "  A get field { return getterField; }",
            "  void set field(arg) { setterField = arg; }",
            "}");
    assertErrors(result.getErrors());
  }

  public void test_setterGetterAssignable2() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {} ",
            "var topGetterField; ",
            "A topSetterField; ",
            "get topField { return topGetterField; }",
            "void set topField(A arg) { topSetterField = arg; }",
            "class C {",
            "  var getterField; ",
            "  A setterField; ",
            "  get field { return getterField; }",
            "  void set field(A arg) { setterField = arg; }",
            "}");
    assertErrors(result.getErrors());
  }

  public void test_setterGetterNotAssignable() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {} ",
            "class B {}",
            "A topGetterField; ",
            "B topSetterField; ",
            "A get topField { return topGetterField; }",
            "void set topField(B arg) { topSetterField = arg; }",
            "class C {",
            "  A getterField; ",
            "  B setterField; ",
            "  A get field { return getterField; }",
            "  void set field(B arg) { setterField = arg; }",
            "}");
    assertErrors(result.getErrors(),
        errEx(TypeErrorCode.SETTER_TYPE_MUST_BE_ASSIGNABLE, 7, 19, 5),
        errEx(TypeErrorCode.SETTER_TYPE_MUST_BE_ASSIGNABLE, 12, 18, 5));
  }

  public void test_setterInvokedAsMethod() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class C {",
            "  void set foo(String arg) {}",
            "} ",
            "method() {",
            " C c = new C();",
            " c.foo(1);",
            "}");
    /* This could probably use a better error message.  The user likely intends
     * to set the property foo, but it is invoking foo as a getter and
     * invoking the result.
     */
    assertErrors(result.getErrors(),
        errEx(TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, 7, 4, 3));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3221
   */
  public void test_conditionalExpressionType() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "main() {",
            "  bool x = (true ? 1 : 2.0);",
            "}", "");
    List<DartCompilationError> errors = result.getErrors();
    assertErrors(errors, errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 3, 12, 16));
    {
      String message = errors.get(0).getMessage();
      assertTrue(message.contains("'num'"));
      assertTrue(message.contains("'bool'"));
    }
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4394
   */
  public void test_conditionalExpressionType_genericInterface() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> { const A(); }",
        "class B<T> extends A<T> { const B(); }",
        "class C<T> implements B<T> { const C(); }",
        "class D<T> implements B<T> { const D(); }",
        "main() {",
        "  B<int> test = true ? new C<int>() : const D<int>();",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * <p>
   * https://codereview.chromium.org/12787002/
   */
  public void test_typeVariableBounds_12787002() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A<T> {",
            "  m() {",
            "    B a = this;",
            "  }",
            "}",
            "class B extends A<String> {}");
    assertErrors(result.getErrors());
  }

  public void test_typeVariableBoundsMismatch() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "abstract class I<T extends num> { }",
            "class A<T extends num> implements I<T> { }",
            "class B<T> implements I<T> { }"); // static type error B.T not assignable to num
    assertErrors(result.getErrors(), errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 4, 25, 1));
  }

  public void test_typeVariableBoundsMismatch2() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class C<T extends num> { }",
            "class A<T extends num> extends C<T> { }",
            "class B<T> extends C<T> { }"); // static type error B.T not assignable to num
    assertErrors(result.getErrors(), errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 4, 22, 1));
  }

  public void test_typeVariableBoundsCheckNew() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "class Object {}",
        "class A { }",
        "class B { }",
        "class C<T extends A> { }",
        "method() {",
        "  new C<B>();", // B not assignable to A
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 6, 9, 1));
  }

  /**
   * When we check getter/setter compatibility, we should compare propagated type variables.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3067
   */
  public void test_typeVariables_getterSetter() throws Exception {
    AnalyzeLibraryResult result =
        analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class Base1<T1> {",
            "  T1 get val {}",
            "}",
            "class Base2<T2> extends Base1<T2> {",
            "}",
            "class Sub<T3> extends Base2<T3> {",
            "  void set val(T3 value) {}",
            "}",
            "");
    assertErrors(result.getErrors());
  }

  public void test_inferredTypes_noMemberWarnings() throws Exception {
    // disabled by default
    {
      AnalyzeLibraryResult result = analyzeLibrary(
          "// filler filler filler filler filler filler filler filler filler filler",
          "class A {}",
          "foo(A a) {",
          "  var v = a;",
          "  v.f = 0;",
          "  v.m();",
          "}",
          "");
      assertErrors(result.getErrors());
    }
    // use CompilerConfiguration to enable
    {
      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
        @Override
        public boolean typeChecksForInferredTypes() {
          return true;
        }
      });
      AnalyzeLibraryResult result = analyzeLibrary(
          "// filler filler filler filler filler filler filler filler filler filler",
          "class A {}",
          "foo(A a) {",
          "  var v = a;",
          "  v.f = 0;",
          "  v.m();",
          "}",
          "");
      assertErrors(
          result.getErrors(),
          errEx(TypeErrorCode.NOT_A_MEMBER_OF_INFERRED, 5, 5, 1),
          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED, 6, 5, 1));
    }
  }

  /**
   * There was bug that for-in loop did not mark type of variable as inferred, so we produced
   * warnings even when this is disabled.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4460
   */
  public void test_inferredTypes_noMemberWarnings_forInLoop() throws Exception {
    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
      @Override
      public boolean typeChecksForInferredTypes() {
        return false;
      }
    });
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "foo() {",
        "  List<A> values;",
        "  for (var v in values) {",
        "    v.bar();",
        "  }",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  public void test_inferredTypes_whenInvocationArgument_checkAssignable() throws Exception {
    // disabled by default
    {
      AnalyzeLibraryResult result = analyzeLibrary(
          "// filler filler filler filler filler filler filler filler filler filler",
          "class A {}",
          "class B {}",
          "foo(A a) {}",
          "main() {",
          "  var v = new B();",
          "  foo(v);",
          "}",
          "");
      assertErrors(result.getErrors());
    }
    // use CompilerConfiguration to enable
    {
      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
        @Override
        public boolean typeChecksForInferredTypes() {
          return true;
        }
      });
      AnalyzeLibraryResult result = analyzeLibrary(
          "// filler filler filler filler filler filler filler filler filler filler",
          "class A {}",
          "class B {}",
          "foo(A a) {}",
          "main() {",
          "  var v = new B();",
          "  foo(v);",
          "}",
          "");
      assertErrors(
          result.getErrors(),
          errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE_INFERRED, 7, 7, 1));
    }
  }

  /**
   * When we resolved method from inferred type, it is possible that arguments of invocation
   * don't is not assignable to the parameters. So, we report warning. But if we would not infer
   * types, there would be no warnings.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4849
   */
  public void test_inferredTypes_invocationOfMethodFromInferredType_arguments() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  foo(int p) {}",
        "}",
        "main() {",
        "  var a = new A();",
        "  a.foo('');",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  public void test_typesPropagation_assignAtDeclaration() throws Exception {
    analyzeLibrary(
        "f() {",
        "  var v0 = true;",
        "  var v1 = true && false;",
        "  var v2 = 1;",
        "  var v3 = 1 + 2;",
        "  var v4 = 1.0;",
        "  var v5 = 1.0 + 2.0;",
        "  var v6 = new Map<String, int>();",
        "  var v7 = new Map().length;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v0", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v4", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v5", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v6", "Map<String, int>", INFERRED);
    assertInferredElementTypeString(testUnit, "v7", "int", INFERRED);
  }

  public void test_typesPropagation_arrayAccess() throws Exception {
    analyzeLibrary(
        "class A {}",
        "class B extends A {}",
        "List<A> list() => [new B()];",
        "main() {",
        "  var v0 = list();",
        "  var v1 = list();",
        "  var v2 = v1[0];",
        "}",
        "");
    {
      DartExpression expr = findNode(DartUnqualifiedInvocation.class, "list();");
      assertInferredElementTypeString(expr.getType(), "v0", "List<A>", EXACT);
    }
    assertInferredElementTypeString(testUnit, "v1", "List<A>", INFERRED);
    {
      DartExpression expr = findNode(DartArrayAccess.class, "v1[0]");
      assertInferredElementTypeString(expr.getType(), "v2", "A", INFERRED);
    }
  }

  /**
   * We should infer types only if variable declared without type.
   */
  public void test_typesPropagation_dontChangeDeclaredType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "class B extends A {}",
        "main() {",
        "  B v = new B();",
        "  var v1 = v;",
        "  v = new A();",
        "  var v2 = v;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    assertInferredElementTypeString(testUnit, "v1", "B", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "B", INFERRED_EXACT);
  }

  public void test_typesPropagation_multiAssign() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v = true;",
        "  var v1 = v;",
        "  v = 0;",
        "  var v2 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
  }

  public void test_typesPropagation_multiAssign_noInitialValue() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v;",
        "  v = 0;",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
  }

  public void test_typesPropagation_multiAssign_IfThen() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v = true;",
        "  var v1 = v;",
        "  if (true) {",
        "    v = 0;",
        "    var v2 = v;",
        "  }",
        "  var v3 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "Object", INFERRED);
  }

  public void test_typesPropagation_multiAssign_IfThenElse() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var a = true;",
        "  var b = true;",
        "  var c = true;",
        "  var d = true;",
        "  if (true) {",
        "    a = 0;",
        "    b = 0;",
        "  } else {",
        "    a = 0;",
        "    c = 0;",
        "  }",
        "  var a1 = a;",
        "  var b1 = b;",
        "  var c1 = c;",
        "  var d1 = d;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "a1", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "b1", "Object", INFERRED);
    assertInferredElementTypeString(testUnit, "c1", "Object", INFERRED);
    assertInferredElementTypeString(testUnit, "d1", "bool", INFERRED_EXACT);
  }

  public void test_typesPropagation_multiAssign_IfThenElse_whenAsTypeCondition() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (v is String) {",
        "    var v1 = v;",
        "    v = null;",
        "  } else {",
        "    var v2 = v;",
        "  }",
        "  var v3 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
  }

  public void test_typesPropagation_multiAssign_While() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v = true;",
        "  var v1 = v;",
        "  while (true) {",
        "    var v2 = v;",
        "    v = 0;",
        "    var v3 = v;",
        "  }",
        "  var v4 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v4", "Object", INFERRED);
  }

  public void test_typesPropagation_multiAssign_DoWhile() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v = true;",
        "  var v1 = v;",
        "  do {",
        "    var v2 = v;",
        "    v = 0;",
        "    var v3 = v;",
        "  } while (true);",
        "  var v4 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v4", "int", INFERRED_EXACT);
  }

  public void test_typesPropagation_multiAssign_For() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v = true;",
        "  var v1 = v;",
        "  for (int i = 0; i < 10; i++) {",
        "    var v2 = v;",
        "    v = 0;",
        "    var v3 = v;",
        "  }",
        "  var v4 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v4", "Object", INFERRED);
  }

  public void test_typesPropagation_multiAssign_ForIn() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v = true;",
        "  var v1 = v;",
        "  List<String> names = [];",
        "  for (var name in names) {",
        "    var v2 = v;",
        "    v = 0;",
        "    var v3 = v;",
        "  }",
        "  var v4 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v4", "Object", INFERRED);
  }

  /**
   * We should understand type with type arguments and choose the most generic version.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4792
   */
  public void test_typesPropagation_multiAssign_withGenerics_type_type() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var a = new List<String>();",
        "  var b = <Object>[];",
        "  if (true) {",
        "    a = <Object>[];",
        "    b = new List<String>();",
        "  }",
        "  var a1 = a;",
        "  var b1 = b;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "a1", "List<Object>", INFERRED);
    assertInferredElementTypeString(testUnit, "b1", "List<Object>", INFERRED);
  }

  /**
   * Prefer specific type, not "dynamic" type argument.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4792
   */
  public void test_typesPropagation_multiAssign_withGenerics_type_dynamic() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var a = new List<String>();",
        "  var b = [];",
        "  if (true) {",
        "    a = [];",
        "    b = new List<String>();",
        "  }",
        "  var a1 = a;",
        "  var b1 = b;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "a1", "List<String>", INFERRED);
    assertInferredElementTypeString(testUnit, "b1", "List<String>", INFERRED);
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4791
   */
  public void test_typesPropagation_multiAssign_type_null() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v = null;",
        "  var v1 = v;",
        "  if (true) {",
        "    v = '';",
        "    var v2 = v;",
        "  }",
        "  var v3 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "String", INFERRED);
  }

  /**
   * There was bug that when we analyze assignment in initializer, we don't have context.
   */
  public void test_typesPropagation_multiAssign_assignmentOutsideFunction() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  A(p) {}",
        "}",
        "class B extends A {",
        "  B(p) : super(p = 0) {}",
        "}",
        "");
    // no exceptions
  }

  /**
   * When we can not identify type of assigned value we should keep "dynamic" as type of variable.
   */
  public void test_typesPropagation_assign_newUnknownType() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f() {",
        "  var v1 = new Unknown();",
        "  var v2 = new Unknown.name();",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifAsType() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if ((v as String).length != 0) {",
        "    var v1 = v;",
        "  }",
        "  var v2 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
  }

  /**
   * Even if there is negation, we still apply "as" cast, so visit "then" statement only if cast was
   * successful.
   */
  public void test_typesPropagation_ifAsType_negation() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (!(v as String).isEmpty()) {",
        "    var v1 = v;",
        "  }",
        "  var v2 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifIsType() throws Exception {
    analyzeLibrary(
        "f(var v) {",
        "  if (v is List<String>) {",
        "    var v1 = v;",
        "  }",
        "  if (v is Map<int, String>) {",
        "    var v2 = v;",
        "  }",
        "  var v3 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "List<String>", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "Map<int, String>", INFERRED);
    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
  }

  /**
   * We should not make variable type less specific, even if there is such (useless) user code.
   */
  public void test_typesPropagation_ifIsType_mostSpecific() throws Exception {
    analyzeLibrary(
        "f() {",
        "  int a;",
        "  num b;",
        "  if (a is num) {",
        "    var a1 = a;",
        "  }",
        "  if (a is dynamic) {",
        "    var a2 = a;",
        "  }",
        "  if (b is int) {",
        "    var b1 = b;",
        "  }",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "a1", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "a2", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "b1", "int", INFERRED);
  }

  /**
   * When single variable has conflicting type constraints, we use union of types.
   */
  public void test_typesPropagation_ifIsType_conflictingTypes() throws Exception {
    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
      @Override
      public boolean typeChecksForInferredTypes() {
        return true;
      }
    });
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(int v) {",
        "  if (v is String) {",
        "    var v1 = v;",
        "    // should be OK because 'v' is String",
        "    v.abs; // from num",
        "    v.length; // from String",
        "    processInt(v);",
        "    processString(v);",
        "  }",
        "}",
        "processInt(int p) {}",
        "processString(String p) {}",
        "");
    // should be no errors, we because "v" is String
    assertErrors(result.getErrors());
    assertInferredElementTypeString(testUnit, "v1", "[int, String]", INFERRED);
  }

  public void test_typesPropagation_ifIsType_negation() throws Exception {
    analyzeLibrary(
        "f(var v) {",
        "  if (v is! String) {",
        "    var v1 = v;",
        "  }",
        "  if (!(v is String)) {",
        "    var v2 = v;",
        "  }",
        "  if (!!(v is String)) {",
        "    var v3 = v;",
        "  }",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "v3", "String", INFERRED);
  }

  public void test_typesPropagation_ifIsType_and() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var a, var b) {",
        "  if (a is String && b is List<String>) {",
        "    var a1 = a;",
        "    var b1 = b;",
        "  }",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "a1", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "b1", "List<String>", INFERRED);
  }

  public void test_typesPropagation_ifIsType_or() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (true || v is String) {",
        "    var v1 = v;",
        "  }",
        "  if (v is String || true) {",
        "    var v2 = v;",
        "  }",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
  }

  public void test_typesPropagation_whileIsType() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  var v = null;",
        "  while (v is String) {",
        "    var v1 = v;",
        "  }",
        "  var v2 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
  }

  public void test_typesPropagation_forIsType() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  var v = null;",
        "  for (; v is String; () {var v2 = v;} ()) {",
        "    var v1 = v;",
        "  }",
        "  var v3 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
  }

  public void test_typesPropagation_forEach() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  List<String> values = [];",
        "  for (var v in values) {",
        "    var v1 = v;",
        "  }",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
  }

  public void test_typesPropagation_ifIsNotType_withElse() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (v is! String) {",
        "    var v1 = v;",
        "  } else {",
        "    var v2 = v;",
        "  }",
        "  var v3 = v;",
        "}",
        "");
    // we don't know type, but not String
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
    // we know that String
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
    // again, we don't know after "if"
    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifIsNotType_hasThenReturn() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  var v1 = v;",
        "  if (v is! String) {",
        "    return;",
        "  }",
        "  var v2 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
  }

  public void test_typesPropagation_ifIsNotType_hasThenThrow() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (v is! String) {",
        "    throw new Exception();",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
  }

  public void test_typesPropagation_ifIsNotType_emptyThen() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (v is! String) {",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifIsNotType_otherThen() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (v is! String) {",
        "    ;",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifIsNotType_hasThenThrow_withCatch() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  try {",
        "    if (v is! String) {",
        "      throw new Exception();",
        "    }",
        "  } catch (var e) {",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifIsNotType_hasThenContinue() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  for (var v in <Object>[1, 'two', 3]) {",
        "    var v1 = v;",
        "    if (v is! String) {",
        "      continue;",
        "    }",
        "    var v2 = v;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    assertInferredElementTypeString(testUnit, "v1", "Object", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
  }

  public void test_typesPropagation_ifIsNotType_hasThenBreak() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  for (var v in <Object>[1, 'two', 3]) {",
        "    var v1 = v;",
        "    if (v is! String) {",
        "      break;",
        "    }",
        "    var v2 = v;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    assertInferredElementTypeString(testUnit, "v1", "Object", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
  }

  public void test_typesPropagation_ifIsNotType_or() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var p1, var p2) {",
        "  if (p1 is! int || p2 is! String) {",
        "    return;",
        "  }",
        "  var v1 = p1;",
        "  var v2 = p2;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
  }

  public void test_typesPropagation_ifIsNotType_and() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (v is! String && true) {",
        "    return;",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifIsNotType_not() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (!(v is! String)) {",
        "    return;",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
  }

  public void test_typesPropagation_ifIsNotType_not2() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (!!(v is! String)) {",
        "    return;",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
  }

  public void test_typesPropagation_ifNotIsType() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(var v) {",
        "  if (!(v is String)) {",
        "    return;",
        "  }",
        "  var v1 = v;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4410
   */
  public void test_typesPropagation_assertIsType() throws Exception {
    analyzeLibrary(
        "f(var v) {",
        "  if (true) {",
        "    var v1 = v;",
        "    assert(v is String);",
        "    var v2 = v;",
        "    {",
        "      var v3 = v;",
        "    }",
        "    var v4 = v;",
        "  }",
        "  var v5 = v;",
        "}",
        "");
    // we don't know type initially
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
    // after "assert" all next statements know type
    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "v3", "String", INFERRED);
    // type is set to unknown only when we exit control Block, not just any Block
    assertInferredElementTypeString(testUnit, "v4", "String", INFERRED);
    // we exited "if" Block, so "assert" may be was not executed, so we don't know type
    assertInferredElementTypeString(testUnit, "v5", "dynamic", EXACT);
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4410
   */
  public void test_typesPropagation_assertIsType_twoVariables() throws Exception {
    analyzeLibrary(
        "f(a, b) {",
        "  while (true) {",
        "    var a1 = a;",
        "    var b1 = b;",
        "    assert(a is String);",
        "    assert(b is String);",
        "    var a2 = a;",
        "    var b2 = b;",
        "  }",
        "  var a3 = a;",
        "  var b3 = b;",
        "}",
        "");
    // we don't know type initially
    assertInferredElementTypeString(testUnit, "a1", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "b1", "dynamic", EXACT);
    // after "assert" all next statements know type
    assertInferredElementTypeString(testUnit, "a2", "String", INFERRED);
    assertInferredElementTypeString(testUnit, "b2", "String", INFERRED);
    // we exited "if" Block, so "assert" may be was not executed, so we don't know type
    assertInferredElementTypeString(testUnit, "a3", "dynamic", EXACT);
    assertInferredElementTypeString(testUnit, "b3", "dynamic", EXACT);
  }

  /**
   * When variable has explicit type, we should not fall to 'dynamic', we need to keep this type.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6399
   */
  public void test_typesPropagation_assertIsType_hasExplicitType() throws Exception {
    analyzeLibrary(
        "class A {}",
        "class B extends A {}",
        "class C extends B {}",
        "main() {",
        "  B v;",
        "  if (v is A) {",
        "    var v1 = v;",
        "  }",
        "  if (v is B) {",
        "    var v2 = v;",
        "  }",
        "  if (v is C) {",
        "    var v3 = v;",
        "  }",
        "  if (v is String) {",
        "    var v4 = v;",
        "  }",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "B", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "B", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "C", INFERRED);
    assertInferredElementTypeString(testUnit, "v4", "[B, String]", INFERRED);
  }

  public void test_typesPropagation_field_inClass_final() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  final v1 = 123;",
        "  final v2 = 1 + 2.0;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
  }

  public void test_typesPropagation_field_inClass_const() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  const v1 = 123;",
        "  final v2 = 1 + 2.0;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
  }

  /**
   * If field is not final, we don't know if is will be assigned somewhere else, may be even not in
   * there same unit, so we cannot be sure about its type.
   */
  public void test_typesPropagation_field_inClass_notFinal() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var v1 = 123;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
  }

  public void test_typesPropagation_field_topLevel_final() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "final v1 = 123;",
        "final v2 = 1 + 2.0;",
        "");
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
  }

  public void test_typesPropagation_field_topLevel_const() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const v1 = 123;",
        "const v2 = 1 + 2.0;",
        "");
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
  }

  /**
   * If field is not final, we don't know if is will be assigned somewhere else, may be even not in
   * there same unit, so we cannot be sure about its type.
   */
  public void test_typesPropagation_field_topLevel_notFinal() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "var v1 = 123;",
        "");
    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
  }

  public void test_typesPropagation_FunctionAliasType() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "typedef F();",
        "foo(F f) {",
        "  var v = f;",
        "  v();",
        "}",
        "",
        "");
    assertInferredElementTypeString(testUnit, "v", "F", INFERRED_EXACT);
  }

  /**
   * When we pass "function literal" into invocation on some method, we may know exact
   * <code>Function</code> type expected by this method, so we know types of "function literal"
   * parameters. So, if these types are not specified in "function literal", we can use "expected"
   * types.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3712
   */
  public void test_typesPropagation_parameterOfClosure_invocationNormalParameter() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "typedef void EventListener(Event event);",
        "foo(EventListener listener) {",
        "}",
        "main() {",
        "  foo((e) {",
        "    var v = e;",
        "  });",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3712
   */
  public void test_typesPropagation_parameterOfClosure_invocationNamedPositionalParameter() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "typedef void EventListener(Event event);",
        "foo([EventListener listener]) {",
        "}",
        "main() {",
        "  foo((e) {",
        "    var v = e;",
        "  });",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3712
   */
  public void test_typesPropagation_parameterOfClosure_invocationNamedParameter() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "typedef void EventListener(Event event);",
        "foo({EventListener listener}) {",
        "}",
        "main() {",
        "  foo(listener: (e) {",
        "    var v = e;",
        "  });",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
  }

  /**
   * http://code.google.com/p/dart/issues/detail?id=3712
   */
  public void test_typesPropagation_parameterOfClosure_invocationOfMethod() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "typedef void EventListener(Event event);",
        "class Button {",
        "  onClick(EventListener listener) {",
        "  }",
        "}",
        "main() {",
        "  Button button = new Button();",
        "  button.onClick((e) {",
        "    var v = e;",
        "  });",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
  }

  /**
   * We should infer closure parameter types even in {@link FunctionType} is specified directly,
   * without using {@link FunctionAliasType}.
   */
  public void test_typesPropagation_parameterOfClosure_functionType() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "class Button<T> {",
        "  onClick(listener(T e)) {",
        "  }",
        "}",
        "main() {",
        "  var button = new Button<Event>();",
        "  button.onClick((e) {",
        "    var v = e;",
        "  });",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
  }

  public void test_typesPropagation_parameterOfClosure_assignVariable() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "typedef void EventListener(Event event);",
        "main() {",
        "  // local variable assign",
        "  {",
        "    EventListener listener;",
        "    listener = (e) {",
        "      var v1 = e;",
        "    };",
        "  }",
        "  // local variable declare",
        "  {",
        "    EventListener listener = (e) {",
        "      var v2 = e;",
        "    };",
        "  }",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "Event", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "Event", INFERRED);
  }

  public void test_typesPropagation_parameterOfClosure_assignField() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "typedef void EventListener(Event event);",
        "class Button {",
        "  EventListener listener;",
        "}",
        "EventListener topLevelListener;",
        "main() {",
        "  // top-level field",
        "  {",
        "    topLevelListener = (e) {",
        "      var v1 = e;",
        "    };",
        "  }",
        "  // member field",
        "  {",
        "    Button button = new Button();",
        "    button.listener = (e) {",
        "      var v2 = e;",
        "    };",
        "  }",
        "}",
        "EventListener topLevelListener2 = (e) {",
        "  var v3 = e;",
        "};",
        "");
    assertInferredElementTypeString(testUnit, "v1", "Event", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "Event", INFERRED);
    assertInferredElementTypeString(testUnit, "v3", "Event", INFERRED);
  }

  /**
   * Sometimes inferred type is too generic - such as "Object" or "Collection", so there are no
   * reason to reports problems.
   */
  public void deprecatedCollection_test_typesPropagation_dontWant_ifTooGeneric() throws Exception {
    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
      @Override
      public boolean typeChecksForInferredTypes() {
        return true;
      }
    });
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "typedef void HandlerObject(Object o);",
        "typedef void HandlerCollection(Collection o);",
        "fObject(HandlerObject h) {}",
        "fCollection(HandlerCollection h) {}",
        "main() {",
        "  fObject((x) {",
        "    x.myNoSuchField;",
        "    x.myNoSuchMethod();",
        "  });",
        "  fCollection((x) {",
        "    x.myNoSuchField;",
        "    x.myNoSuchMethod();",
        "  });",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * Helpful (but not perfectly satisfying Specification) type of "conditional" is intersection of
   * then/else types, not just their "least upper bounds". And this corresponds runtime behavior.
   */
  public void test_typesPropagation_conditional() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "abstract class I1 {",
        "  f1();",
        "}",
        "abstract class I2 {",
        "  f2();",
        "}",
        "class A implements I1, I2 {",
        "  f1() => 11;",
        "  f2() => 12;",
        "}",
        "class B implements I1, I2 {",
        "  f1() => 21;",
        "  f2() => 22;",
        "}",
        "main() {",
        "  var v = true ? new A() : new B();",
        "  v.f1();",
        "  v.f2();",
        "}",
        "");
    // no errors, because both f1() and f2() invocations were resolved
    assertErrors(libraryResult.getErrors());
    // v.f1() was resolved
    {
      DartExpression expression = findNodeBySource(testUnit, "v.f1()");
      assertNotNull(expression);
      assertNotNull(expression.getElement());
    }
    // v.f2() was resolved
    {
      DartExpression expression = findNodeBySource(testUnit, "v.f1()");
      assertNotNull(expression);
      assertNotNull(expression.getElement());
    }
  }

  public void test_getType_binaryExpression() throws Exception {
    analyzeLibrary(
        "f(var arg) {",
        "  var v1 = 1 + 2;",
        "  var v2 = 1 - 2;",
        "  var v3 = 1 * 2;",
        "  var v4 = 1 ~/ 2;",
        "  var v5 = 1 % 2;",
        "  var v6 = 1 / 2;",
        "  var v7 = 1.0 + 2;",
        "  var v8 = 1 + 2.0;",
        "  var v9 = 1 - 2.0;",
        "  var v10 = 1.0 - 2;",
        "  var v11 = 1 * 2.0;",
        "  var v12 = 1.0 * 2;",
        "  var v13 = 1.0 / 2;",
        "  var v14 = 1 / 2.0;",
        "  var v15 = 1.0 ~/ 2.0;",
        "  var v16 = 1.0 ~/ 2;",
        "  var v17 = arg as int",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v4", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v5", "int", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v6", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v7", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v8", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v9", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v10", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v11", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v12", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v13", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v14", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v15", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v16", "double", INFERRED_EXACT);
    assertInferredElementTypeString(testUnit, "v17", "int", INFERRED);
  }

  /**
   * It was requested that even if Editor can be helpful and warn about types incompatibility, it
   * should not do this to completely satisfy specification.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3223
   * <p>
   * This feature was requested by users, so we introduce it again, but disabled to command line.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4518
   */
  public void test_typesPropagation_noExtraWarnings() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "f(int v) {}",
        "f1() {",
        "  var v = true;",
        "  f(v);",
        "}",
        "f2(var v) {",
        "  if (v is bool) {",
        "    f(v);",
        "  }",
        "}",
        "f3(var v) {",
        "  while (v is bool) {",
        "    f(v);",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * There was problem that using <code>() -> bool</code> getter in negation ('!') caused assignment
   * warnings. Actual reason was that with negation getter access is visited twice and on the second
   * time type of getter method, instead of return type, was returned.
   */
  public void test_getType_getterInNegation() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "class A {",
        "  int get intProperty => 42;",
        "  bool get boolProperty => true;",
        "}",
        "f() {",
        "  var a = new A();",
        "  var v1 = a.intProperty;",
        "  var v2 = a.boolProperty;",
        "  if (a.boolProperty) {",
        "  }",
        "  if (!a.boolProperty) {",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED);
  }

  public void test_getType_getterInNegation_generic() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "class A<T> {",
        "  T field;",
        "  T get prop => null;",
        "}",
        "f() {",
        "  var a = new A<bool>();",
        "  var v1 = a.field;",
        "  var v2 = a.prop;",
        "  if (a.field) {",
        "  }",
        "  if (!a.field) {",
        "  }",
        "  if (a.prop) {",
        "  }",
        "  if (!a.prop) {",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED);
    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED);
  }

  public void test_getType_getterInSwitch_default() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "int get foo {}",
        "f() {",
        "  switch (true) {",
        "    default:",
        "      int v = foo;",
        "      break;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3515
   */
  public void test_getType_getterInSwitchExpression_topLevel() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "int get foo => 42;",
        "f() {",
        "  switch (foo) {",
        "    case 2:",
        "      break;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3515
   */
  public void test_getType_getterInSwitchExpression_inClass() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> {",
        "  T get foo => null;",
        "}",
        "f() {",
        "  A<int> a = new A<int>();",
        "  switch (a.foo) {",
        "    case 2:",
        "      break;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3272
   */
  public void test_assignVoidToDynamic() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "void foo() {}",
        "main() {",
        "  var v = foo();",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5114
   */
  public void test_lowerCaseDynamicType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  dynamic v = null;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=7980
   */
  public void test_whenVariableNamedDynamic() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  var dynamic = 42;",
        "  new List<dynamic>();",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NOT_A_TYPE, 4, 12, 7));
  }

  /**
   * It is a static warning if the return type of the user-declared operator == is explicitly
   * declared and not bool.
   */
  public void test_equalsOperator_type() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  bool operator ==(other) {}",
        "}",
        "class B {",
        "  String operator ==(other) {}",
        "}",
        "class C {",
        "  Object operator ==(other) {}",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE, 6, 19, 2),
        errEx(TypeErrorCode.OPERATOR_EQUALS_BOOL_RETURN_TYPE, 6, 3, 6),
        errEx(TypeErrorCode.OPERATOR_EQUALS_BOOL_RETURN_TYPE, 9, 3, 6));
  }

  /**
   * We should be able to resolve "a == b" to the "equals" operator.
   */
  public void test_equalsOperator_resolving() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class C {",
            "  operator ==(other) => false;",
            "}",
            "main() {",
            "  new C() == new C();",
            "}",
            "");
    assertErrors(libraryResult.getErrors());
    // find == expression
    DartExpression expression = findNodeBySource(testUnit, "new C() == new C()");
    assertNotNull(expression);
    // validate == element
    MethodElement equalsElement = (MethodElement) expression.getElement();
    assertNotNull(equalsElement);
  }

  /**
   * We can not override getter. But setter has name "setter=", so there are no conflict.
   */
  public void test_supertypeHasMethod() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
            "// filler filler filler filler filler filler filler filler filler filler",
            "class A {}",
            "abstract class I {",
            "  foo();",
            "  bar();",
            "}",
            "abstract class J implements I {",
            "  get foo;",
            "  set bar(x);",
            "}");
      assertErrors(libraryResult.getErrors(),
          errEx(TypeErrorCode.SUPERTYPE_HAS_METHOD, 8, 7, 3));
  }

  /**
   * Ensure that "operator call()" is parsed, and "operator" is not considered as return type. This
   * too weak test, but for now we are interested only in parsing.
   */
  public void test_callOperator_parsing() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  operator call() => 42;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * The spec in the section 10.28 says:
   * "It is a compile-time error to use a built-in identifier other than dynamic as a type annotation."
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3307
   */
  public void test_builtInIdentifier_asTypeAnnotation() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  abstract   v01;",
        "  as         v02;",
        "  dynamic    v03;",
        "  export     v04;",
        "  external   v05;",
        "  factory    v06;",
        "  get        v07;",
        "  implements v08;",
        "  import     v09;",
        "  library    v10;",
        "  operator   v11;",
        "  part       v12;",
        "  set        v13;",
        "  static     v14;",
        "//  typedef    v15;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 3, 3, 8),   // abstract
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 4, 3, 2),   // as
                                                                         // dynamic
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 6, 3, 6),   // export
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 7, 3, 8),   // external
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 8, 3, 7),   // factory
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 9, 3, 3),   // get
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 10, 3, 10), // implements
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 11, 3, 6),  // import
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 12, 3, 7),  // library
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 13, 3, 8),  // operator
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 14, 3, 4),  // part
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 15, 3, 3),  // set
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 16, 3, 6)  // static
//        ,errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 17, 3, 7)   // typedef
    );
  }

  public void test_supertypeHasField() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var foo;",
        "  var bar;",
        "}",
        "class B extends A {",
        "  foo() {}",
        "  bar() {}",
        "}");
    assertErrors(libraryResult.getErrors(),
        errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 7, 3, 3),
        errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 8, 3, 3));
  }

  /**
   * We can not override getter. But setter has name "setter=", so there are no conflict.
   */
  public void test_supertypeHasGetterSetter() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  get foo => 0;",
        "  set bar(x) {}",
        "}",
        "class B extends A {",
        "  foo() {}",
        "  bar() {}",
        "}");
    assertErrors(libraryResult.getErrors(),
        errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 7, 3, 3));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3280
   */
  public void test_typeVariableExtendsFunctionAliasType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "typedef void F();",
        "class C<T extends F> {",
        "  test() {",
        "    new C<T>();",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3344
   */
  public void test_typeVariableExtendsTypeVariable() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T, U extends T> {",
        "  f1(U u) {",
        "    T t = u;",
        "  }",
        "  f2(T t) {",
        "    U u = t;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  public void test_staticMemberAccessThroughInstance() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  static var x;",
        "  static y() {}",
        "  static method() {",
        "    var a = new A();",
        "    a.x = 1;",
        "    var foo = a.x;",
        "    a.y();",
        "    a.y = 1;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors(),
        errEx(TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, 7, 7, 1),
        errEx(TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, 8, 17, 1),
        errEx(TypeErrorCode.IS_STATIC_METHOD_IN, 9, 7, 1),
        errEx(TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, 10, 7, 1),
        errEx(TypeErrorCode.CANNOT_ASSIGN_TO, 10, 5, 3));
  }

  public void testExpectedPositionalArgument() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "method1(a, [b]) {}",
        "method2() {",
        "  method1(b:1);",
        "}");
    assertErrors(libraryResult.getErrors(),
        errEx(TypeErrorCode.EXPECTED_POSITIONAL_ARGUMENT, 4, 11, 3));
  }

  public void test_cannotResolveMethod_unqualified() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  f() {",
        "    foo();",
        "  }",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 4, 5, 3));
  }

  public void test_canNotResolveMethod_qualified() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "}",
        "main() {",
        "  A a = new A();",
        "  a.foo();",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 6, 5, 3));
  }

  public void test_operatorLocation() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "}",
        "main() {",
        "  A a = new A();",
        "  a + 0;",
        "  -a;",
        "  a--;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 6, 5, 1),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 7, 3, 1),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 8, 4, 2));
  }

  /**
   * It is a static warning if T does not denote a type available in the current lexical scope.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=2373
   */
  public void test_asType_unknown() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  null as T;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 3, 11, 1));
  }

  /**
   * It is a compile-time error if T is a parameterized type of the form G < T1; : : : ; Tn > and G
   * is not a generic type with n type parameters.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=2373
   */
  public void test_asType_wrongNumberOfTypeArguments() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "main() {",
        "  null as A<int, bool>;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 4, 11, 12));
  }

  /**
   * It is a static warning if T does not denote a type available in the current lexical scope.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=2373
   */
  public void test_isType_unknown() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  null is T;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 3, 11, 1));
  }

  public void test_incompatibleTypesInHierarchy1() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "abstract class Interface<T> {",
        "  T m();",
        "}",
        "abstract class A implements Interface {",
        "}",
        "class C extends A implements Interface<int> {",
        "  int m() => 0;",
        "}");
    assertErrors(
        libraryResult.getErrors());
  }

  public void test_incompatibleTypesInHierarchy2() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "abstract class Interface<T> {",
        "  T m();",
        "}",
        "abstract class A implements Interface<String> {",
        "}",
        "class C extends A implements Interface<int> {",
        "  int m() => 0;",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE, 8, 7, 1),
        errEx(TypeErrorCode.INCOMPATIBLE_TYPES_IN_HIERARCHY, 7, 7, 1));
  }

  public void test_variableUsedAsType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "var func;",
        "func i;");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NOT_A_TYPE, 3, 1, 4));
  }

  public void test_metadataComment_deprecated_1() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const deprecated = 0;",
        "@deprecated",
        "ttt() {}",
        "@deprecated",
        "get topLevelGet => 42;",
        "class A {",
        "  var @deprecated fff;",
        "  @deprecated",
        "  mmmm() {}",
        "  @deprecated",
        "  operator + (other) {}",
        "}",
        "method() {",
        "  ttt();",
        "  print(topLevelGet);",
        "  A a = new A();",
        "  a.fff = 0;",
        "  a.mmmm();",
        "  a + 0;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 16, 9, 11),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 15, 3, 3),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 18, 5, 3),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 19, 5, 4),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 20, 5, 1));
  }

  public void test_metadataComment_deprecated_2() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const deprecated = 0;",
        "@deprecated",
        "class A {",
        "  A.named() {}",
        "  @deprecated",
        "  A.depreca() {}",
        "}",
        "method() {",
        "  new A.named();",
        "  new A.depreca();",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 10, 7, 1),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 11, 7, 1),
        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 11, 9, 7));
  }

  public void test_metadata_resolving() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const test = 0;",
        "",
        "@test",
        "class A {",
        "  @test",
        "  m(@test p) {",
        "    @test var v = 0;",
        "  }",
        "}",
        "",
        "f(@test p) {}",
        "",
        "@test typedef F();",
        "",
        "");
    // @deprecated should be resolved at every place, so no errors
    assertErrors(libraryResult.getErrors());
  }

  public void test_assignMethod() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {",
        "  method() { }",
        "}",
        "main () {",
        "  new C().method = f;",
        "}",
        "f() {}",
        "");
    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.CANNOT_ASSIGN_TO, 6, 3, 14));
  }

  public void test_assignSetter() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {",
        "  set method(arg) { }",
        "}",
        "main () {",
        "  new C().method = f;",
        "}",
        "f() {}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  public void test_assignGetter() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {",
        "  get method { }",
        "}",
        "main () {",
        "  new C().method = f;",
        "}",
        "f() {}",
        "");
    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 6, 11, 6));
  }

  /**
   * Test for "operator []=".
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4881
   */
  public void test_assignArrayElement() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {" +
        "  get method { }",
        "  operator []=(k, v) {}",
        "}",
        "main () {",
        "  new C()[0] = 1;",
        "}");
    assertErrors(
        libraryResult.getErrors());
  }

  /**
   * Test for resolving variants of array access and unary/binary expressions.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5042
   */
  public void test_opAssignArrayElement() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  B operator [](k) => new B();",
        "    operator []=(k, v) { }",
        "}",
        "class B {",
        "  B operator +(x) => new B();",
        "}",
        "main () {",
        "  var a = new A();",
        "  process( a[2] );",
        "  a[0]++;",
        "  ++a[0];",
        "  a[0] += 1;",
        "  a[0] = 1;",
        "}",
        "process(x) {}",
        "");
    assertErrors(libraryResult.getErrors());
    // print( a[2] )
    {
      DartArrayAccess access = findNode(DartArrayAccess.class, "a[2]");
      // a[2] is invocation of method "[]"
      assertHasMethodElement(access, "A", "[]");
    }
    // a[0]++
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "a[0]++");
      // a[0]++ is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // a[0] is invocation of method []
      assertHasMethodElement(unary.getArg(), "A", "[]");
    }
    // ++a[0]
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++a[0]");
      // ++a[0] is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // a[0] is invocation of method []
      assertHasMethodElement(unary.getArg(), "A", "[]");
    }
    // a[0] += 1
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a[0] += 1");
      // a[0] += 1 is invocation of method "+"
      assertHasMethodElement(binary, "B", "+");
      // a[0] is invocation of method []
      assertHasMethodElement(binary.getArg1(), "A", "[]");
    }
    // a[0] = 1
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a[0] = 1");
      // a[0] = 1 is invocation of method "[]="
      assertHasMethodElement(binary, "A", "[]=");
      // a[0] is invocation of method []=
      assertHasMethodElement(binary.getArg1(), "A", "[]=");
    }
  }

  /**
   * Test for resolving variants of property access and unary/binary expressions.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5049
   */
  public void test_opAssignPropertyAccess_instance() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  B get b => new B();",
        "    set b(B x) {}",
        "}",
        "class B {",
        "  B operator +(x) => new B();",
        "}",
        "main () {",
        "  A a = new A();",
        "  process( a.b );",
        "  a.b++;",
        "  ++a.b;",
        "  a.b += 1;",
        "  a.b = null;",
        "}",
        "process(x) {}",
        "");
    assertErrors(libraryResult.getErrors());
    // print( a.b )
    {
      DartPropertyAccess access = findNode(DartPropertyAccess.class, "a.b");
      // a.b is field "A.b"
      assertHasFieldElement(access, "A", "b");
    }
    // a.b++
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "a.b++");
      // a.b++ is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // a.b is field "A.b"
      assertHasFieldElement(unary.getArg(), "A", "b");
    }
    // ++a.b
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++a.b");
      // ++a.b is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // a.b is field "A.b"
      assertHasFieldElement(unary.getArg(), "A", "b");
    }
    // a.b += 1
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a.b += 1");
      // a.b += 1 is invocation of method "+"
      assertHasMethodElement(binary, "B", "+");
      // a.b is field "A.b"
      assertHasFieldElement(binary.getArg1(), "A", "b");
    }
    // a.b = null
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a.b = null");
      // a.b = null has no Element
      assertSame(null, binary.getElement());
      // a.b is field "A.b"
      assertHasFieldElement(binary.getArg1(), "A", "b");
    }
  }

  /**
   * Test for resolving variants of static property access and unary/binary expressions.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5049
   */
  public void test_opAssignPropertyAccess_static() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  static B get b => new B();",
        "  static   set b(B x) {}",
        "}",
        "class B {",
        "  B operator +(x) => new B();",
        "}",
        "main () {",
        "  process( A.b );",
        "  A.b++;",
        "  ++A.b;",
        "  A.b += 1;",
        "  A.b = null;",
        "}",
        "process(x) {}",
        "");
    assertErrors(libraryResult.getErrors());
    // print( A.b )
    {
      DartPropertyAccess access = findNode(DartPropertyAccess.class, "A.b");
      // A.b is field "A.b"
      assertHasFieldElement(access, "A", "b");
    }
    // A.b++
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "A.b++");
      // A.b++ is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // A.b is field "A.b"
      assertHasFieldElement(unary.getArg(), "A", "b");
    }
    // ++A.b
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++A.b");
      // ++A.b is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // A.b is field "A.b"
      assertHasFieldElement(unary.getArg(), "A", "b");
    }
    // A.b += 1
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "A.b += 1");
      // A.b += 1 is invocation of method "+"
      assertHasMethodElement(binary, "B", "+");
      // A.b is field "A.b"
      assertHasFieldElement(binary.getArg1(), "A", "b");
    }
    // A.b = null
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "A.b = null");
      // A.b = null has no Element
      assertSame(null, binary.getElement());
      // A.b is field "A.b"
      assertHasFieldElement(binary.getArg1(), "A", "b");
    }
  }

  /**
   * Test for resolving variants of top-level property access and unary/binary expressions.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5049
   */
  public void test_opAssignPropertyAccess_topLevel() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "B get field => new B();",
        "  set field(B x) {}",
        "class B {",
        "  B operator +(x) => new B();",
        "}",
        "main () {",
        "  process( field );",
        "  field++;",
        "  ++field;",
        "  field += 1;",
        "  field = null;",
        "}",
        "process(x) {}",
        "");
    assertErrors(libraryResult.getErrors());
    // print( field )
    {
      DartIdentifier access = findNode(DartIdentifier.class, "field );");
      // "field" is top-level field
      assertHasFieldElement(access, "<library>", "field");
    }
    // field++
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "field++");
      // field++ is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // "field" is top-level field
      assertHasFieldElement(unary.getArg(), "<library>", "field");
    }
    // ++field
    {
      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++field");
      // ++field is invocation of method "+"
      assertHasMethodElement(unary, "B", "+");
      // "field" is top-level field
      assertHasFieldElement(unary.getArg(), "<library>", "field");
    }
    // field += 1
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "field += 1");
      // field += 1 is invocation of method "+"
      assertHasMethodElement(binary, "B", "+");
      // "field" is top-level field
      assertHasFieldElement(binary.getArg1(), "<library>", "field");
    }
    // field = null
    {
      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "field = null");
      // field = null is no Element
      assertSame(null, binary.getElement());
      // "field" is top-level field
      assertHasFieldElement(binary.getArg1(), "<library>", "field");
    }
  }

  private static void assertHasFieldElement(DartNode node, String className, String fieldName) {
    Element element = node.getElement();
    assertTrue("" + node + " " + element, element instanceof FieldElement);
    FieldElement fieldElement = (FieldElement) element;
    assertHasFieldElement(fieldElement, className, fieldName);
  }

  private static void assertHasFieldElement(FieldElement element, String className, String fieldName) {
    EnclosingElement enclosingElement = element.getEnclosingElement();
    String enclosingName;
    if (enclosingElement instanceof LibraryElement) {
      enclosingName = "<library>";
    } else {
      enclosingName = enclosingElement.getName();
    }
    assertEquals(className, enclosingName);
    //
    String elementName = element.getName();
    assertEquals(fieldName, elementName);
  }

  private static void assertHasMethodElement(DartNode node, String className, String methodName) {
    Element element = node.getElement();
    assertTrue("" + node + " " + element, element instanceof MethodElement);
    MethodElement methodElement = (MethodElement) element;
    assertMethodElement(methodElement, className, methodName);
  }

  private static void assertMethodElement(MethodElement element, String className, String methodName) {
    EnclosingElement enclosingElement = element.getEnclosingElement();
    String enclosingName;
    if (enclosingElement instanceof LibraryElement) {
      enclosingName = "<library>";
    } else {
      enclosingName = enclosingElement.getName();
    }
    assertEquals(className, enclosingName);
    //
    String elementName = element.getName();
    if (element.getModifiers().isGetter()) {
      elementName = "get " + elementName;
    }
    if (element.getModifiers().isSetter()) {
      elementName = "set " + elementName;
    }
    assertEquals(methodName, elementName);
  }

  public void test_invokeStaticFieldAsMethod() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {",
        "  static foo() { }",
        "}",
        "main () {",
        "  var a = new C().foo();",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.IS_STATIC_METHOD_IN, 6, 19, 3));
  }

  public void test_invokeNonFunction() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {",
        "  String foo;",
        "  method() {",
        "    foo();",
        "  }",
        "}",
        "method() {",
        "  String foo;",
        "  foo();",
        "  (1 + 5)();",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NOT_A_METHOD_IN, 5, 5, 3),
        errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 10, 3, 3),
        errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 11, 3, 9));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3223
   */
  public void test_invokeNonFunction_inferred() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "method() {",
        "  var v = 1;",
        "  v();",
        "}");
    assertErrors(libraryResult.getErrors());
  }

  public void test_invokeNonFunction_getter() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  int get foo => 0;",
        "}",
        "main() {",
        "  A a = new A();",
        "  a.foo();",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE_FIELD, 7, 5, 3));
  }

  public void test_wrongOperandTypeForUnaryExpression() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class C {",
        "  operator -(String arg) {}",
        "  operator +(String arg) {}",
        "}",
        "method1(arg) {}",
        "method2() {",
        "  C foo = new C();",
        "  method1(++foo);",
        "  method1(--foo);",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.OPERATOR_WRONG_OPERAND_TYPE, 9, 11, 5),
        errEx(TypeErrorCode.OPERATOR_WRONG_OPERAND_TYPE, 10, 11, 5));
  }

  /**
   * Missing value in {@link DartMapLiteralEntry} is parsing error, but should not cause exception.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3931
   */
  public void test_mapLiteralEntry_noValue() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  var v = {'key' : /*no value*/};",
        "}",
        "");
    // has some errors
    assertTrue(libraryResult.getErrors().size() != 0);
  }

  public void test_fieldOverrideWrongType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  int foo;",
        "}",
        "class B extends A {",
        "  String foo;",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER, 6, 10, 3));
  }

  public void test_overrideInstanceMember() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "class A {",
        "  var field;",
        "  method() {}",
        "}",
        "class B extends A {",
        "  static var field;",
        "  static method() {}",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CANNOT_OVERRIDE_INSTANCE_MEMBER, 6, 14, 5),
        errEx(ResolverErrorCode.CANNOT_OVERRIDE_INSTANCE_MEMBER, 7, 10, 6));
  }

  public void test_overrideStaticMember() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  static var foo;",
        "  static bar() {}",
        "}",
        "class B extends A {",
        "  var foo;",
        "  bar() {}",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.OVERRIDING_STATIC_MEMBER, 7, 7, 3),
        errEx(TypeErrorCode.OVERRIDING_STATIC_MEMBER, 8, 3, 3));
  }

  public void test_rethrowNotInCatch() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "class Object {}",
        "method() {",
        "  throw;",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.RETHROW_NOT_IN_CATCH, 3, 3, 5));
  }

  public void test_externalKeyword_OK() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "external topFunction();",
        "external get topGetter;",
        "external set topSetter(var v);",
        "class A {",
        "  external const A.con();",
        "  external A();",
        "  external factory A.named();",
        "  external classMethod();",
        "  external static classMethodStatic();",
        "  external get classGetter;",
        "  external set classSetter(var v);",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    // all method-like nodes here are "external"
    final AtomicInteger methodCounter = new AtomicInteger();
    testUnit.accept(new ASTVisitor<Void>() {
      @Override
      public Void visitMethodDefinition(DartMethodDefinition node) {
        methodCounter.incrementAndGet();
        assertTrue(node.getModifiers().isExternal());
        return null;
      }
    });
    assertEquals(10, methodCounter.get());
  }

  /**
   * Modifier "external" can be applied only to method-like elements.
   */
  public void test_externalKeyword_bad_field() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "external var topVar1;",
        "external int topVar2;",
        "class A {",
        "  external var field1;",
        "  external int field2;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 2, 14, 7),
        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 3, 14, 7),
        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 5, 16, 6),
        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 6, 16, 6));
  }

  /**
   * Methods with "external" cannot have body.
   */
  public void test_externalKeyword_bad_body() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "external topFunction() {}",
        "abstract class A {",
        "  external A() {}",
        "  external factory A.named() {}",
        "  external classMethod() {}",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 2, 24, 2),
        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 4, 16, 2),
        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 5, 30, 2),
        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 6, 26, 2));
  }

  public void test_cascade_type() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  String s = '';",
        "  var v = s..length;",
        "}",
        "");
    assertInferredElementTypeString(testUnit, "v", "String", INFERRED);
  }

  /**
   * There should be no problem reported, because assignment of "a" cascade to "b" with type "B"
   * implicitly set type of "a" to "B".
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6107
   */
  public void test_cascade_inferType_varDeclaration() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "class B extends A {",
        "  bMethod() {}",
        "}",
        "main() {",
        "  A a = new B();",
        "  B b = a..bMethod();",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * There should be no problem reported, because assignment of "a" cascade to "b" with type "B"
   * implicitly set type of "a" to "B".
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6107
   */
  public void test_cascade_inferType_varAssignment() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "class B extends A {",
        "  bMethod() {}",
        "}",
        "main() {",
        "  A a = new B();",
        "  B b = null;",
        "  b = a..bMethod();",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * We assign "a" to field "Holder.b" of type "B", so implicitly set type of "a" to "B".
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6107
   */
  public void test_cascade_inferType_fieldDeclaration() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Holder {",
        "  B b = getA()..bMethod();",
        "}",
        "class A {}",
        "class B extends A {",
        "  bMethod() {}",
        "}",
        "A getA() => new B();",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * We assign "a" to field "Holder.b" of type "B", so implicitly set type of "a" to "B".
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6107
   */
  public void test_cascade_inferType_fieldAssignment() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Holder {",
        "  B b;",
        "}",
        "class A {}",
        "class B extends A {",
        "  bMethod() {}",
        "}",
        "main() {",
        "  A a = new B();",
        "  Holder holder = new Holder();",
        "  holder.b = a..bMethod();",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4315
   */
  public void test_cascade_propertyAccess() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  int f;",
        "}",
        "main() {",
        "  A a = new A();",
        "  a",
        "    ..f = 1",
        "    ..f = 2;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    {
      DartPropertyAccess access = findNode(DartPropertyAccess.class, "..f = 1");
      assertNotNull(access.getElement());
    }
    {
      DartPropertyAccess access = findNode(DartPropertyAccess.class, "..f = 2");
      assertNotNull(access.getElement());
    }
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4315
   */
  public void test_cascade_methodInvocation() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  int m(p) {}",
        "}",
        "main() {",
        "  A a = new A();",
        "  a",
        "    ..m(1)",
        "    ..m(2);",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    {
      DartMethodInvocation invocation = findNode(DartMethodInvocation.class, "..m(1)");
      assertNotNull(invocation.getElement());
    }
    {
      DartMethodInvocation invocation = findNode(DartMethodInvocation.class, "..m(2)");
      assertNotNull(invocation.getElement());
    }
  }

  /**
   * Test that we already support cascaded calls in initializers. No implementation was changed.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6955
   */
  public void test_cascade_inInitializer() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var f;",
        "  A() : f = ''..length;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * Source is invalid, but should not cause {@link NullPointerException}.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4354
   */
  public void test_switchCase_withoutExpression() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  switch (0) {",
        "    case }",
        "  }",
        "}",
        "");
    // has some errors, no exception
    assertTrue(libraryResult.getErrors().size() != 0);
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6836
   */
  public void test_unresolvedIdentifier_inStatic_notPropertyAccess() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "process(x) {}",
        "",
        "class A {",
        "  static foo() {",
        "    unknown = 0;",
        "  }",
        "}",
        "",
        "main() {",
        "  unknown = 0;",
        "  process(unknown);",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 6, 5, 7),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 11, 3, 7),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 12, 11, 7));
  }

  /**
   * If "unknown" is separate identifier, it is handled as "this.unknown", but "this" is not
   * accessible in static context.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3084
   */
  public void test_unresolvedIdentifier_inInstance_notPropertyAccess() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "process(x) {}",
        "class A {",
        "  foo() {",
        "    unknown = 0;",
        "    process(unknown);",
        "  }",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 5, 7),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 6, 13, 7));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3084
   */
  public void test_unresolvedIdentifier_inStatic_inPropertyAccess() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "process(x) {}",
        "main() {",
        "  Unknown.foo = 0;",
        "  process(Unknown.foo);",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 4, 3, 7),
        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 11, 7));
  }

  /**
   * Unresolved constructor is warning.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3800
   */
  public void test_unresolvedConstructor() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "main() {",
        "  new A(); // OK",
        "  new A.noSuchConstructor(); // warning",
        "  new B(); // warning",
        "  new B.noSuchConstructor(); // warning",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.NEW_EXPRESSION_NOT_CONSTRUCTOR, 5, 9, 17),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 6, 7, 1),
        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 7, 1),
        errEx(TypeErrorCode.NEW_EXPRESSION_NOT_CONSTRUCTOR, 7, 9, 17));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4383
   */
  public void test_callFieldWithoutGetter_topLevel() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "set setOnlyField(v) {}",
        "main() {",
        "  setOnlyField(0);",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.USE_ASSIGNMENT_ON_SETTER, 4, 3, 12));
  }

  /**
   * Every {@link DartExpression} should have {@link Type} set. Just to don't guess this type at
   * many other points in the Editor.
   */
  public void test_typeForEveryExpression_variable() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "process(x) {}",
        "main() {",
        "  A aaa = new A();",
        "  process(aaa);",
        "}");
    testUnit.accept(new ASTVisitor<Void>() {
      @Override
      public Void visitIdentifier(DartIdentifier node) {
        // ignore declaration
        if (node.getParent() instanceof DartDeclaration) {
          return null;
        }
        // check "aaa"
        if (node.toString().equals("aaa")) {
          Type type = node.getType();
          assertNotNull(type);
          assertEquals("A", type.toString());
        }
        return null;
      }
    });
  }

  /**
   * Every {@link DartExpression} should have {@link Type} set. Just to don't guess this type at
   * many other points in the Editor.
   */
  public void test_typeForEveryExpression_typeNode() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class AAA {",
        "  static foo() {}",
        "}",
        "main() {",
        "  AAA.foo();",
        "}");
    testUnit.accept(new ASTVisitor<Void>() {
      @Override
      public Void visitIdentifier(DartIdentifier node) {
        // ignore declaration
        if (node.getParent() instanceof DartDeclaration) {
          return null;
        }
        // check "AAA"
        if (node.toString().equals("AAA")) {
          Type type = node.getType();
          assertNotNull(type);
          assertEquals("AAA", type.toString());
        }
        return null;
      }
    });
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4383
   */
  public void test_callFieldWithoutGetter_member() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  set setOnlyField(v) {}",
        "  foo() {",
        "    setOnlyField(0);",
        "  }",
        "}",
        "main() {",
        "  A a = new A();",
        "  a.setOnlyField(0);",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, 5, 5, 12),
        errEx(TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, 10, 5, 12));
  }

  private abstract static class ArgumentsBindingTester {
    static List<DartExpression> arguments;
    void doTest(DartUnit unit) {
      unit.accept(new ASTVisitor<Void>() {
        int invocationIndex = 0;
        @Override
        public Void visitUnqualifiedInvocation(DartUnqualifiedInvocation node) {
          arguments = node.getArguments();
          checkArgs(invocationIndex++);
          return super.visitUnqualifiedInvocation(node);
        }
      });
    }
    abstract void checkArgs(int invocationIndex);
    void assertId(int index, String expectedParameterName) {
      DartExpression argument = arguments.get(index);
      String idString = argument.getInvocationParameterId().toString();
      assertEquals("PARAMETER " + expectedParameterName, idString);
    }
  }

  public void test_formalParameters_positional_optional() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "method(var a, var b, [var c = 3, var d = 4]) {}",
        "main() {",
        "  method(10, 20);",
        "  method(10, 20, 30);",
        "  method(10, 20, 30, 40);",
        "}");
    assertErrors(libraryResult.getErrors());
    new ArgumentsBindingTester() {
      @Override
      void checkArgs(int invocationIndex) {
        switch (invocationIndex) {
          case 0: {
            assertId(0, "a");
            assertId(1, "b");
            break;
          }
          case 1: {
            assertId(0, "a");
            assertId(1, "b");
            assertId(2, "c");
            break;
          }
          case 3: {
            assertId(0, "a");
            assertId(1, "b");
            assertId(2, "c");
            assertId(3, "d");
            break;
          }
        }
      }
    }.doTest(testUnit);
  }

  public void test_formalParameters_positional_named() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "method(var a, var b, {var c : 3, var d : 4}) {}",
        "main() {",
        "  method(10, 20);",
        "  method(10, 20, c: 30);",
        "  method(10, 20, d: 40);",
        "  method(10, 20, d: 40, c: 30);",
        "}");
    assertErrors(libraryResult.getErrors());
    new ArgumentsBindingTester() {
      @Override
      void checkArgs(int invocationIndex) {
        switch (invocationIndex) {
          case 0: {
            assertId(0, "a");
            assertId(1, "b");
            break;
          }
          case 1: {
            assertId(0, "a");
            assertId(1, "b");
            assertId(2, "c");
            break;
          }
          case 2: {
            assertId(0, "a");
            assertId(1, "b");
            assertId(2, "d");
            break;
          }
          case 3: {
            assertId(0, "a");
            assertId(1, "b");
            assertId(2, "d");
            assertId(3, "c");
            break;
          }
        }
      }
    }.doTest(testUnit);
  }

  /**
   * A constructor name always begins with the name of its immediately enclosing class, and may
   * optionally be followed by a dot and an identifier id. It is a compile-time error if id is the
   * name of a member declared in the immediately enclosing class.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3989
   */
  public void test_constructorName_sameAsMemberName() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  A.foo() {}",
        "  foo() {}",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CONSTRUCTOR_WITH_NAME_OF_MEMBER, 3, 3, 5));
  }

  /**
   * It is a compile-time error if M is not the name of the immediately enclosing class.
   * It is a static warning if M.id is not a constructor name.
   */
  public void test_constructorName_factory_notEnclosingClassName() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "class B {",
        "  factory A() {}",
        "  factory A.name() {}",
        "  factory B() {}",
        "  factory B.name() {}",
        "}");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS, 4, 11, 1),
        errEx(ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS, 5, 11, 1),
        errEx(ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS_ID, 5, 11, 6));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3904
   */
  public void test_reifiedClasses() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "process(x) {}",
        "main() {",
        "  process(A);",
        "}");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=3968
   */
  public void test_redirectingFactoryConstructor() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  A() {}",
        "  A.named() {}",
        "}",
        "",
        "class B {",
        "  factory B.foo() = A;",
        "  factory B.bar() = A.named;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
    // prepare "class A"
    ClassElement elementA = findNode(DartClass.class, "class A").getElement();
    Type typeA = elementA.getType();
    // = A;
    {
      DartTypeNode typeNode = findNode(DartTypeNode.class, "A;");
      Type type = typeNode.getType();
      assertSame(typeA, type);
    }
    // = A.named;
    {
      DartTypeNode typeNode = findNode(DartTypeNode.class, "A.named;");
      Type type = typeNode.getType();
      assertSame(typeA, type);
      // .named
      DartIdentifier nameNode = findNode(DartIdentifier.class, "named;");
      Element nameElement = nameNode.getElement();
      assertNotNull(nameElement);
      assertSame(elementA.lookupConstructor("named"), nameElement);
    }
  }

  public void test_redirectingFactoryConstructor_cycle() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  factory A.nameA() = C.nameC;",
        "}",
        "class B {",
        "  factory B.nameB() = A.nameA;",
        "}",
        "class C {",
        "  factory C.nameC() = B.nameB;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE, 3, 11, 7),
        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE, 6, 11, 7),
        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE, 9, 11, 7));
  }

  public void test_redirectingFactoryConstructor_notConst_fromConst() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  A.named() {}",
        "}",
        "",
        "class B {",
        "  const factory B.bar() = A.named;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_CONST, 7, 29, 5));
  }

  public void test_redirectingFactoryConstructor_shouldBeSubType() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  A() {}",
        "  A.named(p0) {}",
        "}",
        "",
        "class B {",
        "  factory B.foo(p0) = A;",
        "  factory B.bar() = A.named;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_SUBTYPE, 8, 23, 1),
        errEx(TypeErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_SUBTYPE, 9, 23, 5));
  }

  public void test_redirectingFactoryConstructor_shouldBeSubType2() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> {",
        "  A.named(T t) {}",
        "}",
        "",
        "class B<T> {",
        "  factory B.foo(T t) = A<T>.named;",
        "}",
        "class B2<T, V> {",
        "  factory B2.foo(V v) = A<V>.named;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  public void test_redirectingFactoryConstructor_shouldBeSubType3() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> {",
        "  A(A<T> p) {}",
        "}",
        "",
        "class B<T> {",
        "  factory B.foo(A<T> p) = A;",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  public void test_redirectingFactoryConstructor_notSubType_typeParameterBounds() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A1<T extends String> {",
        "  A1() {}",
        "}",
        "class A2<T> {",
        "  A2() {}",
        "}",
        "",
        "class B {",
        "  factory B.name1() = A1<String>;",
        "  factory B.name2() = A1<int>;",
        "  factory B.name3() = A2<String>;",
        "  factory B.name4() = A2<int>;",
        "}",
        "");
    assertErrors(
        libraryResult.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 11, 26, 3));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4778
   */
  public void test_unqualifiedAccessToGenericTypeField() throws Exception {
    AnalyzeLibraryResult libraryResult = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Game {}",
        "class GameRenderer<G extends Game> {",
        "  G get game => null;",
        "}",
        "class SpaceShooterGame extends Game {",
        "  int score;",
        "}",
        "class SpaceShooterRenderer extends GameRenderer<SpaceShooterGame> {",
        "  someMethod() {",
        "    var a = game.score;",
        "  }",
        "}",
        "");
    assertErrors(libraryResult.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=4900
   */
  public void test_forInLoop_fieldAsVariable() throws Exception {
      AnalyzeLibraryResult result = analyzeLibrary(
          "// filler filler filler filler filler filler filler filler filler filler",
          "var v;",
          "get l => v;",
          "set l(x) {v = x;}",
          "main() {",
          "  for (l in [1, 2, 3]) {",
          "    process(l);",
          "  }",
          "}",
          "process(x) {}",
          "");
      assertErrors(result.getErrors());
  }

  /**
   * Don't report "no such member" if class implements "noSuchMethod" method.
   */
  public void test_dontReport_ifHas_noSuchMember_method() throws Exception {
    String[] lines = {
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  noSuchMethod(Invocation invocation) {}",
        "}",
        "class B extends A {}",
        "class C {}",
        "main() {",
        "  new A().notExistingMethod();",
        "  new B().notExistingMethod();",
        "  new C().notExistingMethod();",
        "}",
        "process(x) {}",
        ""};
    // report by default
    {
      AnalyzeLibraryResult result = analyzeLibrary(lines);
      assertErrors(
          result.getErrors(),
          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 8, 11, 17),
          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 9, 11, 17),
          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 10, 11, 17));
    }
    // don't report
    {
      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
        @Override
        public boolean reportNoMemberWhenHasInterceptor() {
          return false;
        }
      });
      AnalyzeLibraryResult result = analyzeLibrary(lines);
      assertErrors(
          result.getErrors(),
          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 10, 11, 17));
    }
  }

  /**
   * Don't report "no such member" if class implements "noSuchMethod" method.
   */
  public void test_dontReport_ifHas_noSuchMember_getter() throws Exception {
    String[] lines = {
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  noSuchMethod(Invocation invocation) {}",
        "}",
        "class B extends A {}",
        "class C {}",
        "main() {",
        "  process( new A().notExistingGetter );",
        "  process( new B().notExistingGetter );",
        "  process( new C().notExistingGetter );",
        "}",
        "process(x) {}",
        ""};
    // report by default
    {
      AnalyzeLibraryResult result = analyzeLibrary(lines);
      assertErrors(
          result.getErrors(),
          errEx(TypeErrorCode.NOT_A_MEMBER_OF, 8, 20, 17),
          errEx(TypeErrorCode.NOT_A_MEMBER_OF, 9, 20, 17),
          errEx(TypeErrorCode.NOT_A_MEMBER_OF, 10, 20, 17));
    }
    // don't report
    {
      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
        @Override
        public boolean reportNoMemberWhenHasInterceptor() {
          return false;
        }
      });
      AnalyzeLibraryResult result = analyzeLibrary(lines);
      assertErrors(result.getErrors(), errEx(TypeErrorCode.NOT_A_MEMBER_OF, 10, 20, 17));
    }
  }

  /**
   * Don't report "is not a function type" if class implements "noSuchMethod" method.
   */
  public void test_dontReport_ifHas_noSuchMember_isNotFunction() throws Exception {
    String[] lines = {
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  noSuchMethod(Invocation invocation) {}",
        "}",
        "class B extends A {}",
        "class C {}",
        "main() {",
        "  A a = new A();",
        "  B b = new B();",
        "  C c = new C();",
        "  a();",
        "  b();",
        "  c();",
        "}",
        ""};
    // report by default
    {
      AnalyzeLibraryResult result = analyzeLibrary(lines);
      assertErrors(
          result.getErrors(),
          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 11, 3, 1),
          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 12, 3, 1),
          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 13, 3, 1));
    }
    // don't report
    {
      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
        @Override
        public boolean reportNoMemberWhenHasInterceptor() {
          return false;
        }
      });
      AnalyzeLibraryResult result = analyzeLibrary(lines);
      assertErrors(
          result.getErrors(),
          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 13, 3, 1));
    }
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5084
   */
  public void test_duplicateSuperInterface_errorInClassImplements() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "class B implements A, A {}",
        "");
    assertErrors(result.getErrors(), errEx(ResolverErrorCode.DUPLICATE_IMPLEMENTS_TYPE, 3, 23, 1));
  }

  /**
   * It is a compile-time error if the superclass of a class C appears in the implements clause of C.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=7469
   */
  public void test_superClass_imImplementsClause() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "class B extends A implements A {}",
        "");
    assertErrors(result.getErrors(), errEx(ResolverErrorCode.SUPER_CLASS_IN_IMPLEMENTS, 3, 30, 1));
  }

  /**
   * We should report only "no such type", but not duplicate.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5084
   */
  public void test_duplicateSuperInterface_whenNoSuchType() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class B implements X, Y {}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.NO_SUCH_TYPE, 2, 20, 1),
        errEx(ResolverErrorCode.NO_SUCH_TYPE, 2, 23, 1));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5082
   */
  public void test_argumentDefinitionTest_type() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "foo(p) {",
        "  ?p;",
        "}",
        "");
    assertErrors(result.getErrors());
    DartUnaryExpression unary = findNode(DartUnaryExpression.class, "?p");
    Type type = unary.getType();
    assertNotNull(type);
    assertEquals("bool", type.toString());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5082
   */
  public void test_argumentDefinitionTest_shouldBeFormalParameter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "foo(p) {",
        "  var v;",
        "  ?p;",
        "  ?v;",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.FORMAL_PARAMETER_NAME_EXPECTED, 5, 4, 1));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5148
   */
  public void test_errorIfNoBodyForStaticMethod() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  static foo();",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.STATIC_METHOD_MUST_HAVE_BODY, 3, 3, 13));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5162
   */
  public void test_initializeFinalInstanceVariable_atDeclaration_inInitializer() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  final f = 0;",
        "  A() : f = 1 {}",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.DUPLICATE_INITIALIZATION, 4, 9, 5));
  }

  public void test_getOverridden_method() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  foo() => 1;",
        "}",
        "class B extends A {",
        "  foo() => 2;",
        "}",
        "");
    DartMethodDefinition node = findNode(DartMethodDefinition.class, "foo() => 2");
    Set<Element> superElements = node.getElement().getOverridden();
    assertClassMembers(superElements, "method A.foo");
  }

  public void test_getOverridden_methodAbstract() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  foo();",
        "}",
        "");
    DartMethodDefinition node = findNode(DartMethodDefinition.class, "foo();");
    Set<Element> superElements = node.getElement().getOverridden();
    assertTrue(superElements.isEmpty());
  }

  public void test_getOverridden_field_withGetterSetter() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var foo;",
        "}",
        "class B extends A {",
        "  get foo => 0;",
        "  set foo(x) {}",
        "}",
        "");
    // getter
    {
      DartMethodDefinition node = findNode(DartMethodDefinition.class, "get foo");
      Set<Element> superElements = node.getElement().getOverridden();
      assertClassMembers(superElements, "field A.foo");
    }
    // setter
    {
      DartMethodDefinition node = findNode(DartMethodDefinition.class, "set foo");
      Set<Element> superElements = node.getElement().getOverridden();
      assertClassMembers(superElements, "field A.foo");
    }
  }

  public void test_getOverridden_field_withGetter() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var foo;",
        "}",
        "class B extends A {",
        "  get foo => 0;",
        "  set foo(x) {}",
        "}",
        "");
    // getter
    {
      DartMethodDefinition node = findNode(DartMethodDefinition.class, "get foo");
      Set<Element> superElements = node.getElement().getOverridden();
      assertClassMembers(superElements, "field A.foo");
    }
  }

  public void test_getOverridden_field_withSetter() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var foo;",
        "}",
        "class B extends A {",
        "  set foo(x) {}",
        "}",
        "");
    // setter
    {
      DartMethodDefinition node = findNode(DartMethodDefinition.class, "set foo");
      Set<Element> superElements = node.getElement().getOverridden();
      assertClassMembers(superElements, "field A.foo");
    }
  }

  public void test_getOverridden_getterSetter_withField() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  get foo => 0;",
        "  set foo(x) {}",
        "}",
        "class B extends A {",
        "  var foo = 42;",
        "}",
        "");
    DartField node = findNode(DartField.class, "foo = 42");
    Set<Element> superElements = node.getElement().getOverridden();
    assertClassMembers(superElements, "field A.foo");
  }

  public void test_getOverridden_getter_withField() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  get foo => 0;",
        "}",
        "class B extends A {",
        "  var foo = 42;",
        "}",
        "");
    DartField node = findNode(DartField.class, "foo = 42");
    Set<Element> superElements = node.getElement().getOverridden();
    assertClassMembers(superElements, "field A.foo");
  }

  public void test_getOverridden_setter_withField() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  set foo(x) {}",
        "}",
        "class B extends A {",
        "  var foo = 42;",
        "}",
        "");
    DartField node = findNode(DartField.class, "foo = 42");
    Set<Element> superElements = node.getElement().getOverridden();
    assertClassMembers(superElements, "field A.setter foo");
  }

  public void test_getOverridden_setter_withSetter() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  set foo(x) {} // A",
        "}",
        "class B extends A {",
        "  set foo(x) {} // B",
        "}",
        "");
    DartField node = findNode(DartField.class, "set foo(x) {} // B");
    Set<Element> superElements = node.getElement().getOverridden();
    assertClassMembers(superElements, "field A.setter foo");
  }

  private static void assertClassMembers(Set<Element> superElements, String... expectedNames) {
    Set<String> superNames = Sets.newHashSet();
    for (Element element : superElements) {
      String name = element.getEnclosingElement().getName() + "." + element.getName();
      if (element instanceof FieldElement) {
        superNames.add("field " + name);
      }
      if (element instanceof MethodElement) {
        superNames.add("method " + name);
      }
    }
    for (String name : expectedNames) {
      assertTrue(name, superNames.remove(name));
    }
    assertTrue(superNames.toString(), superNames.isEmpty());
  }

  public void test_fieldAccess_declared_noGetter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  static set f(x) {}",
        "}",
        "main() {",
        "  print(A.f);",
        "}",
        "");
    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER, 6, 11, 1));
  }

  public void test_fieldAccess_notDeclared() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "}",
        "main() {",
        "  print(A.f);",
        "}",
        "");
    assertErrors(result.getErrors(), errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 11, 1));
  }

  public void test_fieldAssign_declared_noSetter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  static get f => 0;",
        "}",
        "main() {",
        "  A.f = 0;",
        "}",
        "");
    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER, 6, 5, 1));
  }

  public void test_fieldAssign_notDeclared() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "}",
        "main() {",
        "  A.f = 0;",
        "}",
        "");
    assertErrors(result.getErrors(), errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 5, 1));
  }

  public void test_field_unqualifiedAccess_read() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  set f(x) {}",
        "  run() {",
        "    var v = f;",
        "  }",
        "}",
        "");
    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER, 5, 13, 1));
  }

  public void test_field_unqualifiedAccess_write() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  get f => 0;",
        "  run() {",
        "    f = 1;",
        "  }",
        "}",
        "");
    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER, 5, 5, 1));
  }

  public void test_typeVariableScope_staticField() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> {",
        "  static T v;",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, 3, 10, 1));
  }

  public void test_typeVariableScope_staticMethod() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> {",
        "  static foo() {",
        "    T v = null;",
        "  }",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, 4, 5, 1));
  }

  public void test_typeVariableScope_instanceField() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A<T> {",
        "  final List<T> values = new List<T>();",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  public void test_unresolvedMethod_inFactoryConstructor() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  factory A() {",
        "    foo();",
        "  }",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_RESOLVE_METHOD, 4, 5, 3));
  }

  /**
   * Developers unfamiliar with Dart frequently write (x/y).toInt() instead of x ~/ y. The editor
   * should recognize that pattern.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5652
   */
  public void test_useEffectiveIntegerDivision_int() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  int x = 7;",
        "  int y = 2;",
        "  print( (x / y).toInt() );",
        "}",
        "");
    assertErrors(result.getErrors(), errEx(TypeErrorCode.USE_INTEGER_DIVISION, 5, 10, 15));
  }

  /**
   * We need to report warning only when arguments are integers.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5652
   */
  public void test_useEffectiveIntegerDivision_num() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  num x = 7;",
        "  num y = 2;",
        "  print( (x / y).toInt() );",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=5157
   */
  public void test_trySubTypeMember_forInferredType() throws Exception {
    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
      @Override
      public boolean typeChecksForInferredTypes() {
        return true;
      }
    });
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "class MouseEvent extends Event {",
        "  int clientX;",
        "  void stop() {}",
        "}",
        "typedef Listener(Event event);",
        "class Button {",
        "  addListener(Listener listener) {}",
        "}",
        "main() {",
        "  Button button = new Button();",
        "  button.addListener((event) {",
        "    event.clientX;",
        "    event.stop();",
        "  });",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * We should resolve sub-type member only if there is only sub-type with such member.
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6776
   */
  public void test_trySubTypeMember_moreThanOneMember() throws Exception {
    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
      @Override
      public boolean typeChecksForInferredTypes() {
        return true;
      }
    });
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class Event {}",
        "class MouseEvent extends Event {",
        "  int clientX;",
        "}",
        "class ScreenEvent extends Event {",
        "  int clientX;",
        "}",
        "typedef Listener(Event event);",
        "class Button {",
        "  addListener(Listener listener) {}",
        "}",
        "main() {",
        "  Button button = new Button();",
        "  button.addListener((event) {",
        "    event.clientX;",
        "  });",
        "}",
        "");
    // don't report error, because there IS member, we just don't know which one
    assertErrors(result.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6491
   */
  public void test_annotationOnGetter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "const myAnnotation = 0;",
        "class A {",
        "  @myAnnotation bool get isEmpty => true;",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  public void test_resolveRefInComment_ofClass() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "/** This class [A] has method [foo]. */",
        "class A {",
        "  foo() {}",
        "}",
        "");
    assertErrors(result.getErrors());
    // [A]
    {
      DartCommentRefName node = findNode(DartCommentRefName.class, "A]");
      ClassElement element = (ClassElement) node.getElement();
      assertEquals("A", element.getName());
    }
    // [foo]
    {
      DartCommentRefName node = findNode(DartCommentRefName.class, "foo]");
      MethodElement element = (MethodElement) node.getElement();
      assertEquals("foo", element.getName());
    }
  }

  public void test_resolveRefInComment_ofFunction() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "/** This function has parameter [aaa] of type [A] ans also [bbb]. */",
        "foo(A aaa, bbb) {}",
        "");
    assertErrors(result.getErrors());
    // [aaa]
    {
      DartCommentRefName node = findNode(DartCommentRefName.class, "aaa]");
      VariableElement element = (VariableElement) node.getElement();
      assertSame(ElementKind.PARAMETER, ElementKind.of(element));
      assertEquals("aaa", element.getName());
    }
    // [A]
    {
      DartCommentRefName node = findNode(DartCommentRefName.class, "A]");
      ClassElement element = (ClassElement) node.getElement();
      assertEquals("A", element.getName());
    }
    // [bbb]
    {
      DartCommentRefName node = findNode(DartCommentRefName.class, "bbb]");
      VariableElement element = (VariableElement) node.getElement();
      assertSame(ElementKind.PARAMETER, ElementKind.of(element));
      assertEquals("bbb", element.getName());
    }
  }

  public void test_resolveRefInComment_ofMethod() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var fff;",
        "  /** Initializes [fff] and then calls [bar]. */",
        "  foo() {}",
        "  bar() {}",
        "}",
        "");
    assertErrors(result.getErrors());
    // [fff]
    {
      DartCommentRefName node = findNode(DartCommentRefName.class, "fff]");
      FieldElement element = (FieldElement) node.getElement();
      assertEquals("fff", element.getName());
    }
    // [bar]
    {
      DartCommentRefName node = findNode(DartCommentRefName.class, "bar]");
      MethodElement element = (MethodElement) node.getElement();
      assertEquals("bar", element.getName());
    }
  }

  public void test_resolveNewInComment() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  A() {}",
        "  A.named() {}",
        "}",
        "/** Creates [A] using [new A] or [new A.named] constructors. */",
        "foo() {}",
        "");
    assertErrors(result.getErrors());
    // [new A]
    {
      DartCommentNewName node = findNode(DartCommentNewName.class, "new A]");
      assertEquals("", node.getConstructorElement().getName());
      assertEquals("A", node.getClassElement().getName());
    }
    // [new A.named]
    {
      DartCommentNewName node = findNode(DartCommentNewName.class, "new A.named]");
      assertEquals("named", node.getConstructorElement().getName());
      assertEquals("A", node.getClassElement().getName());
    }
  }

  public void test_notGenerativeConstructor_default() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  factory A() {",
        "    return null;",
        "  }",
        "}",
        "class B extends A {",
        "  B() : super() {}", // explicit call of super constructor
        "}",
        "class C extends A {",
        "  C() {}", // implicit call of super constructor
        "}",
        "class D extends A {", // implicit call of super constructor
        "}",
        "");
    assertErrors(result.getErrors(),
        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 8, 9, 7),
        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 11, 3, 1),
        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 13, 7, 1));
  }

  public void test_notGenerativeConstructor_explicitNamed() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  factory A.named() {",
        "    return null;",
        "  }",
        "}",
        "class B extends A {",
        "  B() : super.named() {}", // explicit call of super constructor
        "}",
        "");
    assertErrors(result.getErrors(),
        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 8, 9, 13));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=6718
   */
  public void test_initializerInMethod() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  var x;",
        "  B() : x = 0 {}",
        "}",
        "");
    assertErrors(result.getErrors(),
        errEx(ResolverErrorCode.INITIALIZER_ONLY_IN_GENERATIVE_CONSTRUCTOR, 4, 9, 5));
  }

  public void test_variableReferencesItselfInInitializer() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  var x = x;",
        "}",
        "");
    assertErrors(result.getErrors(),
        errEx(ResolverErrorCode.VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER, 3, 11, 1));
  }

  public void test_ForEachStatement_method() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  Iterator<int> iterator() {}",
        "}",
        "main() {",
        "  A a = new A();",
        "  for (int v in a) {}",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  public void test_ForEachStatement_negative_method_invalidReturnType() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  int iterator() {}",
        "}",
        "main() {",
        "  A a = new A();",
        "  for (int v in a) {}",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE, 7, 17, 1));
  }

  /**
   * It was negative test, but in the new <code>Iterator</code> field should be also supported.
   */
  public void test_ForEachStatement_field() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  Iterator iterator;",
        "}",
        "main() {",
        "  A a = new A();",
        "  for (int v in a) {}",
        "}",
        "");
    assertErrors(result.getErrors());
//    Map<String, ClassNodeElement> fieldNotMethod = loadSource(
//        "class A {",
//        "  int iterator;",
//        "}",
//        "class B {",
//        "  main() { for (int i in new A()) {}}",
//        "}");
//    analyzeClasses(fieldNotMethod, TypeErrorCode.FOR_IN_WITH_ITERATOR_FIELD);
  }

  public void test_ForEachStatement_negative_field_invalidReturnType() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  int iterator;",
        "}",
        "main() {",
        "  A a = new A();",
        "  for (int v in a) {}",
        "}",
        "");
    assertErrors(result.getErrors(),
        errEx(TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE, 7, 17, 1));
  }

  public void test_builtInIdentifier_asType() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  abstract v_abstract;",
        "}",
        "");
    assertErrors(result.getErrors(),
        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 3, 3, 8));
  }

  public void test_builtInIdentifier_asParameterizedType() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  abstract<int> v_01;",
        "  as<int> v_02;",
        "  export<int> v_03;",
        "  external<int> v_04;",
        "  factory<int> v_05;",
        "  get<int> v_06;",
        "  implements<int> v_07;",
        "  import<int> v_08;",
        "  library<int> v_09;",
        "  operator<int> v_q0;",
        "  part<int> v_11;",
        "  set<int> v_12;",
        "  static<int> v_13;",
        "  typedef<int> v_14;",
        "}",
        "");
    List<DartCompilationError> errors = result.getErrors();
    assertEquals(14, errors.size());
    for (DartCompilationError error : errors) {
      assertSame(TypeErrorCode.NO_SUCH_TYPE, error.getErrorCode());
      assertEquals(3, error.getColumnNumber());
    }
  }

  public void test_superConstructorInvocation_wrongPlace() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "topLevelMethod() : super() {}",
        "",
        "class A {",
        "  m() : super() {}",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR, 2, 20, 7),
        errEx(ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR, 5, 9, 7));
  }

  /**
   * Test that we set {@link ConstructorElement} for {@link DartSuperConstructorInvocation}.
   */
  public void test_superConstructorInvocation_resolveElement() throws Exception {
    analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "abstract class A {",
        "  A.named() {}",
        "}",
        "abstract class B extends A {",
        "  B() : super.named();",
        "}",
        "");
    DartIdentifier nameInInvocation = findNode(DartIdentifier.class, "named();");
    DartSuperConstructorInvocation invocation = (DartSuperConstructorInvocation) nameInInvocation.getParent();
    ConstructorNodeElement expectedElement = invocation.getElement();
    assertNotNull(expectedElement);
    assertSame(nameInInvocation.getElement(), expectedElement);
  }

  public void test_mixin_1() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  foo() {}",
        "}",
        "class B extends Object with A {", // no unimplemented methods warning
        "}",
        "main() {",
        "  B b = new B();",
        "  A a = b;", // no 'not assignable' warning
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=8022
   */
  public void test_mixin_notObjectSuperclass() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {}",
        "class B extends A {}",
        "typedef C = Object with B;",
        "class D extends Object with B {}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS, 4, 25, 1),
        errEx(ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS, 5, 29, 1));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=8025
   */
  public void test_mixin_withConstructor() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class M { M(); }",
        "typedef A = Object with M;",
        "class B extends Object with M {}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR, 3, 25, 1),
        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR, 4, 29, 1));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=8059
   */
  public void test_mixin_withSuperInvocation() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class M { foo() => super.toString(); }",
        "typedef A = Object with M;",
        "class B extends Object with M {}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_SUPER, 3, 25, 1),
        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_SUPER, 4, 29, 1));
  }

  /**
   * <p>
   * http://code.google.com/p/dart/issues/detail?id=8705
   */
  public void test_mixin_useInScope() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class M { foo() {} }",
        "class A extends Object with M {",
        "  bar() {",
        "    foo();",
        "  }",
        "}",
        "");
    assertErrors(result.getErrors());
  }

  /**
   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
   */
  public void _test_mixin_dontAddSupertypes() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  methodA() {}",
        "}",
        "class B extends A {",
        "  methodB() {}",
        "}",
        "class C extends Object with B {",
        "}",
        "main() {",
        "  C c = new C();",
        "  A a = c;", // 'not assignable' warning - mixing is only "B" content
        "  B b = c;", // OK
        "  c.methodB();", // OK
        "  c.methodA();", // 'no such member' warning - mixing is only "B" content
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 12, 9, 1),
        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 15, 5, 7));
  }

  public void test_mixin_dontAddSupertypes2() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "abstract class A {",
        "  methodA();",
        "}",
        "abstract class B implements A {",
        "  methodB() {}",
        "}",
        "class C extends Object with B {", // no unimplemented methods warning
        "}",
        "main() {",
        "  C c = new C();",
        "  A a = c;", // 'not assignable' warning - mixing is only "B" content
        "  B b = c;", // OK
        "  c.methodB();", // OK
        "  c.methodA();", // 'no such member' warning - mixing is only "B" content
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 12, 9, 1),
        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 15, 5, 7));
  }

  /**
   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
   */
  public void _test_mixin_dontAddSupertypes3() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  foo() {}",
        "}",
        "class B extends A {",
        "}",
        "abstract class C {",
        "  foo();",
        "}",
        "class D extends C with B {", // "foo" is not implemented, because NOT inherited from A
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 10, 7, 1));
  }

  /**
   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
   */
  public void _test_mixin_dontLookSupertype_getter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  get fA => 42;",
        "}",
        "class B extends A {",
        "  get fB => 42;",
        "}",
        "class C extends Object with B {",
        "}",
        "main() {",
        "  C c = new C();",
        "  print(c.fB);",
        "  print(c.fA);",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.NOT_A_MEMBER_OF, 13, 11, 2));
  }

  /**
   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
   */
  public void _test_mixin_dontLookSupertype_setter() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "class A {",
        "  set fA(x) {}",
        "}",
        "class B extends A {",
        "  set fB(x) {}",
        "}",
        "class C extends Object with B {",
        "}",
        "main() {",
        "  C c = new C();",
        "  c.fB = 1;",
        "  c.fA = 2;",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.NOT_A_MEMBER_OF, 13, 5, 2));
  }

  public void test_mixin_disallowMixinApplication_asMixin() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "typedef M = Object with M;",
        "");
    assertErrors(
        result.getErrors(),
        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS, 2, 25, 1));
  }

  public void test_StringPlus() throws Exception {
    AnalyzeLibraryResult result = analyzeLibrary(
        "// filler filler filler filler filler filler filler filler filler filler",
        "main() {",
        "  var v1 = '1' + '2';",
        "  var v2 = '1' + 2;",
        "}",
        "");
    assertErrors(
        result.getErrors(),
        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 4, 18, 1));
  }
}
