// Copyright (c) 2016, 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.

library analyzer.test.generated.simple_resolver_test;

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'resolver_test_case.dart';
import 'test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(SimpleResolverTest);
  });
}

@reflectiveTest
class SimpleResolverTest extends ResolverTestCase {
  void test_argumentResolution_required_matching() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, 3);
  }
  void g(a, b, c) {}
}''');
    _validateArgumentResolution(source, [0, 1, 2]);
  }

  void test_argumentResolution_required_tooFew() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2);
  }
  void g(a, b, c) {}
}''');
    _validateArgumentResolution(source, [0, 1]);
  }

  void test_argumentResolution_required_tooMany() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, 3);
  }
  void g(a, b) {}
}''');
    _validateArgumentResolution(source, [0, 1, -1]);
  }

  void test_argumentResolution_requiredAndNamed_extra() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, c: 3, d: 4);
  }
  void g(a, b, {c}) {}
}''');
    _validateArgumentResolution(source, [0, 1, 2, -1]);
  }

  void test_argumentResolution_requiredAndNamed_matching() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, c: 3);
  }
  void g(a, b, {c}) {}
}''');
    _validateArgumentResolution(source, [0, 1, 2]);
  }

  void test_argumentResolution_requiredAndNamed_missing() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, d: 3);
  }
  void g(a, b, {c, d}) {}
}''');
    _validateArgumentResolution(source, [0, 1, 3]);
  }

  void test_argumentResolution_requiredAndPositional_fewer() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, 3);
  }
  void g(a, b, [c, d]) {}
}''');
    _validateArgumentResolution(source, [0, 1, 2]);
  }

  void test_argumentResolution_requiredAndPositional_matching() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, 3, 4);
  }
  void g(a, b, [c, d]) {}
}''');
    _validateArgumentResolution(source, [0, 1, 2, 3]);
  }

  void test_argumentResolution_requiredAndPositional_more() {
    Source source = addSource(r'''
class A {
  void f() {
    g(1, 2, 3, 4);
  }
  void g(a, b, [c]) {}
}''');
    _validateArgumentResolution(source, [0, 1, 2, -1]);
  }

  void test_argumentResolution_setter_propagated() {
    Source source = addSource(r'''
main() {
  var a = new A();
  a.sss = 0;
}
class A {
  set sss(x) {}
}''');
    LibraryElement library = resolve2(source);
    CompilationUnitElement unit = library.definingCompilationUnit;
    // find "a.sss = 0"
    AssignmentExpression assignment;
    {
      FunctionElement mainElement = unit.functions[0];
      FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
      Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
      ExpressionStatement expressionStatement =
          statement as ExpressionStatement;
      assignment = expressionStatement.expression as AssignmentExpression;
    }
    // get parameter
    Expression rhs = assignment.rightHandSide;
    expect(rhs.staticParameterElement, isNull);
    ParameterElement parameter = rhs.propagatedParameterElement;
    expect(parameter, isNotNull);
    expect(parameter.displayName, "x");
    // validate
    ClassElement classA = unit.types[0];
    PropertyAccessorElement setter = classA.accessors[0];
    expect(setter.parameters[0], same(parameter));
  }

  void test_argumentResolution_setter_propagated_propertyAccess() {
    Source source = addSource(r'''
main() {
  var a = new A();
  a.b.sss = 0;
}
class A {
  B b = new B();
}
class B {
  set sss(x) {}
}''');
    LibraryElement library = resolve2(source);
    CompilationUnitElement unit = library.definingCompilationUnit;
    // find "a.b.sss = 0"
    AssignmentExpression assignment;
    {
      FunctionElement mainElement = unit.functions[0];
      FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
      Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
      ExpressionStatement expressionStatement =
          statement as ExpressionStatement;
      assignment = expressionStatement.expression as AssignmentExpression;
    }
    // get parameter
    Expression rhs = assignment.rightHandSide;
    expect(rhs.staticParameterElement, isNull);
    ParameterElement parameter = rhs.propagatedParameterElement;
    expect(parameter, isNotNull);
    expect(parameter.displayName, "x");
    // validate
    ClassElement classB = unit.types[1];
    PropertyAccessorElement setter = classB.accessors[0];
    expect(setter.parameters[0], same(parameter));
  }

  void test_argumentResolution_setter_static() {
    Source source = addSource(r'''
main() {
  A a = new A();
  a.sss = 0;
}
class A {
  set sss(x) {}
}''');
    LibraryElement library = resolve2(source);
    CompilationUnitElement unit = library.definingCompilationUnit;
    // find "a.sss = 0"
    AssignmentExpression assignment;
    {
      FunctionElement mainElement = unit.functions[0];
      FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
      Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
      ExpressionStatement expressionStatement =
          statement as ExpressionStatement;
      assignment = expressionStatement.expression as AssignmentExpression;
    }
    // get parameter
    Expression rhs = assignment.rightHandSide;
    ParameterElement parameter = rhs.staticParameterElement;
    expect(parameter, isNotNull);
    expect(parameter.displayName, "x");
    // validate
    ClassElement classA = unit.types[0];
    PropertyAccessorElement setter = classA.accessors[0];
    expect(setter.parameters[0], same(parameter));
  }

  void test_argumentResolution_setter_static_propertyAccess() {
    Source source = addSource(r'''
main() {
  A a = new A();
  a.b.sss = 0;
}
class A {
  B b = new B();
}
class B {
  set sss(x) {}
}''');
    LibraryElement library = resolve2(source);
    CompilationUnitElement unit = library.definingCompilationUnit;
    // find "a.b.sss = 0"
    AssignmentExpression assignment;
    {
      FunctionElement mainElement = unit.functions[0];
      FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
      Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
      ExpressionStatement expressionStatement =
          statement as ExpressionStatement;
      assignment = expressionStatement.expression as AssignmentExpression;
    }
    // get parameter
    Expression rhs = assignment.rightHandSide;
    ParameterElement parameter = rhs.staticParameterElement;
    expect(parameter, isNotNull);
    expect(parameter.displayName, "x");
    // validate
    ClassElement classB = unit.types[1];
    PropertyAccessorElement setter = classB.accessors[0];
    expect(setter.parameters[0], same(parameter));
  }

  void test_breakTarget_labeled() {
    // Verify that the target of the label is correctly found and is recorded
    // as the unlabeled portion of the statement.
    String text = r'''
void f() {
  loop1: while (true) {
    loop2: for (int i = 0; i < 10; i++) {
      break loop1;
      break loop2;
    }
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    WhileStatement whileStatement = EngineTestCase.findNode(
        unit, text, 'while (true)', (n) => n is WhileStatement);
    ForStatement forStatement =
        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
    BreakStatement break1 = EngineTestCase.findNode(
        unit, text, 'break loop1', (n) => n is BreakStatement);
    BreakStatement break2 = EngineTestCase.findNode(
        unit, text, 'break loop2', (n) => n is BreakStatement);
    expect(break1.target, same(whileStatement));
    expect(break2.target, same(forStatement));
  }

  void test_breakTarget_unlabeledBreakFromDo() {
    String text = r'''
void f() {
  do {
    break;
  } while (true);
}
''';
    CompilationUnit unit = resolveSource(text);
    DoStatement doStatement =
        EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
    BreakStatement breakStatement = EngineTestCase.findNode(
        unit, text, 'break', (n) => n is BreakStatement);
    expect(breakStatement.target, same(doStatement));
  }

  void test_breakTarget_unlabeledBreakFromFor() {
    String text = r'''
void f() {
  for (int i = 0; i < 10; i++) {
    break;
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    ForStatement forStatement =
        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
    BreakStatement breakStatement = EngineTestCase.findNode(
        unit, text, 'break', (n) => n is BreakStatement);
    expect(breakStatement.target, same(forStatement));
  }

  void test_breakTarget_unlabeledBreakFromForEach() {
    String text = r'''
void f() {
  for (x in []) {
    break;
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    ForEachStatement forStatement = EngineTestCase.findNode(
        unit, text, 'for', (n) => n is ForEachStatement);
    BreakStatement breakStatement = EngineTestCase.findNode(
        unit, text, 'break', (n) => n is BreakStatement);
    expect(breakStatement.target, same(forStatement));
  }

  void test_breakTarget_unlabeledBreakFromSwitch() {
    String text = r'''
void f() {
  while (true) {
    switch (0) {
      case 0:
        break;
    }
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    SwitchStatement switchStatement = EngineTestCase.findNode(
        unit, text, 'switch', (n) => n is SwitchStatement);
    BreakStatement breakStatement = EngineTestCase.findNode(
        unit, text, 'break', (n) => n is BreakStatement);
    expect(breakStatement.target, same(switchStatement));
  }

  void test_breakTarget_unlabeledBreakFromWhile() {
    String text = r'''
void f() {
  while (true) {
    break;
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    WhileStatement whileStatement = EngineTestCase.findNode(
        unit, text, 'while', (n) => n is WhileStatement);
    BreakStatement breakStatement = EngineTestCase.findNode(
        unit, text, 'break', (n) => n is BreakStatement);
    expect(breakStatement.target, same(whileStatement));
  }

  void test_breakTarget_unlabeledBreakToOuterFunction() {
    // Verify that unlabeled break statements can't resolve to loops in an
    // outer function.
    String text = r'''
void f() {
  while (true) {
    void g() {
      break;
    }
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    BreakStatement breakStatement = EngineTestCase.findNode(
        unit, text, 'break', (n) => n is BreakStatement);
    expect(breakStatement.target, isNull);
  }

  void test_class_definesCall() {
    Source source = addSource(r'''
class A {
  int call(int x) { return x; }
}
int f(A a) {
  return a(0);
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_class_extends_implements() {
    Source source = addSource(r'''
class A extends B implements C {}
class B {}
class C {}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_commentReference_class() {
    Source source = addSource(r'''
f() {}
/** [A] [new A] [A.n] [new A.n] [m] [f] */
class A {
  A() {}
  A.n() {}
  m() {}
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_commentReference_parameter() {
    Source source = addSource(r'''
class A {
  A() {}
  A.n() {}
  /** [e] [f] */
  m(e, f()) {}
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_commentReference_singleLine() {
    Source source = addSource(r'''
/// [A]
class A {}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_continueTarget_labeled() {
    // Verify that the target of the label is correctly found and is recorded
    // as the unlabeled portion of the statement.
    String text = r'''
void f() {
  loop1: while (true) {
    loop2: for (int i = 0; i < 10; i++) {
      continue loop1;
      continue loop2;
    }
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    WhileStatement whileStatement = EngineTestCase.findNode(
        unit, text, 'while (true)', (n) => n is WhileStatement);
    ForStatement forStatement =
        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
    ContinueStatement continue1 = EngineTestCase.findNode(
        unit, text, 'continue loop1', (n) => n is ContinueStatement);
    ContinueStatement continue2 = EngineTestCase.findNode(
        unit, text, 'continue loop2', (n) => n is ContinueStatement);
    expect(continue1.target, same(whileStatement));
    expect(continue2.target, same(forStatement));
  }

  void test_continueTarget_unlabeledContinueFromDo() {
    String text = r'''
void f() {
  do {
    continue;
  } while (true);
}
''';
    CompilationUnit unit = resolveSource(text);
    DoStatement doStatement =
        EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
    ContinueStatement continueStatement = EngineTestCase.findNode(
        unit, text, 'continue', (n) => n is ContinueStatement);
    expect(continueStatement.target, same(doStatement));
  }

  void test_continueTarget_unlabeledContinueFromFor() {
    String text = r'''
void f() {
  for (int i = 0; i < 10; i++) {
    continue;
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    ForStatement forStatement =
        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
    ContinueStatement continueStatement = EngineTestCase.findNode(
        unit, text, 'continue', (n) => n is ContinueStatement);
    expect(continueStatement.target, same(forStatement));
  }

  void test_continueTarget_unlabeledContinueFromForEach() {
    String text = r'''
void f() {
  for (x in []) {
    continue;
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    ForEachStatement forStatement = EngineTestCase.findNode(
        unit, text, 'for', (n) => n is ForEachStatement);
    ContinueStatement continueStatement = EngineTestCase.findNode(
        unit, text, 'continue', (n) => n is ContinueStatement);
    expect(continueStatement.target, same(forStatement));
  }

  void test_continueTarget_unlabeledContinueFromWhile() {
    String text = r'''
void f() {
  while (true) {
    continue;
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    WhileStatement whileStatement = EngineTestCase.findNode(
        unit, text, 'while', (n) => n is WhileStatement);
    ContinueStatement continueStatement = EngineTestCase.findNode(
        unit, text, 'continue', (n) => n is ContinueStatement);
    expect(continueStatement.target, same(whileStatement));
  }

  void test_continueTarget_unlabeledContinueSkipsSwitch() {
    String text = r'''
void f() {
  while (true) {
    switch (0) {
      case 0:
        continue;
    }
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    WhileStatement whileStatement = EngineTestCase.findNode(
        unit, text, 'while', (n) => n is WhileStatement);
    ContinueStatement continueStatement = EngineTestCase.findNode(
        unit, text, 'continue', (n) => n is ContinueStatement);
    expect(continueStatement.target, same(whileStatement));
  }

  void test_continueTarget_unlabeledContinueToOuterFunction() {
    // Verify that unlabeled continue statements can't resolve to loops in an
    // outer function.
    String text = r'''
void f() {
  while (true) {
    void g() {
      continue;
    }
  }
}
''';
    CompilationUnit unit = resolveSource(text);
    ContinueStatement continueStatement = EngineTestCase.findNode(
        unit, text, 'continue', (n) => n is ContinueStatement);
    expect(continueStatement.target, isNull);
  }

  void test_empty() {
    Source source = addSource("");
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_entryPoint_exported() {
    addNamedSource(
        "/two.dart",
        r'''
library two;
main() {}''');
    Source source = addNamedSource(
        "/one.dart",
        r'''
library one;
export 'two.dart';''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    FunctionElement main = library.entryPoint;
    expect(main, isNotNull);
    expect(main.library, isNot(same(library)));
    assertNoErrors(source);
    verify([source]);
  }

  void test_entryPoint_local() {
    Source source = addNamedSource(
        "/one.dart",
        r'''
library one;
main() {}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    FunctionElement main = library.entryPoint;
    expect(main, isNotNull);
    expect(main.library, same(library));
    assertNoErrors(source);
    verify([source]);
  }

  void test_entryPoint_none() {
    Source source = addNamedSource("/one.dart", "library one;");
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    expect(library.entryPoint, isNull);
    assertNoErrors(source);
    verify([source]);
  }

  void test_enum_externalLibrary() {
    addNamedSource(
        "/my_lib.dart",
        r'''
library my_lib;
enum EEE {A, B, C}''');
    Source source = addSource(r'''
import 'my_lib.dart';
main() {
  EEE e = null;
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_extractedMethodAsConstant() {
    Source source = addSource(r'''
abstract class Comparable<T> {
  int compareTo(T other);
  static int compare(Comparable a, Comparable b) => a.compareTo(b);
}
class A {
  void sort([compare = Comparable.compare]) {}
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_fieldFormalParameter() {
    Source source = addSource(r'''
class A {
  int x;
  int y;
  A(this.x) : y = x {}
}''');
    CompilationUnit unit =
        analysisContext2.resolveCompilationUnit2(source, source);
    ClassDeclaration classA = unit.declarations[0];
    FieldDeclaration field = classA.members[0];
    ConstructorDeclaration constructor = classA.members[2];
    ParameterElement paramElement =
        constructor.parameters.parameters[0].element;
    expect(paramElement, new isInstanceOf<FieldFormalParameterElement>());
    expect((paramElement as FieldFormalParameterElement).field,
        field.fields.variables[0].element);
    ConstructorFieldInitializer initializer = constructor.initializers[0];
    SimpleIdentifier identifierX = initializer.expression;
    expect(identifierX.staticElement, paramElement);

    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_forEachLoops_nonConflicting() {
    Source source = addSource(r'''
f() {
  List list = [1,2,3];
  for (int x in list) {}
  for (int x in list) {}
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_forLoops_nonConflicting() {
    Source source = addSource(r'''
f() {
  for (int i = 0; i < 3; i++) {
  }
  for (int i = 0; i < 3; i++) {
  }
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_functionTypeAlias() {
    Source source = addSource(r'''
typedef bool P(e);
class A {
  P p;
  m(e) {
    if (p(e)) {}
  }
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_getter_and_setter_fromMixins_bare_identifier() {
    Source source = addSource('''
class B {}
class M1 {
  get x => null;
  set x(value) {}
}
class M2 {
  get x => null;
  set x(value) {}
}
class C extends B with M1, M2 {
  void f() {
    x += 1;
  }
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that both the getter and setter for "x" in C.f() refer to the
    // accessors defined in M2.
    ClassElement classC = library.definingCompilationUnit.types[3];
    MethodDeclaration f = classC.getMethod('f').computeNode();
    BlockFunctionBody body = f.body;
    ExpressionStatement stmt = body.block.statements[0];
    AssignmentExpression assignment = stmt.expression;
    SimpleIdentifier leftHandSide = assignment.leftHandSide;
    expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
    expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name,
        'M2');
  }

  @failingTest
  void test_getter_and_setter_fromMixins_property_access() {
    // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
    // a SimpleIdentifier that's inside a property access.  This bug should be
    // fixed.
    Source source = addSource('''
class B {}
class M1 {
  get x => null;
  set x(value) {}
}
class M2 {
  get x => null;
  set x(value) {}
}
class C extends B with M1, M2 {}
void main() {
  new C().x += 1;
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that both the getter and setter for "x" in "new C().x" refer to
    // the accessors defined in M2.
    FunctionDeclaration main =
        library.definingCompilationUnit.functions[0].computeNode();
    BlockFunctionBody body = main.functionExpression.body;
    ExpressionStatement stmt = body.block.statements[0];
    AssignmentExpression assignment = stmt.expression;
    PropertyAccess propertyAccess = assignment.leftHandSide;
    expect(
        propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
    expect(
        propertyAccess
            .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
        'M2');
  }

  void test_getter_fromMixins_bare_identifier() {
    Source source = addSource('''
class B {}
class M1 {
  get x => null;
}
class M2 {
  get x => null;
}
class C extends B with M1, M2 {
  f() {
    return x;
  }
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that the getter for "x" in C.f() refers to the getter defined in
    // M2.
    ClassElement classC = library.definingCompilationUnit.types[3];
    MethodDeclaration f = classC.getMethod('f').computeNode();
    BlockFunctionBody body = f.body;
    ReturnStatement stmt = body.block.statements[0];
    SimpleIdentifier x = stmt.expression;
    expect(x.staticElement.enclosingElement.name, 'M2');
  }

  void test_getter_fromMixins_property_access() {
    Source source = addSource('''
class B {}
class M1 {
  get x => null;
}
class M2 {
  get x => null;
}
class C extends B with M1, M2 {}
void main() {
  var y = new C().x;
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that the getter for "x" in "new C().x" refers to the getter
    // defined in M2.
    FunctionDeclaration main =
        library.definingCompilationUnit.functions[0].computeNode();
    BlockFunctionBody body = main.functionExpression.body;
    VariableDeclarationStatement stmt = body.block.statements[0];
    PropertyAccess propertyAccess = stmt.variables.variables[0].initializer;
    expect(
        propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
  }

  void test_getterAndSetterWithDifferentTypes() {
    Source source = addSource(r'''
class A {
  int get f => 0;
  void set f(String s) {}
}
g (A a) {
  a.f = a.f.toString();
}''');
    computeLibrarySourceErrors(source);
    assertErrors(
        source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
    verify([source]);
  }

  void test_hasReferenceToSuper() {
    Source source = addSource(r'''
class A {}
class B {toString() => super.toString();}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<ClassElement> classes = unit.types;
    expect(classes, hasLength(2));
    expect(classes[0].hasReferenceToSuper, isFalse);
    expect(classes[1].hasReferenceToSuper, isTrue);
    assertNoErrors(source);
    verify([source]);
  }

  void test_import_hide() {
    addNamedSource(
        "/lib1.dart",
        r'''
library lib1;
set foo(value) {}
class A {}''');
    addNamedSource(
        "/lib2.dart",
        r'''
library lib2;
set foo(value) {}''');
    Source source = addNamedSource(
        "/lib3.dart",
        r'''
import 'lib1.dart' hide foo;
import 'lib2.dart';

main() {
  foo = 0;
}
A a;''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_import_prefix() {
    addNamedSource(
        "/two.dart",
        r'''
library two;
f(int x) {
  return x * x;
}''');
    Source source = addNamedSource(
        "/one.dart",
        r'''
library one;
import 'two.dart' as _two;
main() {
  _two.f(0);
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_import_prefix_doesNotExist() {
    //
    // The primary purpose of this test is to ensure that we are only getting a
    // single error generated when the only problem is that an imported file
    // does not exist.
    //
    Source source = addNamedSource(
        "/a.dart",
        r'''
import 'missing.dart' as p;
int a = p.q + p.r.s;
String b = p.t(a) + p.u(v: 0);
p.T c = new p.T();
class D<E> extends p.T {
  D(int i) : super(i);
  p.U f = new p.V();
}
class F implements p.T {
  p.T m(p.U u) => null;
}
class G extends Object with p.V {}
class H extends D<p.W> {
  H(int i) : super(i);
}
''');
    computeLibrarySourceErrors(source);
    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
    verify([source]);
  }

  void test_import_show_doesNotExist() {
    //
    // The primary purpose of this test is to ensure that we are only getting a
    // single error generated when the only problem is that an imported file
    // does not exist.
    //
    Source source = addNamedSource(
        "/a.dart",
        r'''
import 'missing.dart' show q, r, t, u, T, U, V, W;
int a = q + r.s;
String b = t(a) + u(v: 0);
T c = new T();
class D<E> extends T {
  D(int i) : super(i);
  U f = new V();
}
class F implements T {
  T m(U u) => null;
}
class G extends Object with V {}
class H extends D<W> {
  H(int i) : super(i);
}
''');
    computeLibrarySourceErrors(source);
    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
    verify([source]);
  }

  void test_import_spaceInUri() {
    addNamedSource(
        "/sub folder/lib.dart",
        r'''
library lib;
foo() {}''');
    Source source = addNamedSource(
        "/app.dart",
        r'''
import 'sub folder/lib.dart';

main() {
  foo();
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_indexExpression_typeParameters() {
    Source source = addSource(r'''
f() {
  List<int> a;
  a[0];
  List<List<int>> b;
  b[0][0];
  List<List<List<int>>> c;
  c[0][0][0];
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_indexExpression_typeParameters_invalidAssignmentWarning() {
    Source source = addSource(r'''
f() {
  List<List<int>> b;
  b[0][0] = 'hi';
}''');
    computeLibrarySourceErrors(source);
    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
    verify([source]);
  }

  void test_indirectOperatorThroughCall() {
    Source source = addSource(r'''
class A {
  B call() { return new B(); }
}

class B {
  int operator [](int i) { return i; }
}

A f = new A();

g(int x) {}

main() {
  g(f()[0]);
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_invoke_dynamicThroughGetter() {
    Source source = addSource(r'''
class A {
  List get X => [() => 0];
  m(A a) {
    X.last;
  }
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_isValidMixin_badSuperclass() {
    Source source = addSource(r'''
class A extends B {}
class B {}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isFalse);
    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
    verify([source]);
  }

  void test_isValidMixin_badSuperclass_withSuperMixins() {
    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
    Source source = addSource(r'''
class A extends B {}
class B {}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isTrue);
    assertNoErrors(source);
    verify([source]);
  }

  void test_isValidMixin_constructor() {
    Source source = addSource(r'''
class A {
  A() {}
}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isFalse);
    assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
    verify([source]);
  }

  void test_isValidMixin_constructor_withSuperMixins() {
    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
    Source source = addSource(r'''
class A {
  A() {}
}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isFalse);
    assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
    verify([source]);
  }

  void test_isValidMixin_factoryConstructor() {
    Source source = addSource(r'''
class A {
  factory A() => null;
}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isTrue);
    assertNoErrors(source);
    verify([source]);
  }

  void test_isValidMixin_factoryConstructor_withSuperMixins() {
    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
    Source source = addSource(r'''
class A {
  factory A() => null;
}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isTrue);
    assertNoErrors(source);
    verify([source]);
  }

  void test_isValidMixin_super() {
    Source source = addSource(r'''
class A {
  toString() {
    return super.toString();
  }
}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isFalse);
    assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
    verify([source]);
  }

  void test_isValidMixin_super_withSuperMixins() {
    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
    Source source = addSource(r'''
class A {
  toString() {
    return super.toString();
  }
}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isTrue);
    assertNoErrors(source);
    verify([source]);
  }

  void test_isValidMixin_valid() {
    Source source = addSource('''
class A {}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isTrue);
    assertNoErrors(source);
    verify([source]);
  }

  void test_isValidMixin_valid_withSuperMixins() {
    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
    Source source = addSource('''
class A {}
class C = Object with A;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    ClassElement a = unit.getType('A');
    expect(a.isValidMixin, isTrue);
    assertNoErrors(source);
    verify([source]);
  }

  void test_labels_switch() {
    Source source = addSource(r'''
void doSwitch(int target) {
  switch (target) {
    l0: case 0:
      continue l1;
    l1: case 1:
      continue l0;
    default:
      continue l1;
  }
}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    assertNoErrors(source);
    verify([source]);
  }

  void test_localVariable_types_invoked() {
    Source source = addSource(r'''
const A = null;
main() {
  var myVar = (int p) => 'foo';
  myVar(42);
}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnit unit =
        analysisContext.resolveCompilationUnit(source, library);
    expect(unit, isNotNull);
    List<bool> found = [false];
    List<CaughtException> thrownException = new List<CaughtException>(1);
    unit.accept(new _SimpleResolverTest_localVariable_types_invoked(
        this, found, thrownException));
    if (thrownException[0] != null) {
      throw new AnalysisException(
          "Exception", new CaughtException(thrownException[0], null));
    }
    expect(found[0], isTrue);
  }

  void test_metadata_class() {
    Source source = addSource(r'''
const A = null;
@A class C<A> {}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unitElement = library.definingCompilationUnit;
    expect(unitElement, isNotNull);
    List<ClassElement> classes = unitElement.types;
    expect(classes, hasLength(1));
    List<ElementAnnotation> annotations = classes[0].metadata;
    expect(annotations, hasLength(1));
    assertNoErrors(source);
    verify([source]);
    CompilationUnit unit = resolveCompilationUnit(source, library);
    NodeList<CompilationUnitMember> declarations = unit.declarations;
    expect(declarations, hasLength(2));
    Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
        .variables
        .variables[0]
        .name
        .staticElement;
    EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
        PropertyInducingElement, expectedElement);
    expectedElement = (expectedElement as PropertyInducingElement).getter;
    Element actualElement =
        (declarations[1] as ClassDeclaration).metadata[0].name.staticElement;
    expect(actualElement, same(expectedElement));
  }

  void test_metadata_field() {
    Source source = addSource(r'''
const A = null;
class C {
  @A int f;
}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<ClassElement> classes = unit.types;
    expect(classes, hasLength(1));
    FieldElement field = classes[0].fields[0];
    List<ElementAnnotation> annotations = field.metadata;
    expect(annotations, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_fieldFormalParameter() {
    Source source = addSource(r'''
const A = null;
class C {
  int f;
  C(@A this.f);
}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<ClassElement> classes = unit.types;
    expect(classes, hasLength(1));
    List<ConstructorElement> constructors = classes[0].constructors;
    expect(constructors, hasLength(1));
    List<ParameterElement> parameters = constructors[0].parameters;
    expect(parameters, hasLength(1));
    List<ElementAnnotation> annotations = parameters[0].metadata;
    expect(annotations, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_function() {
    Source source = addSource(r'''
const A = null;
@A f() {}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<FunctionElement> functions = unit.functions;
    expect(functions, hasLength(1));
    List<ElementAnnotation> annotations = functions[0].metadata;
    expect(annotations, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_functionTypedParameter() {
    Source source = addSource(r'''
const A = null;
f(@A int p(int x)) {}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<FunctionElement> functions = unit.functions;
    expect(functions, hasLength(1));
    List<ParameterElement> parameters = functions[0].parameters;
    expect(parameters, hasLength(1));
    List<ElementAnnotation> annotations1 = parameters[0].metadata;
    expect(annotations1, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_libraryDirective() {
    Source source = addSource(r'''
@A library lib;
const A = null;''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    List<ElementAnnotation> annotations = library.metadata;
    expect(annotations, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_method() {
    Source source = addSource(r'''
const A = null;
class C {
  @A void m() {}
}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<ClassElement> classes = unit.types;
    expect(classes, hasLength(1));
    MethodElement method = classes[0].methods[0];
    List<ElementAnnotation> annotations = method.metadata;
    expect(annotations, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_namedParameter() {
    Source source = addSource(r'''
const A = null;
f({@A int p : 0}) {}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<FunctionElement> functions = unit.functions;
    expect(functions, hasLength(1));
    List<ParameterElement> parameters = functions[0].parameters;
    expect(parameters, hasLength(1));
    List<ElementAnnotation> annotations1 = parameters[0].metadata;
    expect(annotations1, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_positionalParameter() {
    Source source = addSource(r'''
const A = null;
f([@A int p = 0]) {}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<FunctionElement> functions = unit.functions;
    expect(functions, hasLength(1));
    List<ParameterElement> parameters = functions[0].parameters;
    expect(parameters, hasLength(1));
    List<ElementAnnotation> annotations1 = parameters[0].metadata;
    expect(annotations1, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_simpleParameter() {
    Source source = addSource(r'''
const A = null;
f(@A p1, @A int p2) {}''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unit = library.definingCompilationUnit;
    expect(unit, isNotNull);
    List<FunctionElement> functions = unit.functions;
    expect(functions, hasLength(1));
    List<ParameterElement> parameters = functions[0].parameters;
    expect(parameters, hasLength(2));
    List<ElementAnnotation> annotations1 = parameters[0].metadata;
    expect(annotations1, hasLength(1));
    List<ElementAnnotation> annotations2 = parameters[1].metadata;
    expect(annotations2, hasLength(1));
    assertNoErrors(source);
    verify([source]);
  }

  void test_metadata_typedef() {
    Source source = addSource(r'''
const A = null;
@A typedef F<A>();''');
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    CompilationUnitElement unitElement = library.definingCompilationUnit;
    expect(unitElement, isNotNull);
    List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases;
    expect(aliases, hasLength(1));
    List<ElementAnnotation> annotations = aliases[0].metadata;
    expect(annotations, hasLength(1));
    assertNoErrors(source);
    verify([source]);
    CompilationUnit unit = resolveCompilationUnit(source, library);
    NodeList<CompilationUnitMember> declarations = unit.declarations;
    expect(declarations, hasLength(2));
    Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
        .variables
        .variables[0]
        .name
        .staticElement;
    EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
        PropertyInducingElement, expectedElement);
    expectedElement = (expectedElement as PropertyInducingElement).getter;
    Element actualElement =
        (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement;
    expect(actualElement, same(expectedElement));
  }

  void test_method_fromMixin() {
    Source source = addSource(r'''
class B {
  bar() => 1;
}
class A {
  foo() => 2;
}

class C extends B with A {
  bar() => super.bar();
  foo() => super.foo();
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_method_fromMixins() {
    Source source = addSource('''
class B {}
class M1 {
  void f() {}
}
class M2 {
  void f() {}
}
class C extends B with M1, M2 {}
void main() {
  new C().f();
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that the "f" in "new C().f()" refers to the "f" defined in M2.
    FunctionDeclaration main =
        library.definingCompilationUnit.functions[0].computeNode();
    BlockFunctionBody body = main.functionExpression.body;
    ExpressionStatement stmt = body.block.statements[0];
    MethodInvocation expr = stmt.expression;
    expect(expr.methodName.staticElement.enclosingElement.name, 'M2');
  }

  void test_method_fromMixins_bare_identifier() {
    Source source = addSource('''
class B {}
class M1 {
  void f() {}
}
class M2 {
  void f() {}
}
class C extends B with M1, M2 {
  void g() {
    f();
  }
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that the call to f() in C.g() refers to the method defined in M2.
    ClassElement classC = library.definingCompilationUnit.types[3];
    MethodDeclaration g = classC.getMethod('g').computeNode();
    BlockFunctionBody body = g.body;
    ExpressionStatement stmt = body.block.statements[0];
    MethodInvocation invocation = stmt.expression;
    SimpleIdentifier methodName = invocation.methodName;
    expect(methodName.staticElement.enclosingElement.name, 'M2');
  }

  void test_method_fromMixins_invked_from_outside_class() {
    Source source = addSource('''
class B {}
class M1 {
  void f() {}
}
class M2 {
  void f() {}
}
class C extends B with M1, M2 {}
void main() {
  new C().f();
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that the call to f() in "new C().f()" refers to the method
    // defined in M2.
    FunctionDeclaration main =
        library.definingCompilationUnit.functions[0].computeNode();
    BlockFunctionBody body = main.functionExpression.body;
    ExpressionStatement stmt = body.block.statements[0];
    MethodInvocation invocation = stmt.expression;
    expect(invocation.methodName.staticElement.enclosingElement.name, 'M2');
  }

  void test_method_fromSuperclassMixin() {
    Source source = addSource(r'''
class A {
  void m1() {}
}
class B extends Object with A {
}
class C extends B {
}
f(C c) {
  c.m1();
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_methodCascades() {
    Source source = addSource(r'''
class A {
  void m1() {}
  void m2() {}
  void m() {
    A a = new A();
    a..m1()
     ..m2();
  }
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_methodCascades_withSetter() {
    Source source = addSource(r'''
class A {
  String name;
  void m1() {}
  void m2() {}
  void m() {
    A a = new A();
    a..m1()
     ..name = 'name'
     ..m2();
  }
}''');
    computeLibrarySourceErrors(source);
    // failing with error code: INVOCATION_OF_NON_FUNCTION
    assertNoErrors(source);
    verify([source]);
  }

  void test_resolveAgainstNull() {
    Source source = addSource(r'''
f(var p) {
  return null == p;
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
  }

  void test_setter_fromMixins_bare_identifier() {
    Source source = addSource('''
class B {}
class M1 {
  set x(value) {}
}
class M2 {
  set x(value) {}
}
class C extends B with M1, M2 {
  void f() {
    x = 1;
  }
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that the setter for "x" in C.f() refers to the setter defined in
    // M2.
    ClassElement classC = library.definingCompilationUnit.types[3];
    MethodDeclaration f = classC.getMethod('f').computeNode();
    BlockFunctionBody body = f.body;
    ExpressionStatement stmt = body.block.statements[0];
    AssignmentExpression assignment = stmt.expression;
    SimpleIdentifier leftHandSide = assignment.leftHandSide;
    expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
  }

  void test_setter_fromMixins_property_access() {
    Source source = addSource('''
class B {}
class M1 {
  set x(value) {}
}
class M2 {
  set x(value) {}
}
class C extends B with M1, M2 {}
void main() {
  new C().x = 1;
}
''');
    LibraryElement library = resolve2(source);
    assertNoErrors(source);
    verify([source]);
    // Verify that the setter for "x" in "new C().x" refers to the setter
    // defined in M2.
    FunctionDeclaration main =
        library.definingCompilationUnit.functions[0].computeNode();
    BlockFunctionBody body = main.functionExpression.body;
    ExpressionStatement stmt = body.block.statements[0];
    AssignmentExpression assignment = stmt.expression;
    PropertyAccess propertyAccess = assignment.leftHandSide;
    expect(
        propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
  }

  void test_setter_inherited() {
    Source source = addSource(r'''
class A {
  int get x => 0;
  set x(int p) {}
}
class B extends A {
  int get x => super.x == null ? 0 : super.x;
  int f() => x = 1;
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  void test_setter_static() {
    Source source = addSource(r'''
set s(x) {
}

main() {
  s = 123;
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  @failingTest
  void test_staticInvocation() {
    Source source = addSource(r'''
class A {
  static int get g => (a,b) => 0;
}
class B {
  f() {
    A.g(1,0);
  }
}''');
    computeLibrarySourceErrors(source);
    assertNoErrors(source);
    verify([source]);
  }

  /**
   * Resolve the given source and verify that the arguments in a specific method invocation were
   * correctly resolved.
   *
   * The source is expected to be source for a compilation unit, the first declaration is expected
   * to be a class, the first member of which is expected to be a method with a block body, and the
   * first statement in the body is expected to be an expression statement whose expression is a
   * method invocation. It is the arguments to that method invocation that are tested. The method
   * invocation can contain errors.
   *
   * The arguments were resolved correctly if the number of expressions in the list matches the
   * length of the array of indices and if, for each index in the array of indices, the parameter to
   * which the argument expression was resolved is the parameter in the invoked method's list of
   * parameters at that index. Arguments that should not be resolved to a parameter because of an
   * error can be denoted by including a negative index in the array of indices.
   *
   * @param source the source to be resolved
   * @param indices the array of indices used to associate arguments with parameters
   * @throws Exception if the source could not be resolved or if the structure of the source is not
   *           valid
   */
  void _validateArgumentResolution(Source source, List<int> indices) {
    LibraryElement library = resolve2(source);
    expect(library, isNotNull);
    ClassElement classElement = library.definingCompilationUnit.types[0];
    List<ParameterElement> parameters = classElement.methods[1].parameters;
    CompilationUnit unit = resolveCompilationUnit(source, library);
    expect(unit, isNotNull);
    ClassDeclaration classDeclaration =
        unit.declarations[0] as ClassDeclaration;
    MethodDeclaration methodDeclaration =
        classDeclaration.members[0] as MethodDeclaration;
    Block block = (methodDeclaration.body as BlockFunctionBody).block;
    ExpressionStatement statement = block.statements[0] as ExpressionStatement;
    MethodInvocation invocation = statement.expression as MethodInvocation;
    NodeList<Expression> arguments = invocation.argumentList.arguments;
    int argumentCount = arguments.length;
    expect(argumentCount, indices.length);
    for (int i = 0; i < argumentCount; i++) {
      Expression argument = arguments[i];
      ParameterElement element = argument.staticParameterElement;
      int index = indices[i];
      if (index < 0) {
        expect(element, isNull);
      } else {
        expect(element, same(parameters[index]));
      }
    }
  }
}

class _SimpleResolverTest_localVariable_types_invoked
    extends RecursiveAstVisitor<Object> {
  final SimpleResolverTest test;

  List<bool> found;

  List<CaughtException> thrownException;

  _SimpleResolverTest_localVariable_types_invoked(
      this.test, this.found, this.thrownException)
      : super();

  @override
  Object visitSimpleIdentifier(SimpleIdentifier node) {
    if (node.name == "myVar" && node.parent is MethodInvocation) {
      try {
        found[0] = true;
        // check static type
        DartType staticType = node.staticType;
        expect(staticType, same(test.typeProvider.dynamicType));
        // check propagated type
        FunctionType propagatedType = node.propagatedType as FunctionType;
        expect(propagatedType.returnType, test.typeProvider.stringType);
      } on AnalysisException catch (e, stackTrace) {
        thrownException[0] = new CaughtException(e, stackTrace);
      }
    }
    return null;
  }
}
