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

import 'dart:async';
import 'dart:collection';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/token.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/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/source/source_resource.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'analysis_context_factory.dart';
import 'parser_test.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnalysisDeltaTest);
    defineReflectiveTests(ChangeSetTest);
    defineReflectiveTests(EnclosedScopeTest);
    defineReflectiveTests(ErrorResolverTest);
    defineReflectiveTests(LibraryImportScopeTest);
    defineReflectiveTests(LibraryScopeTest);
    defineReflectiveTests(PrefixedNamespaceTest);
    defineReflectiveTests(ScopeTest);
    defineReflectiveTests(StrictModeTest);
    defineReflectiveTests(TypeOverrideManagerTest);
    defineReflectiveTests(TypePropagationTest);
    defineReflectiveTests(TypeProviderImplTest);
    defineReflectiveTests(TypeResolverVisitorTest);
  });
}

/// Wrapper around the test package's `fail` function.
///
/// Unlike the test package's `fail` function, this function is not annotated
/// with @alwaysThrows, so we can call it at the top of a test method without
/// causing the rest of the method to be flagged as dead code.
void _fail(String message) {
  fail(message);
}

@reflectiveTest
class AnalysisDeltaTest extends EngineTestCase {
  TestSource source1 = new TestSource('/1.dart');
  TestSource source2 = new TestSource('/2.dart');
  TestSource source3 = new TestSource('/3.dart');

  void test_getAddedSources() {
    AnalysisDelta delta = new AnalysisDelta();
    delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
    delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
    delta.setAnalysisLevel(source3, AnalysisLevel.NONE);
    List<Source> addedSources = delta.addedSources;
    expect(addedSources, hasLength(2));
    expect(addedSources, unorderedEquals([source1, source2]));
  }

  void test_getAnalysisLevels() {
    AnalysisDelta delta = new AnalysisDelta();
    expect(delta.analysisLevels.length, 0);
  }

  void test_setAnalysisLevel() {
    AnalysisDelta delta = new AnalysisDelta();
    delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
    delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
    Map<Source, AnalysisLevel> levels = delta.analysisLevels;
    expect(levels.length, 2);
    expect(levels[source1], AnalysisLevel.ALL);
    expect(levels[source2], AnalysisLevel.ERRORS);
  }

  void test_toString() {
    AnalysisDelta delta = new AnalysisDelta();
    delta.setAnalysisLevel(new TestSource(), AnalysisLevel.ALL);
    String result = delta.toString();
    expect(result, isNotNull);
    expect(result.length > 0, isTrue);
  }
}

@reflectiveTest
class ChangeSetTest extends EngineTestCase {
  void test_changedContent() {
    TestSource source = new TestSource();
    String content = "";
    ChangeSet changeSet = new ChangeSet();
    changeSet.changedContent(source, content);
    expect(changeSet.addedSources, hasLength(0));
    expect(changeSet.changedSources, hasLength(0));
    Map<Source, String> map = changeSet.changedContents;
    expect(map, hasLength(1));
    expect(map[source], same(content));
    expect(changeSet.changedRanges, hasLength(0));
    expect(changeSet.removedSources, hasLength(0));
    expect(changeSet.removedContainers, hasLength(0));
  }

  void test_changedRange() {
    TestSource source = new TestSource();
    String content = "";
    ChangeSet changeSet = new ChangeSet();
    changeSet.changedRange(source, content, 1, 2, 3);
    expect(changeSet.addedSources, hasLength(0));
    expect(changeSet.changedSources, hasLength(0));
    expect(changeSet.changedContents, hasLength(0));
    Map<Source, ChangeSet_ContentChange> map = changeSet.changedRanges;
    expect(map, hasLength(1));
    ChangeSet_ContentChange change = map[source];
    expect(change, isNotNull);
    expect(change.contents, content);
    expect(change.offset, 1);
    expect(change.oldLength, 2);
    expect(change.newLength, 3);
    expect(changeSet.removedSources, hasLength(0));
    expect(changeSet.removedContainers, hasLength(0));
  }

  void test_toString() {
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(new TestSource());
    changeSet.changedSource(new TestSource());
    changeSet.changedContent(new TestSource(), "");
    changeSet.changedRange(new TestSource(), "", 0, 0, 0);
    changeSet.removedSource(new TestSource());
    changeSet
        .removedContainer(new SourceContainer_ChangeSetTest_test_toString());
    expect(changeSet.toString(), isNotNull);
  }
}

@reflectiveTest
class EnclosedScopeTest extends ResolverTestCase {
  test_define_duplicate() async {
    Scope rootScope = new _RootScope();
    EnclosedScope scope = new EnclosedScope(rootScope);
    SimpleIdentifier identifier = AstTestFactory.identifier3('v');
    VariableElement element1 = ElementFactory.localVariableElement(identifier);
    VariableElement element2 = ElementFactory.localVariableElement(identifier);
    scope.define(element1);
    scope.define(element2);
    expect(scope.lookup(identifier, null), same(element1));
  }
}

