// 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:collection';

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.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/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 '../src/dart/resolution/driver_resolution.dart';
import 'elements_types_mixin.dart';
import 'parser_test.dart';
import 'resolver_test_case.dart';
import 'test_analysis_context.dart';
import 'test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ChangeSetTest);
    defineReflectiveTests(EnclosedScopeTest);
    defineReflectiveTests(ErrorResolverTest);
    defineReflectiveTests(LibraryImportScopeTest);
    defineReflectiveTests(LibraryScopeTest);
    defineReflectiveTests(PrefixedNamespaceTest);
    defineReflectiveTests(ScopeTest);
    defineReflectiveTests(StrictModeTest);
    defineReflectiveTests(TypePropagationTest);
    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 ChangeSetTest {
  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 DriverResolutionTest {
  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 DriverResolutionTest {
  test_breakLabelOnSwitchMember() async {
    await assertErrorsInCode(r'''
class A {
  void m(int i) {
    switch (i) {
      l: case 0:
        break;
      case 1:
        break l;
    }
  }
}''', [
      error(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, 105, 1),
    ]);
  }

  test_continueLabelOnSwitch() async {
    await assertErrorsInCode(r'''
class A {
  void m(int i) {
    l: switch (i) {
      case 0:
        continue l;
    }
  }
}''', [
      error(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, 79, 1),
    ]);
  }

  test_enclosingElement_invalidLocalFunction() async {
    await resolveTestCode(r'''
class C {
  C() {
    int get x => 0;
  }
}''');
    assertTestErrorsWithCodes([
      ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
      ParserErrorCode.EXPECTED_TOKEN
    ]);

    var constructor = findElement.unnamedConstructor('C');
    var x = findElement.localFunction('x');
    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 assertNoErrorsInCode(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 = TestAnalysisContext();
    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_extensions_imported() {
    var context = TestAnalysisContext();

    var extension = ElementFactory.extensionElement('test_extension');

    var importedUnit1 = ElementFactory.compilationUnit('/imported1.dart');
    importedUnit1.extensions = <ExtensionElement>[extension];

    var importedLibraryName = 'imported_lib';
    var importedLibrary = LibraryElementImpl(context, null, importedLibraryName,
        0, importedLibraryName.length, false);
    importedLibrary.definingCompilationUnit = importedUnit1;

    var importingLibraryName = 'importing_lib';
    var importingLibrary = LibraryElementImpl(context, null,
        importingLibraryName, 0, importingLibraryName.length, false);
    importingLibrary.definingCompilationUnit =
        ElementFactory.compilationUnit('/importing.dart');

    var importElement = ImportElementImpl(0);
    importElement.importedLibrary = importedLibrary;
    importingLibrary.imports = <ImportElement>[importElement];

    expect(
        LibraryImportScope(importingLibrary).extensions, contains(extension));
  }

  void test_prefixedAndNonPrefixed() {
    AnalysisContext context = TestAnalysisContext();
    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 = TestAnalysisContext();
    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);
  }

  void test_extensions() {
    ExtensionElement extension =
        ElementFactory.extensionElement('test_extension');

    CompilationUnitElementImpl compilationUnit =
        ElementFactory.compilationUnit('/test.dart');
    compilationUnit.extensions = <ExtensionElement>[extension];

    String libraryName = 'lib';
    LibraryElementImpl library = new LibraryElementImpl(
        null, null, libraryName, 0, libraryName.length, false);
    library.definingCompilationUnit = compilationUnit;

    expect(LibraryScope(library).extensions, contains(extension));
  }

  void test_extensions_imported() {
    var context = TestAnalysisContext();

    var importedUnit1 = ElementFactory.compilationUnit('/imported1.dart');
    var importedExtension = ElementFactory.extensionElement('test_extension');
    var unnamedImportedExtension = ElementFactory.extensionElement();
    importedUnit1.extensions = [importedExtension, unnamedImportedExtension];

    var importedLibraryName = 'imported_lib';
    var importedLibrary = LibraryElementImpl(context, null, importedLibraryName,
        0, importedLibraryName.length, false);
    importedLibrary.definingCompilationUnit = importedUnit1;

    var importingLibraryName = 'importing_lib';
    var importingLibrary = LibraryElementImpl(context, null,
        importingLibraryName, 0, importingLibraryName.length, false);

    var localExtension = ElementFactory.extensionElement('test_extension');

    var importingUnit = ElementFactory.compilationUnit('/importing.dart');
    importingUnit.extensions = [localExtension];
    importingLibrary.definingCompilationUnit = importingUnit;

    var importElement = ImportElementImpl(0);
    importElement.importedLibrary = importedLibrary;
    importingLibrary.imports = [importElement];

    var libraryExtensions = LibraryScope(importingLibrary).extensions;

    expect(libraryExtensions, contains(localExtension));
    expect(libraryExtensions, contains(importedExtension));
    expect(libraryExtensions, isNot(contains(unnamedImportedExtension)));
  }

  /// Ensure that if a library L1 defines an extension E, L2 exports L1, and L3
  /// imports L2, then E is included in the list.
  void test_extensions_imported_chain() {
    var context = TestAnalysisContext();

    var unit1 = ElementFactory.compilationUnit('/unit1.dart');
    var ext1 = ElementFactory.extensionElement('ext1');
    unit1.extensions = [ext1];

    var lib1Name = 'lib1';
    var lib1 =
        LibraryElementImpl(context, null, lib1Name, 0, lib1Name.length, false);
    lib1.definingCompilationUnit = unit1;

    var unit2 = ElementFactory.compilationUnit('/unit2.dart');

    var lib2Name = 'lib2';
    var lib2 =
        LibraryElementImpl(context, null, lib2Name, 0, lib2Name.length, false);
    lib2.definingCompilationUnit = unit2;

    var lib1Export = ExportElementImpl(0);
    lib1Export.exportedLibrary = lib1;
    lib2.exports = [lib1Export];

    var importingLibraryName = 'importing_lib';
    var importingLibrary = LibraryElementImpl(context, null,
        importingLibraryName, 0, importingLibraryName.length, false);

    var importingUnit = ElementFactory.compilationUnit('/importing.dart');
    importingLibrary.definingCompilationUnit = importingUnit;

    var lib2Import = ImportElementImpl(0);
    lib2Import.importedLibrary = lib2;
    importingLibrary.imports = [lib2Import];

    var libraryExtensions = LibraryScope(importingLibrary).extensions;

    expect(libraryExtensions, orderedEquals([ext1]));
  }

  /// Ensure that if there are two extensions with the same name that are
  /// imported from different libraries that they are both in the list of
  /// extensions.
  void test_extensions_imported_same_name() {
    var context = TestAnalysisContext();

    var sharedExtensionName = 'test_ext';

    var unit1 = ElementFactory.compilationUnit('/unit1.dart');
    var ext1 = ElementFactory.extensionElement(sharedExtensionName);
    unit1.extensions = [ext1];

    var lib1Name = 'lib1';
    var lib1 =
        LibraryElementImpl(context, null, lib1Name, 0, lib1Name.length, false);
    lib1.definingCompilationUnit = unit1;

    var unit2 = ElementFactory.compilationUnit('/unit2.dart');
    var ext2 = ElementFactory.extensionElement(sharedExtensionName);
    unit2.extensions = [ext2];

    var lib2Name = 'lib2';
    var lib2 =
        LibraryElementImpl(context, null, lib2Name, 0, lib2Name.length, false);
    lib2.definingCompilationUnit = unit2;

    var importingLibraryName = 'importing_lib';
    var importingLibrary = LibraryElementImpl(context, null,
        importingLibraryName, 0, importingLibraryName.length, false);

    var importingUnit = ElementFactory.compilationUnit('/importing.dart');
    importingLibrary.definingCompilationUnit = importingUnit;

    var importElement1 = ImportElementImpl(0);
    importElement1.importedLibrary = lib1;
    var importElement2 = ImportElementImpl(0);
    importElement2.importedLibrary = lib2;
    importingLibrary.imports = [importElement1, importElement2];

    var libraryExtensions = LibraryScope(importingLibrary).extensions;

    expect(libraryExtensions, contains(ext1));
    expect(libraryExtensions, contains(ext2));
  }

  /// Ensure that if there are two imports for the same library that the
  /// imported extension is only in the list one time.
  void test_extensions_imported_twice() {
    var context = TestAnalysisContext();

    var sharedExtensionName = 'test_ext';

    var unit1 = ElementFactory.compilationUnit('/unit1.dart');
    var ext1 = ElementFactory.extensionElement(sharedExtensionName);
    unit1.extensions = [ext1];

    var lib1Name = 'lib1';
    var lib1 =
        LibraryElementImpl(context, null, lib1Name, 0, lib1Name.length, false);
    lib1.definingCompilationUnit = unit1;

    var importingLibraryName = 'importing_lib';
    var importingLibrary = LibraryElementImpl(context, null,
        importingLibraryName, 0, importingLibraryName.length, false);

    var importingUnit = ElementFactory.compilationUnit('/importing.dart');
    importingLibrary.definingCompilationUnit = importingUnit;

    var importElement1 = ImportElementImpl(0);
    importElement1.importedLibrary = lib1;
    var importElement2 = ImportElementImpl(0);
    importElement2.importedLibrary = lib1;
    importingLibrary.imports = [importElement1, importElement2];

    var libraryExtensions = LibraryScope(importingLibrary).extensions;
    expect(libraryExtensions, orderedEquals([ext1]));
  }
}

@reflectiveTest
class PrefixedNamespaceTest extends DriverResolutionTest {
  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 DriverResolutionTest {
  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<void> {
  /**
   * 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.isNotEmpty || _unresolvedTypes.isNotEmpty) {
      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
  void visitBreakStatement(BreakStatement node) {}

  @override
  void visitCommentReference(CommentReference node) {}

  @override
  void visitContinueStatement(ContinueStatement node) {}

  @override
  void visitExportDirective(ExportDirective node) {}

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

  @override
  void visitImportDirective(ImportDirective node) {}

  @override
  void visitLabel(Label node) {}

  @override
  void visitLibraryIdentifier(LibraryIdentifier node) {}

  @override
  void 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 && node.prefix.staticType.isDynamic) {
      return;
    }
    super.visitPrefixedIdentifier(node);
  }

  @override
  void 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;
    } else if (parent is RedirectingConstructorInvocation &&
        identical(node, parent.constructorName)) {
      return;
    } else if (parent is SuperConstructorInvocation &&
        identical(node, parent.constructorName)) {
      return;
    } else if (parent is ConstructorName && identical(node, parent.name)) {
      return;
    } else if (parent is ConstructorFieldInitializer &&
        identical(node, parent.fieldName)) {
      return;
    } else if (node.staticElement is PrefixElement) {
      // Prefixes don't have a type.
      return;
    }
    super.visitSimpleIdentifier(node);
  }

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

  @override
  void 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++;
    }
  }

  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 rootCU.declaredElement.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 DriverResolutionTest {
  test_assert_is() async {
    await assertErrorsInCode(r'''
int f(num n) {
  assert (n is int);
  return n & 0x0F;
}''', [
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 47, 1),
    ]);
  }

  test_conditional_and_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  return (n is int && n > 0) ? n & 0x0F : 0;
}''');
  }

  test_conditional_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  return (n is int) ? n & 0x0F : 0;
}''');
  }

  test_conditional_isNot() async {
    await assertErrorsInCode(r'''
int f(num n) {
  return (n is! int) ? 0 : n & 0x0F;
}''', [
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 44, 1),
    ]);
  }

  test_conditional_or_is() async {
    await assertErrorsInCode(r'''
int f(num n) {
  return (n is! int || n < 0) ? 0 : n & 0x0F;
}''', [
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 53, 1),
    ]);
  }

//  @failingTest
  test_for() async {
    await assertErrorsInCode(r'''
int f(List<int> list) {
  num sum = 0;
  for (num i = 0; i < list.length; i++) {
    sum += list[i];
  }
}''', [
      error(HintCode.MISSING_RETURN, 0, 3),
      error(HintCode.UNUSED_LOCAL_VARIABLE, 30, 3),
    ]);
  }

  test_forEach() async {
    await assertErrorsInCode(r'''
int f(List<int> list) {
  num sum = 0;
  for (num n in list) {
    sum += n & 0x0F;
  }
}''', [
      error(HintCode.MISSING_RETURN, 0, 3),
      error(HintCode.UNUSED_LOCAL_VARIABLE, 30, 3),
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 76, 1),
    ]);
  }

  test_if_and_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  if (n is int && n > 0) {
    return n & 0x0F;
  }
  return 0;
}''');
  }

  test_if_is() async {
    await assertNoErrorsInCode(r'''
int f(num n) {
  if (n is int) {
    return n & 0x0F;
  }
  return 0;
}''');
  }

  test_if_isNot() async {
    await assertErrorsInCode(r'''
int f(num n) {
  if (n is! int) {
    return 0;
  } else {
    return n & 0x0F;
  }
}''', [
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 72, 1),
    ]);
  }

  test_if_isNot_abrupt() async {
    await assertErrorsInCode(r'''
int f(num n) {
  if (n is! int) {
    return 0;
  }
  return n & 0x0F;
}''', [
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 63, 1),
    ]);
  }

  test_if_or_is() async {
    await assertErrorsInCode(r'''
int f(num n) {
  if (n is! int || n < 0) {
    return 0;
  } else {
    return n & 0x0F;
  }
}''', [
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 81, 1),
    ]);
  }

  test_localVar() async {
    await assertErrorsInCode(r'''
int f() {
  num n = 1234;
  return n & 0x0F;
}''', [
      error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 37, 1),
    ]);
  }
}

@reflectiveTest
class TypePropagationTest extends DriverResolutionTest {
  test_assignment_null() async {
    String code = r'''
main() {
  int v; // declare
  v = null;
  return v; // return
}''';
    await resolveTestCode(code);
    assertType(findNode.simple('v; // declare'), 'int');
    assertType(findNode.simple('v = null;'), 'int');
    assertType(findNode.simple('v; // return'), 'int');
  }

  test_functionExpression_asInvocationArgument_notSubtypeOfStaticType() async {
    await assertErrorsInCode(r'''
class A {
  m(void f(int i)) {}
}
x() {
  A a = new A();
  a.m(() => 0);
}''', [
      error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 63, 7),
    ]);
    assertType(findNode.functionExpression('() => 0'), 'int Function()');
  }

  test_initializer_hasStaticType() async {
    await resolveTestCode(r'''
f() {
  int v = 0;
  return v;
}''');
    assertType(findNode.simple('v = 0;'), 'int');
    assertType(findNode.simple('v;'), 'int');
  }

  test_initializer_hasStaticType_parameterized() async {
    await resolveTestCode(r'''
f() {
  List<int> v = <int>[];
  return v;
}''');
    assertType(findNode.simple('v ='), 'List<int>');
    assertType(findNode.simple('v;'), 'List<int>');
  }

  test_initializer_null() async {
    await resolveTestCode(r'''
main() {
  int v = null;
  return v;
}''');
    assertType(findNode.simple('v ='), 'int');
    assertType(findNode.simple('v;'), 'int');
  }

  test_invocation_target_prefixed() async {
    newFile('/test/lib/a.dart', content: r'''
int max(int x, int y) => 0;
''');
    await resolveTestCode('''
import 'a.dart' as helper;
main() {
  helper.max(10, 10); // marker
}''');
    assertElement(
      findNode.simple('max(10, 10)'),
      findElement.importFind('package:test/a.dart').topFunction('max'),
    );
  }

  test_is_subclass() async {
    await resolveTestCode(r'''
class A {}
class B extends A {
  B m() => this;
}
A f(A p) {
  if (p is B) {
    return p.m();
  }
  return p;
}''');
    assertElement(
      findNode.methodInvocation('p.m()'),
      findElement.method('m', of: 'B'),
    );
  }

  test_mutatedOutsideScope() async {
    // https://code.google.com/p/dart/issues/detail?id=22732
    await assertNoErrorsInCode(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;
}''');
  }

  test_objectAccessInference_disabled_for_library_prefix() async {
    newFile('/test/lib/a.dart', content: '''
dynamic get hashCode => 42;
''');
    await assertNoErrorsInCode('''
import 'a.dart' as helper;
main() {
  helper.hashCode;
}''');
    assertTypeDynamic(findNode.prefixed('helper.hashCode'));
  }

  test_objectAccessInference_disabled_for_local_getter() async {
    await assertNoErrorsInCode('''
dynamic get hashCode => null;
main() {
  hashCode; // marker
}''');
    assertTypeDynamic(findNode.simple('hashCode; // marker'));
  }

  test_objectMethodInference_disabled_for_library_prefix() async {
    newFile('/test/lib/a.dart', content: '''
dynamic toString = (int x) => x + 42;
''');
    await assertNoErrorsInCode('''
import 'a.dart' as helper;
main() {
  helper.toString();
}''');
    assertTypeDynamic(findNode.methodInvocation('helper.toString()'));
  }

  test_objectMethodInference_disabled_for_local_function() async {
    await resolveTestCode('''
main() {
  dynamic toString = () => null;
  toString(); // marker
}''');
    assertTypeDynamic(findNode.simple('toString ='));
    assertTypeDynamic(findNode.simple('toString(); // marker'));
  }

  @failingTest
  test_propagatedReturnType_functionExpression() async {
    // TODO(scheglov) disabled because we don't resolve function expression
    await resolveTestCode(r'''
main() {
  var v = (() {return 42;})();
}''');
    assertTypeDynamic(findNode.simple('v = '));
  }
}

@reflectiveTest
class TypeResolverVisitorTest extends ParserTestCase
    with ResourceProviderMixin, ElementsTypesMixin {
  /**
   * 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;

  TypeProvider get typeProvider => _typeProvider;

  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, interfaceType(type));
    _listener.assertNoErrors();
  }

  void setUp({bool shouldSetElementSupertypes: false}) {
    _listener = new GatheringErrorListener();
    AnalysisContext context = TestAnalysisContext();
    Source librarySource = new FileSource(getFile("/lib.dart"));
    // TODO(paulberry): make it possible to override the feature set so we can
    // test NNBD features.
    var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
    LibraryElementImpl element = new LibraryElementImpl.forNode(
        context,
        null,
        AstTestFactory.libraryIdentifier2(["lib"]),
        featureSet.isEnabled(Feature.non_nullable));
    element.definingCompilationUnit = new CompilationUnitElementImpl();
    _typeProvider = new TestTypeProvider();
    libraryScope = new LibraryScope(element);
    _visitor = new TypeResolverVisitor(
        element, librarySource, _typeProvider, _listener,
        featureSet: featureSet,
        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.
    {
      AnalysisContext context = TestAnalysisContext();
      var source = getFile('/test.dart').createSource();
      // TODO(paulberry): make it possible to override the feature set so we can
      // test NNBD features.
      var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
      var libraryElement = new LibraryElementImpl.forNode(
          context, null, null, featureSet.isEnabled(Feature.non_nullable))
        ..definingCompilationUnit = unitElement;
      var libraryScope = new LibraryScope(libraryElement);
      var visitor = new TypeResolverVisitor(
          libraryElement, source, _typeProvider, _listener,
          featureSet: featureSet,
          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, interfaceType(exceptionElement), 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, interfaceType(exceptionElement),
        _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, interfaceType(elementB));
    List<InterfaceType> mixins = elementA.mixins;
    expect(mixins, hasLength(1));
    expect(mixins[0], interfaceType(elementC));
    List<InterfaceType> interfaces = elementA.interfaces;
    expect(interfaces, hasLength(1));
    expect(interfaces[0], interfaceType(elementD));
    _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, interfaceType(elementA));
    _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, 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]), 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, interfaceType(elementR));
    SimpleFormalParameter parameter =
        declaration.functionExpression.parameters.parameters[0];
    expect(parameter.type.type, interfaceType(elementP));
    _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, typeParameterType(elementE));
    SimpleFormalParameter parameter =
        declaration.functionExpression.parameters.parameters[0];
    expect(parameter.type.type, typeParameterType(elementE));
    _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, interfaceType(elementR));
    expect(gType.returnType, interfaceType(elementR));
    expect(gNode.returnType.type, interfaceType(elementR));
    expect(pNode.type.type, interfaceType(elementP));

    _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');
    gElement.typeParameters = [elementE];
    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, interfaceType(elementR));
    expect(gType.returnType, interfaceType(elementR));
    expect(gNode.returnType.type, interfaceType(elementR));
    expect(eNode.type.type, typeParameterType(elementE));

    _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, interfaceType(elementR));
    SimpleFormalParameter parameter = declaration.parameters.parameters[0];
    expect(parameter.type.type, interfaceType(elementP));
    _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, typeParameterType(elementE));
    SimpleFormalParameter parameter = declaration.parameters.parameters[0];
    expect(parameter.type.type, typeParameterType(elementE));
    _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]), 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, interfaceType(classA));
    _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, DynamicTypeImpl.instance);
    expect(typeName.name.staticElement, null);
    _listener.assertErrorsWithCodes([CompileTimeErrorCode.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], interfaceType(classB));
    _listener.assertNoErrors();
  }

  test_visitTypeName_parameters_noArguments() async {
    var tpE = ElementFactory.typeParameterElement('E');
    tpE.defaultType = DynamicTypeImpl.instance;

    ClassElement classA =
        ElementFactory.classElement3(name: 'A', typeParameters: [tpE]);
    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, DynamicTypeImpl.instance);
    expect(prefix.staticElement, null);
    expect(suffix.staticElement, null);
    _listener.assertErrorsWithCodes([CompileTimeErrorCode.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, exceptionType);
    }
    SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
    if (stackTraceParameter != null) {
      expect(stackTraceParameter.staticType, 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;
    {
      AnalysisContext context = TestAnalysisContext();
      var source = getFile('/test.dart').createSource();
      // TODO(paulberry): make it possible to override the feature set so we can
      // test NNBD features.
      var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
      var libraryElement = new LibraryElementImpl.forNode(
          context, null, null, featureSet.isEnabled(Feature.non_nullable))
        ..definingCompilationUnit = unitElement;
      libraryScope = new LibraryScope(libraryElement);
      visitor = new TypeResolverVisitor(
          libraryElement, source, _typeProvider, _listener,
          featureSet: featureSet,
          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";
}