@reflectiveTest
class ErrorResolverTest extends ResolverTestCase {
  test_breakLabelOnSwitchMember() async {
    Source source = addSource(r'''
class A {
  void m(int i) {
    switch (i) {
      l: case 0:
        break;
      case 1:
        break l;
    }
  }
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
    verify([source]);
  }

  test_continueLabelOnSwitch() async {
    Source source = addSource(r'''
class A {
  void m(int i) {
    l: switch (i) {
      case 0:
        continue l;
    }
  }
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
    verify([source]);
  }

  test_enclosingElement_invalidLocalFunction() async {
    String code = r'''
class C {
  C() {
    int get x => 0;
  }
}''';
    Source source = addSource(code);

    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
    assertErrors(source, [
      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
      ParserErrorCode.EXPECTED_TOKEN
    ]);

    CompilationUnitElement unit = analysisResult.unit.declaredElement;
    LibraryElement library = unit.library;
    expect(library, isNotNull);
    expect(unit.enclosingElement, same(library));

    var types = unit.types;
    expect(types, hasLength(1));
    var type = types[0];
    expect(type, isNotNull);

    var constructors = type.constructors;
    expect(constructors, hasLength(1));
    ConstructorElement constructor = constructors[0];
    expect(constructor, isNotNull);

    FunctionElement x = findElementsByName(analysisResult.unit, 'x').single;
    expect(x.enclosingElement, constructor);
  }
}

/**
 * Tests for generic method and function resolution that do not use strong mode.
 */
@reflectiveTest
class GenericMethodResolverTest extends StaticTypeAnalyzer2TestShared {
  test_genericMethod_propagatedType_promotion() async {
    // Regression test for:
    // https://github.com/dart-lang/sdk/issues/25340
    //
    // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
    // strong mode example won't work, as we now compute a static type and
    // therefore discard the propagated type.
    //
    // So this test does not use strong mode.
    await resolveTestUnit(r'''
abstract class Iter {
  List<S> map<S>(S f(x));
}
class C {}
C toSpan(dynamic element) {
  if (element is Iter) {
    var y = element.map(toSpan);
  }
  return null;
}''');
    expectIdentifierType('y = ', 'dynamic');
  }
}

@reflectiveTest
class LibraryImportScopeTest extends ResolverTestCase {
  void test_creation_empty() {
    new LibraryImportScope(createDefaultTestLibrary());
  }

  void test_creation_nonEmpty() {
    AnalysisContext context = AnalysisContextFactory.contextWithCore(
        resourceProvider: resourceProvider);
    String importedTypeName = "A";
    ClassElement importedType = new ClassElementImpl.forNode(
        AstTestFactory.identifier3(importedTypeName));
    LibraryElement importedLibrary = createTestLibrary(context, "imported");
    (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
        .types = <ClassElement>[importedType];
    LibraryElementImpl definingLibrary =
        createTestLibrary(context, "importing");
    ImportElementImpl importElement = new ImportElementImpl(0);
    importElement.importedLibrary = importedLibrary;
    definingLibrary.imports = <ImportElement>[importElement];
    Scope scope = new LibraryImportScope(definingLibrary);
    expect(
        scope.lookup(
            AstTestFactory.identifier3(importedTypeName), definingLibrary),
        importedType);
  }

  void test_prefixedAndNonPrefixed() {
    AnalysisContext context = AnalysisContextFactory.contextWithCore(
        resourceProvider: resourceProvider);
    String typeName = "C";
    String prefixName = "p";
    ClassElement prefixedType = ElementFactory.classElement2(typeName);
    ClassElement nonPrefixedType = ElementFactory.classElement2(typeName);
    LibraryElement prefixedLibrary =
        createTestLibrary(context, "import.prefixed");
    (prefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
        .types = <ClassElement>[prefixedType];
    ImportElementImpl prefixedImport = ElementFactory.importFor(
        prefixedLibrary, ElementFactory.prefix(prefixName));
    LibraryElement nonPrefixedLibrary =
        createTestLibrary(context, "import.nonPrefixed");
    (nonPrefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
        .types = <ClassElement>[nonPrefixedType];
    ImportElementImpl nonPrefixedImport =
        ElementFactory.importFor(nonPrefixedLibrary, null);
    LibraryElementImpl importingLibrary =
        createTestLibrary(context, "importing");
    importingLibrary.imports = <ImportElement>[
      prefixedImport,
      nonPrefixedImport
    ];
    Scope scope = new LibraryImportScope(importingLibrary);
    Element prefixedElement = scope.lookup(
        AstTestFactory.identifier5(prefixName, typeName), importingLibrary);
    expect(prefixedElement, same(prefixedType));
    Element nonPrefixedElement =
        scope.lookup(AstTestFactory.identifier3(typeName), importingLibrary);
    expect(nonPrefixedElement, same(nonPrefixedType));
  }
}

@reflectiveTest
class LibraryScopeTest extends ResolverTestCase {
  void test_creation_empty() {
    new LibraryScope(createDefaultTestLibrary());
  }

  void test_creation_nonEmpty() {
    AnalysisContext context = AnalysisContextFactory.contextWithCore(
        resourceProvider: resourceProvider);
    String importedTypeName = "A";
    ClassElement importedType = new ClassElementImpl.forNode(
        AstTestFactory.identifier3(importedTypeName));
    LibraryElement importedLibrary = createTestLibrary(context, "imported");
    (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
        .types = <ClassElement>[importedType];
    LibraryElementImpl definingLibrary =
        createTestLibrary(context, "importing");
    ImportElementImpl importElement = new ImportElementImpl(0);
    importElement.importedLibrary = importedLibrary;
    definingLibrary.imports = <ImportElement>[importElement];
    Scope scope = new LibraryScope(definingLibrary);
    expect(
        scope.lookup(
            AstTestFactory.identifier3(importedTypeName), definingLibrary),
        importedType);
  }
}

@reflectiveTest
class PrefixedNamespaceTest extends ResolverTestCase {
  void test_lookup_missing() {
    ClassElement element = ElementFactory.classElement2('A');
    PrefixedNamespace namespace = new PrefixedNamespace('p', _toMap([element]));
    expect(namespace.get('p.B'), isNull);
  }

  void test_lookup_missing_matchesPrefix() {
    ClassElement element = ElementFactory.classElement2('A');
    PrefixedNamespace namespace = new PrefixedNamespace('p', _toMap([element]));
    expect(namespace.get('p'), isNull);
  }

  void test_lookup_valid() {
    ClassElement element = ElementFactory.classElement2('A');
    PrefixedNamespace namespace = new PrefixedNamespace('p', _toMap([element]));
    expect(namespace.get('p.A'), same(element));
  }

  Map<String, Element> _toMap(List<Element> elements) {
    Map<String, Element> map = new HashMap<String, Element>();
    for (Element element in elements) {
      map[element.name] = element;
    }
    return map;
  }
}

@reflectiveTest
class ScopeTest extends ResolverTestCase {
  void test_define_duplicate() {
    Scope scope = new _RootScope();
    SimpleIdentifier identifier = AstTestFactory.identifier3('v');
    VariableElement element1 = ElementFactory.localVariableElement(identifier);
    VariableElement element2 = ElementFactory.localVariableElement(identifier);
    scope.define(element1);
    scope.define(element2);
    expect(scope.localLookup('v', null), same(element1));
  }

  void test_isPrivateName_nonPrivate() {
    expect(Scope.isPrivateName("Public"), isFalse);
  }

  void test_isPrivateName_private() {
    expect(Scope.isPrivateName("_Private"), isTrue);
  }
}

class SourceContainer_ChangeSetTest_test_toString implements SourceContainer {
  @override
  bool contains(Source source) => false;
}

/**
 * Instances of the class `StaticTypeVerifier` verify that all of the nodes in an AST
 * structure that should have a static type associated with them do have a static type.
 */
class StaticTypeVerifier extends GeneralizingAstVisitor<Object> {
  /**
   * A list containing all of the AST Expression nodes that were not resolved.
   */
  List<Expression> _unresolvedExpressions = new List<Expression>();

  /**
   * The TypeAnnotation nodes that were not resolved.
   */
  List<TypeAnnotation> _unresolvedTypes = new List<TypeAnnotation>();

  /**
   * Counter for the number of Expression nodes visited that are resolved.
   */
  int _resolvedExpressionCount = 0;

  /**
   * Counter for the number of TypeName nodes visited that are resolved.
   */
  int _resolvedTypeCount = 0;

  /**
   * Assert that all of the visited nodes have a static type associated with them.
   */
  void assertResolved() {
    if (!_unresolvedExpressions.isEmpty || !_unresolvedTypes.isEmpty) {
      StringBuffer buffer = new StringBuffer();
      int unresolvedTypeCount = _unresolvedTypes.length;
      if (unresolvedTypeCount > 0) {
        buffer.write("Failed to resolve ");
        buffer.write(unresolvedTypeCount);
        buffer.write(" of ");
        buffer.write(_resolvedTypeCount + unresolvedTypeCount);
        buffer.writeln(" type names:");
        for (TypeAnnotation identifier in _unresolvedTypes) {
          buffer.write("  ");
          buffer.write(identifier.toString());
          buffer.write(" (");
          buffer.write(_getFileName(identifier));
          buffer.write(" : ");
          buffer.write(identifier.offset);
          buffer.writeln(")");
        }
      }
      int unresolvedExpressionCount = _unresolvedExpressions.length;
      if (unresolvedExpressionCount > 0) {
        buffer.writeln("Failed to resolve ");
        buffer.write(unresolvedExpressionCount);
        buffer.write(" of ");
        buffer.write(_resolvedExpressionCount + unresolvedExpressionCount);
        buffer.writeln(" expressions:");
        for (Expression expression in _unresolvedExpressions) {
          buffer.write("  ");
          buffer.write(expression.toString());
          buffer.write(" (");
          buffer.write(_getFileName(expression));
          buffer.write(" : ");
          buffer.write(expression.offset);
          buffer.writeln(")");
        }
      }
      fail(buffer.toString());
    }
  }

  @override
  Object visitBreakStatement(BreakStatement node) => null;

  @override
  Object visitCommentReference(CommentReference node) => null;

  @override
  Object visitContinueStatement(ContinueStatement node) => null;

  @override
  Object visitExportDirective(ExportDirective node) => null;

  @override
  Object visitExpression(Expression node) {
    node.visitChildren(this);
    DartType staticType = node.staticType;
    if (staticType == null) {
      _unresolvedExpressions.add(node);
    } else {
      _resolvedExpressionCount++;
    }
    return null;
  }

  @override
  Object visitImportDirective(ImportDirective node) => null;

  @override
  Object visitLabel(Label node) => null;

  @override
  Object visitLibraryIdentifier(LibraryIdentifier node) => null;

  @override
  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
    // In cases where we have a prefixed identifier where the prefix is dynamic,
    // we don't want to assert that the node will have a type.
    if (node.staticType == null &&
        resolutionMap.staticTypeForExpression(node.prefix).isDynamic) {
      return null;
    }
    return super.visitPrefixedIdentifier(node);
  }

  @override
  Object visitSimpleIdentifier(SimpleIdentifier node) {
    // In cases where identifiers are being used for something other than an
    // expressions, then they can be ignored.
    AstNode parent = node.parent;
    if (parent is MethodInvocation && identical(node, parent.methodName)) {
      return null;
    } else if (parent is RedirectingConstructorInvocation &&
        identical(node, parent.constructorName)) {
      return null;
    } else if (parent is SuperConstructorInvocation &&
        identical(node, parent.constructorName)) {
      return null;
    } else if (parent is ConstructorName && identical(node, parent.name)) {
      return null;
    } else if (parent is ConstructorFieldInitializer &&
        identical(node, parent.fieldName)) {
      return null;
    } else if (node.staticElement is PrefixElement) {
      // Prefixes don't have a type.
      return null;
    }
    return super.visitSimpleIdentifier(node);
  }

  @override
  Object visitTypeAnnotation(TypeAnnotation node) {
    if (node.type == null) {
      _unresolvedTypes.add(node);
    } else {
      _resolvedTypeCount++;
    }
    return super.visitTypeAnnotation(node);
  }

  @override
  Object visitTypeName(TypeName node) {
    // Note: do not visit children from this node, the child SimpleIdentifier in
    // TypeName (i.e. "String") does not have a static type defined.
    // TODO(brianwilkerson) Not visiting the children means that we won't catch
    // type arguments that were not resolved.
    if (node.type == null) {
      _unresolvedTypes.add(node);
    } else {
      _resolvedTypeCount++;
    }
    return null;
  }

  String _getFileName(AstNode node) {
    // TODO (jwren) there are two copies of this method, one here and one in
    // ResolutionVerifier, they should be resolved into a single method
    if (node != null) {
      AstNode root = node.root;
      if (root is CompilationUnit) {
        CompilationUnit rootCU = root;
        if (rootCU.declaredElement != null) {
          return resolutionMap
              .elementDeclaredByCompilationUnit(rootCU)
              .source
              .fullName;
        } else {
          return "<unknown file- CompilationUnit.getElement() returned null>";
        }
      } else {
        return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
      }
    }
    return "<unknown file- ASTNode is null>";
  }
}

/**
 * The class `StrictModeTest` contains tests to ensure that the correct errors and warnings
 * are reported when the analysis engine is run in strict mode.
 */
@reflectiveTest
class StrictModeTest extends ResolverTestCase {
  fail_for() async {
    Source source = addSource(r'''
int f(List<int> list) {
  num sum = 0;
  for (num i = 0; i < list.length; i++) {
    sum += list[i];
  }
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  @override
  void setUp() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    options.hint = false;
    resetWith(options: options);
  }

  test_assert_is() async {
    Source source = addSource(r'''
int f(num n) {
  assert (n is int);
  return n & 0x0F;
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  test_conditional_and_is() async {
    Source source = addSource(r'''
int f(num n) {
  return (n is int && n > 0) ? n & 0x0F : 0;
}''');
    await computeAnalysisResult(source);
    assertNoErrors(source);
  }

  test_conditional_is() async {
    Source source = addSource(r'''
int f(num n) {
  return (n is int) ? n & 0x0F : 0;
}''');
    await computeAnalysisResult(source);
    assertNoErrors(source);
  }

  test_conditional_isNot() async {
    Source source = addSource(r'''
int f(num n) {
  return (n is! int) ? 0 : n & 0x0F;
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  test_conditional_or_is() async {
    Source source = addSource(r'''
int f(num n) {
  return (n is! int || n < 0) ? 0 : n & 0x0F;
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  test_forEach() async {
    Source source = addSource(r'''
int f(List<int> list) {
  num sum = 0;
  for (num n in list) {
    sum += n & 0x0F;
  }
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  test_if_and_is() async {
    Source source = addSource(r'''
int f(num n) {
  if (n is int && n > 0) {
    return n & 0x0F;
  }
  return 0;
}''');
    await computeAnalysisResult(source);
    assertNoErrors(source);
  }

  test_if_is() async {
    Source source = addSource(r'''
int f(num n) {
  if (n is int) {
    return n & 0x0F;
  }
  return 0;
}''');
    await computeAnalysisResult(source);
    assertNoErrors(source);
  }

  test_if_isNot() async {
    Source source = addSource(r'''
int f(num n) {
  if (n is! int) {
    return 0;
  } else {
    return n & 0x0F;
  }
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  test_if_isNot_abrupt() async {
    Source source = addSource(r'''
int f(num n) {
  if (n is! int) {
    return 0;
  }
  return n & 0x0F;
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  test_if_or_is() async {
    Source source = addSource(r'''
int f(num n) {
  if (n is! int || n < 0) {
    return 0;
  } else {
    return n & 0x0F;
  }
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  test_localVar() async {
    Source source = addSource(r'''
int f() {
  num n = 1234;
  return n & 0x0F;
}''');
    await computeAnalysisResult(source);
    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }
}

@reflectiveTest
class TypeOverrideManagerTest extends EngineTestCase {
  void test_exitScope_noScopes() {
    TypeOverrideManager manager = new TypeOverrideManager();
    expect(() {
      manager.exitScope();
    }, throwsStateError);
  }

  void test_exitScope_oneScope() {
    TypeOverrideManager manager = new TypeOverrideManager();
    manager.enterScope();
    manager.exitScope();
    expect(() {
      manager.exitScope();
    }, throwsStateError);
  }

  void test_exitScope_twoScopes() {
    TypeOverrideManager manager = new TypeOverrideManager();
    manager.enterScope();
    manager.exitScope();
    manager.enterScope();
    manager.exitScope();
    expect(() {
      manager.exitScope();
    }, throwsStateError);
  }

  void test_getType_enclosedOverride() {
    TypeOverrideManager manager = new TypeOverrideManager();
    LocalVariableElementImpl element =
        ElementFactory.localVariableElement2("v");
    InterfaceType type = ElementFactory.classElement2("C").type;
    manager.enterScope();
    manager.setType(element, type);
    manager.enterScope();
    expect(manager.getType(element), same(type));
  }

  void test_getType_immediateOverride() {
    TypeOverrideManager manager = new TypeOverrideManager();
    LocalVariableElementImpl element =
        ElementFactory.localVariableElement2("v");
    InterfaceType type = ElementFactory.classElement2("C").type;
    manager.enterScope();
    manager.setType(element, type);
    expect(manager.getType(element), same(type));
  }

  void test_getType_noOverride() {
    TypeOverrideManager manager = new TypeOverrideManager();
    manager.enterScope();
    expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
  }

  void test_getType_noScope() {
    TypeOverrideManager manager = new TypeOverrideManager();
    expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
  }
}

@reflectiveTest
class TypePropagationTest extends ResolverTestCase {
  fail_propagatedReturnType_functionExpression() async {
    // TODO(scheglov) disabled because we don't resolve function expression
    String code = r'''
main() {
  var v = (() {return 42;})();
}''';
    CompilationUnit unit = await resolveSource(code);
    assertAssignedType(code, unit, typeProvider.dynamicType);
  }

  test_assignment_null() async {
    String code = r'''
main() {
  int v; // declare
  v = null;
  return v; // return
}''';
    CompilationUnit unit;
    {
      Source source = addSource(code);
      TestAnalysisResult analysisResult = await computeAnalysisResult(source);
      assertNoErrors(source);
      verify([source]);
      unit = analysisResult.unit;
    }
    {
      SimpleIdentifier identifier = EngineTestCase.findNode(
          unit, code, "v; // declare", (node) => node is SimpleIdentifier);
      expect(identifier.staticType, typeProvider.intType);
    }
    {
      SimpleIdentifier identifier = EngineTestCase.findNode(
          unit, code, "v = null;", (node) => node is SimpleIdentifier);
      expect(identifier.staticType, typeProvider.intType);
    }
    {
      SimpleIdentifier identifier = EngineTestCase.findNode(
          unit, code, "v; // return", (node) => node is SimpleIdentifier);
      expect(identifier.staticType, typeProvider.intType);
    }
  }

  test_functionExpression_asInvocationArgument() async {
    if (previewDart2) {
      return;
    }
    String code = r'''
class MyMap<K, V> {
  forEach(f(K key, V value)) {}
}
f(MyMap<int, String> m) {
  m.forEach((k, v) {
    k;
    v;
  });
}''';
    Source source = addSource(code);
    CompilationUnit unit = await _computeResolvedUnit(source);
    // k
    SimpleIdentifier kIdentifier = EngineTestCase.findNode(
        unit, code, "k;", (node) => node is SimpleIdentifier);
    expect(kIdentifier.staticType, typeProvider.dynamicType);
    // v
    SimpleIdentifier vIdentifier = EngineTestCase.findNode(
        unit, code, "v;", (node) => node is SimpleIdentifier);
    expect(vIdentifier.staticType, typeProvider.dynamicType);
  }

  test_functionExpression_asInvocationArgument_functionExpressionInvocation() async {
    if (previewDart2) {
      return;
    }
    String code = r'''
main() {
  (f(String value)) {} ((v) {
    v;
  });
}''';
    Source source = addSource(code);
    CompilationUnit unit = await _computeResolvedUnit(source);
    // v
    FormalParameter vParameter = EngineTestCase.findNode(
        unit, code, "v)", (node) => node is FormalParameter);
    expect(vParameter.identifier.staticType, typeProvider.dynamicType);
    SimpleIdentifier vIdentifier = EngineTestCase.findNode(
        unit, code, "v;", (node) => node is SimpleIdentifier);
    expect(vIdentifier.staticType, typeProvider.dynamicType);
  }

  test_functionExpression_asInvocationArgument_keepIfLessSpecific() async {
    if (previewDart2) {
      return;
    }
    String code = r'''
class MyList {
  forEach(f(Object value)) {}
}
f(MyList list) {
  list.forEach((int v) {
    v;
  });
}''';
    Source source = addSource(code);
    CompilationUnit unit = await _computeResolvedUnit(source);
    // v
    FormalParameter vParameter = EngineTestCase.findNode(
        unit, code, "v)", (node) => node is SimpleFormalParameter);
    expect(vParameter.identifier.staticType, typeProvider.intType);
    SimpleIdentifier vIdentifier = EngineTestCase.findNode(
        unit, code, "v;", (node) => node is SimpleIdentifier);
    expect(vIdentifier.staticType, typeProvider.intType);
  }

  test_functionExpression_asInvocationArgument_notSubtypeOfStaticType() async {
    String code = r'''
class A {
  m(void f(int i)) {}
}
x() {
  A a = new A();
  a.m(() => 0);
}''';
    Source source = addSource(code);
    CompilationUnit unit = await _computeResolvedUnit(source, noErrors: false);
    assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
    // () => 0
    FunctionExpression functionExpression = EngineTestCase.findNode(
        unit, code, "() => 0)", (node) => node is FunctionExpression);
    expect((functionExpression.staticType as FunctionType).parameters.length,
        same(0));
  }

  test_functionExpression_asInvocationArgument_replaceIfMoreSpecific() async {
    if (previewDart2) {
      return;
    }
    String code = r'''
class MyList<E> {
  forEach(f(E value)) {}
}
f(MyList<String> list) {
  list.forEach((Object v) {
    v;
  });
}''';
    Source source = addSource(code);
    CompilationUnit unit = await _computeResolvedUnit(source);
    // v
    FormalParameter vParameter = EngineTestCase.findNode(
        unit, code, "v)", (node) => node is SimpleFormalParameter);
    expect(vParameter.identifier.staticType, typeProvider.objectType);
  }

  test_initializer() async {
    if (previewDart2) {
      return;
    }
    Source source = addSource(r'''
f() {
  var v = 0;
  return v;
}''');
    CompilationUnit unit = await _computeResolvedUnit(source);
    FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
    BlockFunctionBody body =
        function.functionExpression.body as BlockFunctionBody;
    NodeList<Statement> statements = body.block.statements;
    // Type of 'v' in declaration.
    {
      VariableDeclarationStatement statement =
          statements[0] as VariableDeclarationStatement;
      SimpleIdentifier variableName = statement.variables.variables[0].name;
      expect(variableName.staticType, typeProvider.dynamicType);
    }
  }

  test_initializer_hasStaticType() async {
    Source source = addSource(r'''
f() {
  int v = 0;
  return v;
}''');
    CompilationUnit unit = await _computeResolvedUnit(source);
    FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
    BlockFunctionBody body =
        function.functionExpression.body as BlockFunctionBody;
    NodeList<Statement> statements = body.block.statements;
    // Type of 'v' in declaration.
    {
      VariableDeclarationStatement statement =
          statements[0] as VariableDeclarationStatement;
      SimpleIdentifier variableName = statement.variables.variables[0].name;
      expect(variableName.staticType, typeProvider.intType);
    }
    // Type of 'v' in reference.
    {
      ReturnStatement statement = statements[1] as ReturnStatement;
      SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
      expect(variableName.staticType, typeProvider.intType);
    }
  }

  test_initializer_hasStaticType_parameterized() async {
    Source source = addSource(r'''
f() {
  List<int> v = <int>[];
  return v;
}''');
    CompilationUnit unit = await _computeResolvedUnit(source);
    FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
    BlockFunctionBody body =
        function.functionExpression.body as BlockFunctionBody;
    NodeList<Statement> statements = body.block.statements;
    // Type of 'v' in declaration.
    {
      VariableDeclarationStatement statement =
          statements[0] as VariableDeclarationStatement;
      SimpleIdentifier variableName = statement.variables.variables[0].name;
      expect(variableName.staticType, isNotNull);
    }
    // Type of 'v' in reference.
    {
      ReturnStatement statement = statements[1] as ReturnStatement;
      SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
      expect(variableName.staticType, isNotNull);
    }
  }

  test_initializer_null() async {
    String code = r'''
main() {
  int v = null;
  return v; // marker
}''';
    CompilationUnit unit;
    {
      Source source = addSource(code);
      unit = await _computeResolvedUnit(source);
    }
    {
      SimpleIdentifier identifier = EngineTestCase.findNode(
          unit, code, "v = null;", (node) => node is SimpleIdentifier);
      expect(identifier.staticType, typeProvider.intType);
    }
    {
      SimpleIdentifier identifier = EngineTestCase.findNode(
          unit, code, "v; // marker", (node) => node is SimpleIdentifier);
      expect(identifier.staticType, typeProvider.intType);
    }
  }

  test_invocation_target_prefixed() async {
    addNamedSource('/helper.dart', '''
library helper;
int max(int x, int y) => 0;
''');
    String code = '''
import 'helper.dart' as helper;
main() {
  helper.max(10, 10); // marker
}''';
    CompilationUnit unit = await resolveSource(code);
    SimpleIdentifier methodName =
        findMarkedIdentifier(code, unit, "(10, 10); // marker");
    MethodInvocation methodInvoke = methodName.parent;
    expect(methodInvoke.methodName.staticElement, isNotNull);
  }

  test_is_subclass() async {
    Source source = addSource(r'''
class A {}
class B extends A {
  B m() => this;
}
A f(A p) {
  if (p is B) {
    return p.m();
  }
  return p;
}''');
    CompilationUnit unit = await _computeResolvedUnit(source);
    FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
    BlockFunctionBody body =
        function.functionExpression.body as BlockFunctionBody;
    IfStatement ifStatement = body.block.statements[0] as IfStatement;
    ReturnStatement statement =
        (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
    MethodInvocation invocation = statement.expression as MethodInvocation;
    expect(invocation.methodName.staticElement, isNotNull);
  }

  test_mutatedOutsideScope() async {
    // https://code.google.com/p/dart/issues/detail?id=22732
    Source source = addSource(r'''
class Base {
}

class Derived extends Base {
  get y => null;
}

class C {
  void f() {
    Base x = null;
    if (x is Derived) {
      print(x.y); // BAD
    }
    x = null;
  }
}

void g() {
  Base x = null;
  if (x is Derived) {
    print(x.y); // GOOD
  }
  x = null;
}''');
    await computeAnalysisResult(source);
    assertNoErrors(source);
  }

  test_objectAccessInference_disabled_for_library_prefix() async {
    String name = 'hashCode';
    addNamedSource('/helper.dart', '''
library helper;
dynamic get $name => 42;
''');
    String code = '''
import 'helper.dart' as helper;
main() {
  helper.$name; // marker
}''';

    CompilationUnit unit = await resolveSource(code);
    SimpleIdentifier id = findMarkedIdentifier(code, unit, "; // marker");
    PrefixedIdentifier prefixedId = id.parent;
    expect(id.staticType, typeProvider.dynamicType);
    expect(prefixedId.staticType, typeProvider.dynamicType);
  }

  test_objectAccessInference_disabled_for_local_getter() async {
    String name = 'hashCode';
    String code = '''
dynamic get $name => null;
main() {
  $name; // marker
}''';

    CompilationUnit unit = await resolveSource(code);
    SimpleIdentifier getter = findMarkedIdentifier(code, unit, "; // marker");
    expect(getter.staticType, typeProvider.dynamicType);
  }

  test_objectAccessInference_enabled_for_cascades() async {
    if (previewDart2) {
      return;
    }
    String name = 'hashCode';
    String code = '''
main() {
  dynamic obj;
  obj..$name..$name; // marker
}''';
    CompilationUnit unit = await resolveSource(code);
    PropertyAccess access =
        findMarkedIdentifier(code, unit, "; // marker").parent;
    expect(access.staticType, typeProvider.dynamicType);
    expect(access.realTarget.staticType, typeProvider.dynamicType);
  }

  test_objectMethodInference_disabled_for_library_prefix() async {
    String name = 'toString';
    addNamedSource('/helper.dart', '''
library helper;
dynamic toString = (int x) => x + 42;
''');
    String code = '''
import 'helper.dart' as helper;
main() {
  helper.$name(); // marker
}''';
    CompilationUnit unit = await resolveSource(code);
    SimpleIdentifier methodName =
        findMarkedIdentifier(code, unit, "(); // marker");
    MethodInvocation methodInvoke = methodName.parent;
    expect(methodName.staticType, typeProvider.dynamicType);
    expect(methodInvoke.staticType, typeProvider.dynamicType);
  }

  test_objectMethodInference_disabled_for_local_function() async {
    String name = 'toString';
    String code = '''
main() {
  dynamic $name = () => null;
  $name(); // marker
}''';
    CompilationUnit unit = await resolveSource(code);

    SimpleIdentifier identifier = findMarkedIdentifier(code, unit, "$name = ");
    expect(identifier.staticType, typeProvider.dynamicType);

    SimpleIdentifier methodName =
        findMarkedIdentifier(code, unit, "(); // marker");
    MethodInvocation methodInvoke = methodName.parent;
    expect(methodName.staticType, typeProvider.dynamicType);
    expect(methodInvoke.staticType, typeProvider.dynamicType);
  }

  test_objectMethodInference_enabled_for_cascades() async {
    if (previewDart2) {
      return;
    }
    String name = 'toString';
    String code = '''
main() {
  dynamic obj;
  obj..$name()..$name(); // marker
}''';
    CompilationUnit unit = await resolveSource(code);
    SimpleIdentifier methodName =
        findMarkedIdentifier(code, unit, "(); // marker");
    MethodInvocation methodInvoke = methodName.parent;

    expect(methodInvoke.staticType, typeProvider.dynamicType);
    expect(methodInvoke.realTarget.staticType, typeProvider.dynamicType);
  }

  test_propagatedReturnType_localFunction() async {
    if (previewDart2) {
      return;
    }
    String code = r'''
main() {
  f() => 42;
  var v = f();
}''';
    CompilationUnit unit = await resolveSource(code);
    assertAssignedType(code, unit, typeProvider.dynamicType);
  }

  /**
   * Return the resolved unit for the given [source].
   *
   * If [noErrors] is not specified or is not `true`, [assertNoErrors].
   */
  Future<CompilationUnit> _computeResolvedUnit(Source source,
      {bool noErrors: true}) async {
    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
    if (noErrors) {
      assertNoErrors(source);
      verify([source]);
    }
    return analysisResult.unit;
  }
}

@reflectiveTest
class TypeProviderImplTest extends EngineTestCase {
  void test_creation() {
    //
    // Create a mock library element with the types expected to be in dart:core.
    // We cannot use either ElementFactory or TestTypeProvider (which uses
    // ElementFactory) because we side-effect the elements in ways that would
    // break other tests.
    //
    InterfaceType objectType = _classElement("Object", null).type;
    InterfaceType boolType = _classElement("bool", objectType).type;
    InterfaceType numType = _classElement("num", objectType).type;
    InterfaceType doubleType = _classElement("double", numType).type;
    InterfaceType functionType = _classElement("Function", objectType).type;
    InterfaceType futureType = _classElement("Future", objectType, ["T"]).type;
    InterfaceType futureOrType =
        _classElement("FutureOr", objectType, ["T"]).type;
    InterfaceType intType = _classElement("int", numType).type;
    InterfaceType iterableType =
        _classElement("Iterable", objectType, ["T"]).type;
    InterfaceType listType = _classElement("List", objectType, ["E"]).type;
    InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
    InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
    InterfaceType streamType = _classElement("Stream", objectType, ["T"]).type;
    InterfaceType stringType = _classElement("String", objectType).type;
    InterfaceType symbolType = _classElement("Symbol", objectType).type;
    InterfaceType typeType = _classElement("Type", objectType).type;
    CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl();
    coreUnit.types = <ClassElement>[
      boolType.element,
      doubleType.element,
      functionType.element,
      intType.element,
      iterableType.element,
      listType.element,
      mapType.element,
      objectType.element,
      stackTraceType.element,
      stringType.element,
      symbolType.element,
      typeType.element
    ];
    CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
    asyncUnit.types = <ClassElement>[
      futureType.element,
      futureOrType.element,
      streamType.element
    ];
    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
    LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
        context, AstTestFactory.libraryIdentifier2(["dart.core"]));
    coreLibrary.definingCompilationUnit = coreUnit;
    LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
        context, AstTestFactory.libraryIdentifier2(["dart.async"]));
    asyncLibrary.definingCompilationUnit = asyncUnit;
    //
    // Create a type provider and ensure that it can return the expected types.
    //
    TypeProviderImpl provider = new TypeProviderImpl(coreLibrary, asyncLibrary);
    expect(provider.boolType, same(boolType));
    expect(provider.bottomType, isNotNull);
    expect(provider.doubleType, same(doubleType));
    expect(provider.dynamicType, isNotNull);
    expect(provider.functionType, same(functionType));
    expect(provider.futureType, same(futureType));
    expect(provider.futureOrType, same(futureOrType));
    expect(provider.intType, same(intType));
    expect(provider.listType, same(listType));
    expect(provider.mapType, same(mapType));
    expect(provider.objectType, same(objectType));
    expect(provider.stackTraceType, same(stackTraceType));
    expect(provider.streamType, same(streamType));
    expect(provider.stringType, same(stringType));
    expect(provider.symbolType, same(symbolType));
    expect(provider.typeType, same(typeType));
  }

  ClassElement _classElement(String typeName, InterfaceType superclassType,
      [List<String> parameterNames]) {
    ClassElementImpl element =
        new ClassElementImpl.forNode(AstTestFactory.identifier3(typeName));
    element.supertype = superclassType;
    if (parameterNames != null) {
      int count = parameterNames.length;
      if (count > 0) {
        List<TypeParameterElementImpl> typeParameters =
            new List<TypeParameterElementImpl>(count);
        List<TypeParameterTypeImpl> typeArguments =
            new List<TypeParameterTypeImpl>(count);
        for (int i = 0; i < count; i++) {
          TypeParameterElementImpl typeParameter =
              new TypeParameterElementImpl.forNode(
                  AstTestFactory.identifier3(parameterNames[i]));
          typeParameters[i] = typeParameter;
          typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
          typeParameter.type = typeArguments[i];
        }
        element.typeParameters = typeParameters;
      }
    }
    return element;
  }
}

@reflectiveTest
class TypeResolverVisitorTest extends ParserTestCase
    with ResourceProviderMixin {
  /**
   * The error listener to which errors will be reported.
   */
  GatheringErrorListener _listener;

  /**
   * The type provider used to access the types.
   */
  TestTypeProvider _typeProvider;

  /**
   * The library scope in which types are to be resolved.
   */
  LibraryScope libraryScope;

  /**
   * The visitor used to resolve types needed to form the type hierarchy.
   */
  TypeResolverVisitor _visitor;

  fail_visitConstructorDeclaration() async {
    _fail("Not yet tested");
    _listener.assertNoErrors();
  }

  fail_visitFunctionTypeAlias() async {
    _fail("Not yet tested");
    _listener.assertNoErrors();
  }

  fail_visitVariableDeclaration() async {
    _fail("Not yet tested");
    ClassElement type = ElementFactory.classElement2("A");
    VariableDeclaration node = AstTestFactory.variableDeclaration("a");
    AstTestFactory.variableDeclarationList(
        null, AstTestFactory.typeName(type), [node]);
    //resolve(node);
    expect(node.name.staticType, same(type.type));
    _listener.assertNoErrors();
  }

  void setUp({bool shouldSetElementSupertypes: false}) {
    _listener = new GatheringErrorListener();
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
        resourceProvider: resourceProvider);
    Source librarySource = new FileSource(getFile("/lib.dart"));
    LibraryElementImpl element = new LibraryElementImpl.forNode(
        context, AstTestFactory.libraryIdentifier2(["lib"]));
    element.definingCompilationUnit = new CompilationUnitElementImpl();
    _typeProvider = new TestTypeProvider();
    libraryScope = new LibraryScope(element);
    _visitor = new TypeResolverVisitor(
        element, librarySource, _typeProvider, _listener,
        nameScope: libraryScope,
        shouldSetElementSupertypes: shouldSetElementSupertypes);
  }

  test_modeApi() async {
    CompilationUnit unit = parseCompilationUnit(r'''
class C extends A with A implements A {
  A f = new A();
  A m() {
    A v1;
  }
}
A f([A p = const A()]) {
  A v2;
}
A V = new A();
''');
    var unitElement = new CompilationUnitElementImpl();
    ClassElementImpl A = ElementFactory.classElement2('A');

    // Build API elements.
    {
      var holder = new ElementHolder();
      unit.accept(new ApiElementBuilder(holder, unitElement));
    }

    // Resolve API types.
    {
      InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
          resourceProvider: resourceProvider);
      var source = getFile('/test.dart').createSource();
      var libraryElement = new LibraryElementImpl.forNode(context, null)
        ..definingCompilationUnit = unitElement;
      var libraryScope = new LibraryScope(libraryElement);
      var visitor = new TypeResolverVisitor(
          libraryElement, source, _typeProvider, _listener,
          nameScope: libraryScope, mode: TypeResolverMode.api);
      libraryScope.define(A);
      unit.accept(visitor);
    }

    // Top-level: C
    {
      var c = unit.declarations[0] as ClassDeclaration;

      // The extends/with/implements types are resolved.
      expect(c.extendsClause.superclass.toString(), 'A');
      expect(c.withClause.mixinTypes[0].type.toString(), 'A');
      expect(c.implementsClause.interfaces[0].type.toString(), 'A');

      {
        var fd = c.members[0] as FieldDeclaration;
        // The field type is resolved.
        expect(fd.fields.type.type.toString(), 'A');
        // The type in the initializer is not resolved.
        var f = fd.fields.variables[0];
        var fi = f.initializer as InstanceCreationExpression;
        expect(fi.constructorName.type.type, isNull);
      }

      {
        var m = c.members[1] as MethodDeclaration;
        // The return type is resolved.
        expect(m.returnType.type.toString(), 'A');
        // The local variable type is not resolved.
        var body = m.body as BlockFunctionBody;
        var vd = body.block.statements.single as VariableDeclarationStatement;
        expect(vd.variables.type.type, isNull);
      }
    }

    // Top-level: f
    {
      var f = unit.declarations[1] as FunctionDeclaration;
      FunctionExpression fe = f.functionExpression;
      // The return type is resolved.
      expect(f.returnType.type.toString(), 'A');
      // The parameter type is resolved.
      var pd = fe.parameters.parameters[0] as DefaultFormalParameter;
      var p = pd.parameter as SimpleFormalParameter;
      expect(p.type.type.toString(), 'A');
      // The parameter default is not resolved.
      {
        var pde = pd.defaultValue as InstanceCreationExpression;
        expect(pde.constructorName.type.type, isNull);
      }
      // The local variable type is not resolved.
      var body = fe.body as BlockFunctionBody;
      var vd = body.block.statements.single as VariableDeclarationStatement;
      expect(vd.variables.type.type, isNull);
    }

    // Top-level: V
    {
      var vd = unit.declarations[2] as TopLevelVariableDeclaration;
      // The type is resolved.
      expect(vd.variables.type.toString(), 'A');
      // The initializer is not resolved.
      VariableDeclaration v = vd.variables.variables[0];
      var vi = v.initializer as InstanceCreationExpression;
      expect(vi.constructorName.type.type, isNull);
    }
  }

  test_modeLocal_noContext() async {
    CompilationUnit unit;
    _resolveTypeModeLocal(r'''
class C {
  A f = new A();
  A m([A p = const A()]) {
    A v;
  }
}
A f([A p = const A()]) {
  A v1 = new A();
  A f2(A p2) {
    A v2;
  }
}
A V = new A();
A get G => new A();
''', (CompilationUnit u) {
      unit = u;
      return u;
    });

    // Top-level: C
    {
      var c = unit.declarations[0] as ClassDeclaration;
      {
        var fd = c.members[0] as FieldDeclaration;
        // The type of "f" is not resolved.
        expect(fd.fields.type.type, isNull);
        // The initializer of "f" is resolved.
        var f = fd.fields.variables[0];
        var fi = f.initializer as InstanceCreationExpression;
        expect(fi.constructorName.type.type.toString(), 'A');
      }
      {
        var m = c.members[1] as MethodDeclaration;
        // The return type of "m" is not resolved.
        expect(m.returnType.type, isNull);
        // The type of the parameter "p" is not resolved.
        var pd = m.parameters.parameters[0] as DefaultFormalParameter;
        var p = pd.parameter as SimpleFormalParameter;
        expect(p.type.type, isNull);
        // The default value of the parameter "p" is resolved.
        var pdd = pd.defaultValue as InstanceCreationExpression;
        expect(pdd.constructorName.type.type.toString(), 'A');
        // The type of "v" is resolved.
        var mb = m.body as BlockFunctionBody;
        var vd = mb.block.statements[0] as VariableDeclarationStatement;
        expect(vd.variables.type.type.toString(), 'A');
      }
    }

    // Top-level: f
    {
      var f = unit.declarations[1] as FunctionDeclaration;
      // The return type of "f" is not resolved.
      expect(f.returnType.type, isNull);
      // The type of the parameter "p" is not resolved.
      var fe = f.functionExpression;
      var pd = fe.parameters.parameters[0] as DefaultFormalParameter;
      var p = pd.parameter as SimpleFormalParameter;
      expect(p.type.type, isNull);
      // The default value of the parameter "p" is resolved.
      var pdd = pd.defaultValue as InstanceCreationExpression;
      expect(pdd.constructorName.type.type.toString(), 'A');
      // The type of "v1" is resolved.
      var fb = fe.body as BlockFunctionBody;
      var vd = fb.block.statements[0] as VariableDeclarationStatement;
      expect(vd.variables.type.type.toString(), 'A');
      // The initializer of "v1" is resolved.
      var v = vd.variables.variables[0];
      var vi = v.initializer as InstanceCreationExpression;
      expect(vi.constructorName.type.type.toString(), 'A');
      // Local: f2
      {
        var f2s = fb.block.statements[1] as FunctionDeclarationStatement;
        var f2 = f2s.functionDeclaration;
        // The return type of "f2" is resolved.
        expect(f2.returnType.type.toString(), 'A');
        // The type of the parameter "p2" is resolved.
        var f2e = f2.functionExpression;
        var p2 = f2e.parameters.parameters[0] as SimpleFormalParameter;
        expect(p2.type.type.toString(), 'A');
        // The type of "v2" is resolved.
        var f2b = f2e.body as BlockFunctionBody;
        var v2d = f2b.block.statements[0] as VariableDeclarationStatement;
        expect(v2d.variables.type.type.toString(), 'A');
      }
    }

    // Top-level: V
    {
      var vd = unit.declarations[2] as TopLevelVariableDeclaration;
      // The type is not resolved.
      expect(vd.variables.type.type, isNull);
      // The initializer is resolved.
      VariableDeclaration v = vd.variables.variables[0];
      var vi = v.initializer as InstanceCreationExpression;
      expect(vi.constructorName.type.type.toString(), 'A');
    }

    // Top-level: G
    {
      var g = unit.declarations[3] as FunctionDeclaration;
      // The return type is not resolved.
      expect(g.returnType.type, isNull);
      // The body is resolved.
      var gb = g.functionExpression.body as ExpressionFunctionBody;
      var ge = gb.expression as InstanceCreationExpression;
      expect(ge.constructorName.type.type.toString(), 'A');
    }
  }

  test_modeLocal_withContext_bad_methodBody() async {
    expect(() {
      _resolveTypeModeLocal(r'''
class C<T1> {
  A m<T2>() {
    T1 v1;
    T2 v2;
  }
}
''', (CompilationUnit u) {
        var c = u.declarations[0] as ClassDeclaration;
        var m = c.members[0] as MethodDeclaration;
        var mb = m.body as BlockFunctionBody;
        return mb;
      });
    }, throwsStateError);
  }

  test_modeLocal_withContext_bad_topLevelVariable_declaration() async {
    expect(() {
      _resolveTypeModeLocal(r'''
var v = new A();
''', (CompilationUnit u) {
        var tlv = u.declarations[0] as TopLevelVariableDeclaration;
        return tlv.variables.variables[0];
      });
    }, throwsStateError);
  }

  test_modeLocal_withContext_bad_topLevelVariable_initializer() async {
    expect(() {
      _resolveTypeModeLocal(r'''
var v = new A();
''', (CompilationUnit u) {
        var tlv = u.declarations[0] as TopLevelVariableDeclaration;
        return tlv.variables.variables[0].initializer;
      });
    }, throwsStateError);
  }

  test_modeLocal_withContext_class() async {
    ClassDeclaration c;
    _resolveTypeModeLocal(r'''
class C<T1> {
  A m<T2>() {
    T1 v1;
    T2 v2;
  }
}
''', (CompilationUnit u) {
      c = u.declarations[0] as ClassDeclaration;
      return c;
    });
    var m = c.members[0] as MethodDeclaration;

    // The return type of "m" is not resolved.
    expect(m.returnType.type, isNull);

    var mb = m.body as BlockFunctionBody;
    var ms = mb.block.statements;

    // The type of "v1" is resolved.
    {
      var vd = ms[0] as VariableDeclarationStatement;
      expect(vd.variables.type.type.toString(), 'T1');
    }

    // The type of "v2" is resolved.
    {
      var vd = ms[1] as VariableDeclarationStatement;
      expect(vd.variables.type.type.toString(), 'T2');
    }
  }

  test_modeLocal_withContext_inClass_constructor() async {
    ConstructorDeclaration cc;
    _resolveTypeModeLocal(r'''
class C<T> {
  C() {
    T v1;
  }
}
''', (CompilationUnit u) {
      var c = u.declarations[0] as ClassDeclaration;
      cc = c.members[0] as ConstructorDeclaration;
      return cc;
    });

    var ccb = cc.body as BlockFunctionBody;
    var ccs = ccb.block.statements;

    // The type of "v" is resolved.
    {
      var vd = ccs[0] as VariableDeclarationStatement;
      expect(vd.variables.type.type.toString(), 'T');
    }
  }

  test_modeLocal_withContext_inClass_method() async {
    MethodDeclaration m;
    _resolveTypeModeLocal(r'''
class C<T1> {
  A m<T2>() {
    T1 v1;
    T2 v2;
  }
}
''', (CompilationUnit u) {
      var c = u.declarations[0] as ClassDeclaration;
      m = c.members[0] as MethodDeclaration;
      return m;
    });

    // The return type of "m" is not resolved.
    expect(m.returnType.type, isNull);

    var mb = m.body as BlockFunctionBody;
    var ms = mb.block.statements;

    // The type of "v1" is resolved.
    {
      var vd = ms[0] as VariableDeclarationStatement;
      expect(vd.variables.type.type.toString(), 'T1');
    }

    // The type of "v2" is resolved.
    {
      var vd = ms[1] as VariableDeclarationStatement;
      expect(vd.variables.type.type.toString(), 'T2');
    }
  }

  test_modeLocal_withContext_topLevelFunction() async {
    FunctionDeclaration f;
    _resolveTypeModeLocal(r'''
A m<T>() {
  T v;
}
''', (CompilationUnit u) {
      f = u.declarations[0] as FunctionDeclaration;
      return f;
    });

    // The return type of "f" is not resolved.
    expect(f.returnType.type, isNull);

    var fb = f.functionExpression.body as BlockFunctionBody;
    var fs = fb.block.statements;

    // The type of "v" is resolved.
    var vd = fs[0] as VariableDeclarationStatement;
    expect(vd.variables.type.type.toString(), 'T');
  }

  test_modeLocal_withContext_topLevelVariable() async {
    TopLevelVariableDeclaration v;
    _resolveTypeModeLocal(r'''
A v = new A();
''', (CompilationUnit u) {
      v = u.declarations[0] as TopLevelVariableDeclaration;
      return v;
    });

    // The type of "v" is not resolved.
    expect(v.variables.type.type, isNull);

    // The type of "v" initializer is resolved.
    var vi = v.variables.variables[0].initializer as InstanceCreationExpression;
    expect(vi.constructorName.type.type.toString(), 'A');
  }

  test_visitCatchClause_exception() async {
    // catch (e)
    CatchClause clause = AstTestFactory.catchClause("e");
    SimpleIdentifier exceptionParameter = clause.exceptionParameter;
    exceptionParameter.staticElement =
        new LocalVariableElementImpl.forNode(exceptionParameter);
    _resolveCatchClause(clause, _typeProvider.dynamicType, null);
    _listener.assertNoErrors();
  }

  test_visitCatchClause_exception_stackTrace() async {
    // catch (e, s)
    CatchClause clause = AstTestFactory.catchClause2("e", "s");
    SimpleIdentifier exceptionParameter = clause.exceptionParameter;
    exceptionParameter.staticElement =
        new LocalVariableElementImpl.forNode(exceptionParameter);
    SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
    stackTraceParameter.staticElement =
        new LocalVariableElementImpl.forNode(stackTraceParameter);
    _resolveCatchClause(
        clause, _typeProvider.dynamicType, _typeProvider.stackTraceType);
    _listener.assertNoErrors();
  }

  test_visitCatchClause_on_exception() async {
    // on E catch (e)
    ClassElement exceptionElement = ElementFactory.classElement2("E");
    TypeName exceptionType = AstTestFactory.typeName(exceptionElement);
    CatchClause clause = AstTestFactory.catchClause4(exceptionType, "e");
    SimpleIdentifier exceptionParameter = clause.exceptionParameter;
    exceptionParameter.staticElement =
        new LocalVariableElementImpl.forNode(exceptionParameter);
    _resolveCatchClause(
        clause, exceptionElement.type, null, [exceptionElement]);
    _listener.assertNoErrors();
  }

  test_visitCatchClause_on_exception_stackTrace() async {
    // on E catch (e, s)
    ClassElement exceptionElement = ElementFactory.classElement2("E");
    TypeName exceptionType = AstTestFactory.typeName(exceptionElement);
    (exceptionType.name as SimpleIdentifier).staticElement = exceptionElement;
    CatchClause clause = AstTestFactory.catchClause5(exceptionType, "e", "s");
    SimpleIdentifier exceptionParameter = clause.exceptionParameter;
    exceptionParameter.staticElement =
        new LocalVariableElementImpl.forNode(exceptionParameter);
    SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
    stackTraceParameter.staticElement =
        new LocalVariableElementImpl.forNode(stackTraceParameter);
    _resolveCatchClause(clause, exceptionElement.type,
        _typeProvider.stackTraceType, [exceptionElement]);
    _listener.assertNoErrors();
  }

  test_visitClassDeclaration() async {
    // class A extends B with C implements D {}
    // class B {}
    // class C {}
    // class D {}
    setUp(shouldSetElementSupertypes: true);
    ClassElement elementA = ElementFactory.classElement2("A");
    ClassElement elementB = ElementFactory.classElement2("B");
    ClassElement elementC = ElementFactory.classElement2("C");
    ClassElement elementD = ElementFactory.classElement2("D");
    ExtendsClause extendsClause =
        AstTestFactory.extendsClause(AstTestFactory.typeName(elementB));
    WithClause withClause =
        AstTestFactory.withClause([AstTestFactory.typeName(elementC)]);
    ImplementsClause implementsClause =
        AstTestFactory.implementsClause([AstTestFactory.typeName(elementD)]);
    ClassDeclaration declaration = AstTestFactory.classDeclaration(
        null, "A", null, extendsClause, withClause, implementsClause);
    declaration.name.staticElement = elementA;
    _resolveNode(declaration, [elementA, elementB, elementC, elementD]);
    expect(elementA.supertype, same(elementB.type));
    List<InterfaceType> mixins = elementA.mixins;
    expect(mixins, hasLength(1));
    expect(mixins[0], same(elementC.type));
    List<InterfaceType> interfaces = elementA.interfaces;
    expect(interfaces, hasLength(1));
    expect(interfaces[0], same(elementD.type));
    _listener.assertNoErrors();
  }

  test_visitClassDeclaration_instanceMemberCollidesWithClass() async {
    // class A {}
    // class B extends A {
    //   void A() {}
    // }
    setUp(shouldSetElementSupertypes: true);
    ClassElementImpl elementA = ElementFactory.classElement2("A");
    ClassElementImpl elementB = ElementFactory.classElement2("B");
    elementB.methods = <MethodElement>[
      ElementFactory.methodElement("A", VoidTypeImpl.instance)
    ];
    ExtendsClause extendsClause =
        AstTestFactory.extendsClause(AstTestFactory.typeName(elementA));
    ClassDeclaration declaration = AstTestFactory.classDeclaration(
        null, "B", null, extendsClause, null, null);
    declaration.name.staticElement = elementB;
    _resolveNode(declaration, [elementA, elementB]);
    expect(elementB.supertype, same(elementA.type));
    _listener.assertNoErrors();
  }

  test_visitFieldFormalParameter_functionType() async {
    InterfaceType intType = _typeProvider.intType;
    TypeName intTypeName = AstTestFactory.typeName4('int');

    String aName = 'a';
    SimpleFormalParameterImpl aNode =
        AstTestFactory.simpleFormalParameter3(aName);
    aNode.declaredElement = aNode.identifier.staticElement =
        ElementFactory.requiredParameter(aName);

    String pName = 'p';
    FormalParameter pNode = AstTestFactory.fieldFormalParameter(
        null, intTypeName, pName, AstTestFactory.formalParameterList([aNode]));
    var pElement = ElementFactory.requiredParameter(pName);
    pNode.identifier.staticElement = pElement;

    FunctionType pType = new FunctionTypeImpl(
        new GenericFunctionTypeElementImpl.forOffset(-1)
          ..parameters = [aNode.declaredElement]);
    pElement.type = pType;

    _resolveFormalParameter(pNode, [intType.element]);
    expect(pType.returnType, same(intType));
    expect(pType.parameters, hasLength(1));
    _listener.assertNoErrors();
  }

  test_visitFieldFormalParameter_noType() async {
    String parameterName = "p";
    FormalParameter node =
        AstTestFactory.fieldFormalParameter(Keyword.VAR, null, parameterName);
    node.identifier.staticElement =
        ElementFactory.requiredParameter(parameterName);
    expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
    _listener.assertNoErrors();
  }

  test_visitFieldFormalParameter_type() async {
    InterfaceType intType = _typeProvider.intType;
    TypeName intTypeName = AstTestFactory.typeName4("int");
    String parameterName = "p";
    FormalParameter node =
        AstTestFactory.fieldFormalParameter(null, intTypeName, parameterName);
    node.identifier.staticElement =
        ElementFactory.requiredParameter(parameterName);
    expect(_resolveFormalParameter(node, [intType.element]), same(intType));
    _listener.assertNoErrors();
  }

  test_visitFunctionDeclaration() async {
    // R f(P p) {}
    // class R {}
    // class P {}
    ClassElement elementR = ElementFactory.classElement2('R');
    ClassElement elementP = ElementFactory.classElement2('P');
    FunctionElement elementF = ElementFactory.functionElement('f');
    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
        AstTestFactory.typeName4('R'),
        null,
        'f',
        AstTestFactory.functionExpression2(
            AstTestFactory.formalParameterList([
              AstTestFactory.simpleFormalParameter4(
                  AstTestFactory.typeName4('P'), 'p')
            ]),
            null));
    declaration.name.staticElement = elementF;
    _resolveNode(declaration, [elementR, elementP]);
    expect(declaration.returnType.type, elementR.type);
    SimpleFormalParameter parameter =
        declaration.functionExpression.parameters.parameters[0];
    expect(parameter.type.type, elementP.type);
    _listener.assertNoErrors();
  }

  test_visitFunctionDeclaration_typeParameter() async {
    // E f<E>(E e) {}
    TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
    FunctionElementImpl elementF = ElementFactory.functionElement('f');
    elementF.typeParameters = <TypeParameterElement>[elementE];
    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
        AstTestFactory.typeName4('E'),
        null,
        'f',
        AstTestFactory.functionExpression2(
            AstTestFactory.formalParameterList([
              AstTestFactory.simpleFormalParameter4(
                  AstTestFactory.typeName4('E'), 'e')
            ]),
            null));
    declaration.name.staticElement = elementF;
    _resolveNode(declaration, []);
    expect(declaration.returnType.type, elementE.type);
    SimpleFormalParameter parameter =
        declaration.functionExpression.parameters.parameters[0];
    expect(parameter.type.type, elementE.type);
    _listener.assertNoErrors();
  }

  test_visitFunctionTypedFormalParameter() async {
    // R f(R g(P p)) {}
    // class R {}
    // class P {}
    ClassElement elementR = ElementFactory.classElement2('R');
    ClassElement elementP = ElementFactory.classElement2('P');

    SimpleFormalParameter pNode = AstTestFactory.simpleFormalParameter4(
        AstTestFactory.typeName4('P'), 'p');
    ParameterElementImpl pElement = ElementFactory.requiredParameter('p');
    pNode.identifier.staticElement = pElement;

    FunctionTypedFormalParameter gNode =
        AstTestFactory.functionTypedFormalParameter(
            AstTestFactory.typeName4('R'), 'g', [pNode]);
    ParameterElementImpl gElement = ElementFactory.requiredParameter('g');
    gNode.identifier.staticElement = gElement;

    FunctionTypeImpl gType = new FunctionTypeImpl(
        new GenericFunctionTypeElementImpl.forOffset(-1)
          ..parameters = [pElement]);
    gElement.type = gType;

    FunctionDeclaration fNode = AstTestFactory.functionDeclaration(
        AstTestFactory.typeName4('R'),
        null,
        'f',
        AstTestFactory.functionExpression2(
            AstTestFactory.formalParameterList([gNode]), null));
    fNode.name.staticElement = ElementFactory.functionElement('f');

    _resolveNode(fNode, [elementR, elementP]);

    expect(fNode.returnType.type, elementR.type);
    expect(gType.returnType, elementR.type);
    expect(gNode.returnType.type, elementR.type);
    expect(pNode.type.type, elementP.type);

    _listener.assertNoErrors();
  }

  test_visitFunctionTypedFormalParameter_typeParameter() async {
    // R f(R g<E>(E e)) {}
    // class R {}
    ClassElement elementR = ElementFactory.classElement2('R');
    TypeParameterElement elementE = ElementFactory.typeParameterElement('E');

    SimpleFormalParameterImpl eNode = AstTestFactory.simpleFormalParameter4(
        AstTestFactory.typeName4('E'), 'e');
    eNode.declaredElement = ElementFactory.requiredParameter('e');

    FunctionTypedFormalParameter gNode =
        AstTestFactory.functionTypedFormalParameter(
            AstTestFactory.typeName4('R'), 'g', [eNode]);
    ParameterElementImpl gElement = ElementFactory.requiredParameter('g');
    gNode.identifier.staticElement = gElement;

    FunctionTypeImpl gType =
        new FunctionTypeImpl(new GenericFunctionTypeElementImpl.forOffset(-1)
          ..typeParameters = [elementE]
          ..parameters = [eNode.declaredElement]);
    gElement.type = gType;

    FunctionDeclaration fNode = AstTestFactory.functionDeclaration(
        AstTestFactory.typeName4('R'),
        null,
        'f',
        AstTestFactory.functionExpression2(
            AstTestFactory.formalParameterList([gNode]), null));
    fNode.name.staticElement = ElementFactory.functionElement('f');

    _resolveNode(fNode, [elementR]);

    expect(fNode.returnType.type, elementR.type);
    expect(gType.returnType, elementR.type);
    expect(gNode.returnType.type, elementR.type);
    expect(eNode.type.type, elementE.type);

    _listener.assertNoErrors();
  }

  test_visitMethodDeclaration() async {
    // class A {
    //   R m(P p) {}
    // }
    // class R {}
    // class P {}
    ClassElementImpl elementA = ElementFactory.classElement2('A');
    ClassElement elementR = ElementFactory.classElement2('R');
    ClassElement elementP = ElementFactory.classElement2('P');
    MethodElement elementM = ElementFactory.methodElement('m', null);
    elementA.methods = <MethodElement>[elementM];
    MethodDeclaration declaration = AstTestFactory.methodDeclaration(
        null,
        AstTestFactory.typeName4('R'),
        null,
        null,
        AstTestFactory.identifier3('m'),
        AstTestFactory.formalParameterList([
          AstTestFactory.simpleFormalParameter4(
              AstTestFactory.typeName4('P'), 'p')
        ]));
    declaration.name.staticElement = elementM;
    _resolveNode(declaration, [elementA, elementR, elementP]);
    expect(declaration.returnType.type, elementR.type);
    SimpleFormalParameter parameter = declaration.parameters.parameters[0];
    expect(parameter.type.type, elementP.type);
    _listener.assertNoErrors();
  }

  test_visitMethodDeclaration_typeParameter() async {
    // class A {
    //   E m<E>(E e) {}
    // }
    ClassElementImpl elementA = ElementFactory.classElement2('A');
    TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
    MethodElementImpl elementM = ElementFactory.methodElement('m', null);
    elementM.typeParameters = <TypeParameterElement>[elementE];
    elementA.methods = <MethodElement>[elementM];
    MethodDeclaration declaration = AstTestFactory.methodDeclaration(
        null,
        AstTestFactory.typeName4('E'),
        null,
        null,
        AstTestFactory.identifier3('m'),
        AstTestFactory.formalParameterList([
          AstTestFactory.simpleFormalParameter4(
              AstTestFactory.typeName4('E'), 'e')
        ]));
    declaration.name.staticElement = elementM;
    _resolveNode(declaration, [elementA]);
    expect(declaration.returnType.type, elementE.type);
    SimpleFormalParameter parameter = declaration.parameters.parameters[0];
    expect(parameter.type.type, elementE.type);
    _listener.assertNoErrors();
  }

  test_visitSimpleFormalParameter_noType() async {
    // p
    SimpleFormalParameterImpl node = AstTestFactory.simpleFormalParameter3("p");
    node.declaredElement = node.identifier.staticElement =
        new ParameterElementImpl.forNode(AstTestFactory.identifier3("p"));
    expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
    _listener.assertNoErrors();
  }

  test_visitSimpleFormalParameter_type() async {
    // int p
    InterfaceType intType = _typeProvider.intType;
    ClassElement intElement = intType.element;
    SimpleFormalParameterImpl node = AstTestFactory.simpleFormalParameter4(
        AstTestFactory.typeName(intElement), "p");
    SimpleIdentifier identifier = node.identifier;
    ParameterElementImpl element = new ParameterElementImpl.forNode(identifier);
    node.declaredElement = identifier.staticElement = element;
    expect(_resolveFormalParameter(node, [intElement]), same(intType));
    _listener.assertNoErrors();
  }

  test_visitTypeName_noParameters_noArguments() async {
    ClassElement classA = ElementFactory.classElement2("A");
    TypeName typeName = AstTestFactory.typeName(classA);
    typeName.type = null;
    _resolveNode(typeName, [classA]);
    expect(typeName.type, same(classA.type));
    _listener.assertNoErrors();
  }

  test_visitTypeName_noParameters_noArguments_undefined() async {
    SimpleIdentifier id = AstTestFactory.identifier3("unknown")
      ..staticElement = new _StaleElement();
    TypeName typeName = astFactory.typeName(id, null);
    _resolveNode(typeName, []);
    expect(typeName.type, UndefinedTypeImpl.instance);
    expect(typeName.name.staticElement, null);
    _listener.assertErrorsWithCodes([StaticWarningCode.UNDEFINED_CLASS]);
  }

  test_visitTypeName_parameters_arguments() async {
    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
    ClassElement classB = ElementFactory.classElement2("B");
    TypeName typeName =
        AstTestFactory.typeName(classA, [AstTestFactory.typeName(classB)]);
    typeName.type = null;
    _resolveNode(typeName, [classA, classB]);
    InterfaceType resultType = typeName.type as InterfaceType;
    expect(resultType.element, same(classA));
    List<DartType> resultArguments = resultType.typeArguments;
    expect(resultArguments, hasLength(1));
    expect(resultArguments[0], same(classB.type));
    _listener.assertNoErrors();
  }

  test_visitTypeName_parameters_noArguments() async {
    ClassElement classA = ElementFactory.classElement2("A", ["E"]);
    TypeName typeName = AstTestFactory.typeName(classA);
    typeName.type = null;
    _resolveNode(typeName, [classA]);
    InterfaceType resultType = typeName.type as InterfaceType;
    expect(resultType.element, same(classA));
    List<DartType> resultArguments = resultType.typeArguments;
    expect(resultArguments, hasLength(1));
    expect(resultArguments[0], same(DynamicTypeImpl.instance));
    _listener.assertNoErrors();
  }

  test_visitTypeName_prefixed_noParameters_noArguments_undefined() async {
    SimpleIdentifier prefix = AstTestFactory.identifier3("unknownPrefix")
      ..staticElement = new _StaleElement();
    SimpleIdentifier suffix = AstTestFactory.identifier3("unknownSuffix")
      ..staticElement = new _StaleElement();
    TypeName typeName =
        astFactory.typeName(AstTestFactory.identifier(prefix, suffix), null);
    _resolveNode(typeName, []);
    expect(typeName.type, UndefinedTypeImpl.instance);
    expect(prefix.staticElement, null);
    expect(suffix.staticElement, null);
    _listener.assertErrorsWithCodes([StaticWarningCode.UNDEFINED_CLASS]);
  }

  test_visitTypeName_void() async {
    ClassElement classA = ElementFactory.classElement2("A");
    TypeName typeName = AstTestFactory.typeName4("void");
    _resolveNode(typeName, [classA]);
    expect(typeName.type, same(VoidTypeImpl.instance));
    _listener.assertNoErrors();
  }

  /**
   * Analyze the given catch clause and assert that the types of the parameters have been set to the
   * given types. The types can be null if the catch clause does not have the corresponding
   * parameter.
   *
   * @param node the catch clause to be analyzed
   * @param exceptionType the expected type of the exception parameter
   * @param stackTraceType the expected type of the stack trace parameter
   * @param definedElements the elements that are to be defined in the scope in which the element is
   *          being resolved
   */
  void _resolveCatchClause(
      CatchClause node, DartType exceptionType, InterfaceType stackTraceType,
      [List<Element> definedElements]) {
    _resolveNode(node, definedElements);
    SimpleIdentifier exceptionParameter = node.exceptionParameter;
    if (exceptionParameter != null) {
      expect(exceptionParameter.staticType, same(exceptionType));
    }
    SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
    if (stackTraceParameter != null) {
      expect(stackTraceParameter.staticType, same(stackTraceType));
    }
  }

  /**
   * Return the type associated with the given parameter after the static type analyzer has computed
   * a type for it.
   *
   * @param node the parameter with which the type is associated
   * @param definedElements the elements that are to be defined in the scope in which the element is
   *          being resolved
   * @return the type associated with the parameter
   */
  DartType _resolveFormalParameter(FormalParameter node,
      [List<Element> definedElements]) {
    _resolveNode(node, definedElements);
    return (node.identifier.staticElement as ParameterElement).type;
  }

  /**
   * Return the element associated with the given identifier after the resolver has resolved the
   * identifier.
   *
   * @param node the expression to be resolved
   * @param definedElements the elements that are to be defined in the scope in which the element is
   *          being resolved
   * @return the element to which the expression was resolved
   */
  void _resolveNode(AstNode node, [List<Element> definedElements]) {
    if (definedElements != null) {
      for (Element element in definedElements) {
        libraryScope.define(element);
      }
    }
    node.accept(_visitor);
  }

  /**
   * Parse the given [code], build elements and resolve in the
   * [TypeResolverMode.local] mode. The [code] is allowed to use only the type
   * named `A`.
   */
  void _resolveTypeModeLocal(
      String code, AstNode getNodeToResolve(CompilationUnit unit)) {
    CompilationUnit unit = parseCompilationUnit2(code);
    var unitElement = new CompilationUnitElementImpl();

    // Build API elements.
    {
      var holder = new ElementHolder();
      unit.accept(new ElementBuilder(holder, unitElement));
    }

    // Prepare for resolution.
    LibraryScope libraryScope;
    TypeResolverVisitor visitor;
    {
      InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
          resourceProvider: resourceProvider);
      var source = getFile('/test.dart').createSource();
      var libraryElement = new LibraryElementImpl.forNode(context, null)
        ..definingCompilationUnit = unitElement;
      libraryScope = new LibraryScope(libraryElement);
      visitor = new TypeResolverVisitor(
          libraryElement, source, _typeProvider, _listener,
          nameScope: libraryScope, mode: TypeResolverMode.local);
    }

    // Define top-level types.
    ClassElementImpl A = ElementFactory.classElement2('A');
    libraryScope.define(A);

    // Perform resolution.
    AstNode nodeToResolve = getNodeToResolve(unit);
    nodeToResolve.accept(visitor);
  }
}

class _RootScope extends Scope {
  @override
  Element internalLookup(Identifier identifier, String name,
          LibraryElement referencingLibrary) =>
      null;
}

/**
 * Represents an element left over from a previous resolver run.
 *
 * A _StaleElement should always be replaced with either null or a new Element.
 */
class _StaleElement extends ElementImpl {
  _StaleElement() : super("_StaleElement", -1);

  @override
  get kind => throw "_StaleElement's kind shouldn't be accessed";

  @override
  T accept<T>(_) => throw "_StaleElement shouldn't be visited";
}
