// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

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/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/element_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.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 '../util/element_type_matchers.dart';
import '../utils.dart';
import 'analysis_context_factory.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnnotationElementResolverTest);
    defineReflectiveTests(ElementResolverTest);
    defineReflectiveTests(PreviewDart2Test);
  });
}

/// 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 AnnotationElementResolverTest extends DriverResolutionTest {
  test_class_namedConstructor() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  const A.named();
}
''');
    await _validateAnnotation('', '@A.named()', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isClassElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'A');
      expect(name2, isNotNull);
      expect(name2.staticElement, isConstructorElement);
      expect(
          resolutionMap.staticElementForIdentifier(name2).displayName, 'named');
      expect(name3, isNull);
      if (annotationElement is ConstructorElement) {
        expect(annotationElement, same(name2.staticElement));
        expect(annotationElement.enclosingElement, name1.staticElement);
        expect(annotationElement.displayName, 'named');
        expect(annotationElement.parameters, isEmpty);
      } else {
        fail('Expected "annotationElement" is ConstructorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  test_class_prefixed_namedConstructor() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  const A.named();
}
''');
    await _validateAnnotation('as p', '@p.A.named()', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isPrefixElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
      expect(name2, isNotNull);
      expect(name2.staticElement, isClassElement);
      expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'A');
      expect(name3, isNotNull);
      expect(name3.staticElement, isConstructorElement);
      expect(
          resolutionMap.staticElementForIdentifier(name3).displayName, 'named');
      if (annotationElement is ConstructorElement) {
        expect(annotationElement, same(name3.staticElement));
        expect(annotationElement.enclosingElement, name2.staticElement);
        expect(annotationElement.displayName, 'named');
        expect(annotationElement.parameters, isEmpty);
      } else {
        fail('Expected "annotationElement" is ConstructorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  test_class_prefixed_staticConstField() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  static const V = 0;
}
''');
    await _validateAnnotation('as p', '@p.A.V', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isPrefixElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
      expect(name2, isNotNull);
      expect(name2.staticElement, isClassElement);
      expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'A');
      expect(name3, isNotNull);
      expect(name3.staticElement, isPropertyAccessorElement);
      expect(resolutionMap.staticElementForIdentifier(name3).displayName, 'V');
      if (annotationElement is PropertyAccessorElement) {
        expect(annotationElement, same(name3.staticElement));
        expect(annotationElement.enclosingElement, name2.staticElement);
        expect(annotationElement.displayName, 'V');
      } else {
        fail('Expected "annotationElement" is PropertyAccessorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  test_class_prefixed_unnamedConstructor() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  const A();
}
''');
    await _validateAnnotation('as p', '@p.A', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isPrefixElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
      expect(name2, isNotNull);
      expect(name2.staticElement, isClassElement);
      expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'A');
      expect(name3, isNull);
      if (annotationElement is ConstructorElement) {
        expect(annotationElement.enclosingElement, name2.staticElement);
        expect(annotationElement.displayName, '');
        expect(annotationElement.parameters, isEmpty);
      } else {
        fail('Expected "annotationElement" is ConstructorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  test_class_staticConstField() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  static const V = 0;
}
''');
    await _validateAnnotation('', '@A.V', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isClassElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'A');
      expect(name2, isNotNull);
      expect(name2.staticElement, isPropertyAccessorElement);
      expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'V');
      expect(name3, isNull);
      if (annotationElement is PropertyAccessorElement) {
        expect(annotationElement, same(name2.staticElement));
        expect(annotationElement.enclosingElement, name1.staticElement);
        expect(annotationElement.displayName, 'V');
      } else {
        fail('Expected "annotationElement" is PropertyAccessorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  test_class_unnamedConstructor() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  const A();
}
''');
    await _validateAnnotation('', '@A', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isClassElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'A');
      expect(name2, isNull);
      expect(name3, isNull);
      if (annotationElement is ConstructorElement) {
        expect(annotationElement.enclosingElement, name1.staticElement);
        expect(annotationElement.displayName, '');
        expect(annotationElement.parameters, isEmpty);
      } else {
        fail('Expected "annotationElement" is ConstructorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  test_topLevelVariable() async {
    newFile('/test/lib/a.dart', content: r'''
const V = 0;
''');
    await _validateAnnotation('', '@V', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isPropertyAccessorElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'V');
      expect(name2, isNull);
      expect(name3, isNull);
      if (annotationElement is PropertyAccessorElement) {
        expect(annotationElement, same(name1.staticElement));
        expect(annotationElement.enclosingElement, isCompilationUnitElement);
        expect(annotationElement.displayName, 'V');
      } else {
        fail('Expected "annotationElement" is PropertyAccessorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  test_topLevelVariable_prefixed() async {
    newFile('/test/lib/a.dart', content: r'''
const V = 0;
''');
    await _validateAnnotation('as p', '@p.V', (SimpleIdentifier name1,
        SimpleIdentifier name2,
        SimpleIdentifier name3,
        Element annotationElement) {
      expect(name1, isNotNull);
      expect(name1.staticElement, isPrefixElement);
      expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
      expect(name2, isNotNull);
      expect(name2.staticElement, isPropertyAccessorElement);
      expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'V');
      expect(name3, isNull);
      if (annotationElement is PropertyAccessorElement) {
        expect(annotationElement, same(name2.staticElement));
        expect(annotationElement.enclosingElement, isCompilationUnitElement);
        expect(annotationElement.displayName, 'V');
      } else {
        fail('Expected "annotationElement" is PropertyAccessorElement, '
            'but (${annotationElement?.runtimeType}) $annotationElement found.');
      }
    });
  }

  Future<void> _validateAnnotation(
      String annotationPrefix,
      String annotationText,
      validator(SimpleIdentifier name1, SimpleIdentifier name2,
          SimpleIdentifier name3, Element annotationElement)) async {
    addTestFile('''
import 'a.dart' $annotationPrefix;
$annotationText
class C {}
''');
    await resolveTestFile();

    var clazz = findNode.classDeclaration('C');
    Annotation annotation = clazz.metadata.single;
    Identifier name = annotation.name;
    Element annotationElement = annotation.element;
    if (name is SimpleIdentifier) {
      validator(name, null, annotation.constructorName, annotationElement);
    } else if (name is PrefixedIdentifier) {
      validator(name.prefix, name.identifier, annotation.constructorName,
          annotationElement);
    } else {
      fail('Uknown "name": ${name?.runtimeType} $name');
    }
  }
}

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

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

  /**
   * The library containing the code being resolved.
   */
  LibraryElementImpl _definingLibrary;

  /**
   * The resolver visitor that maintains the state for the resolver.
   */
  ResolverVisitor _visitor;

  /**
   * The resolver being used to resolve the test cases.
   */
  ElementResolver _resolver;

  void fail_visitExportDirective_combinators() {
    _fail("Not yet tested");
    // Need to set up the exported library so that the identifier can be
    // resolved.
    ExportDirective directive = AstTestFactory.exportDirective2(null, [
      AstTestFactory.hideCombinator2(["A"])
    ]);
    _resolveNode(directive);
    _listener.assertNoErrors();
  }

  void fail_visitFunctionExpressionInvocation() {
    _fail("Not yet tested");
    _listener.assertNoErrors();
  }

  void fail_visitImportDirective_combinators_noPrefix() {
    _fail("Not yet tested");
    // Need to set up the imported library so that the identifier can be
    // resolved.
    ImportDirective directive = AstTestFactory.importDirective3(null, null, [
      AstTestFactory.showCombinator2(["A"])
    ]);
    _resolveNode(directive);
    _listener.assertNoErrors();
  }

  void fail_visitImportDirective_combinators_prefix() {
    _fail("Not yet tested");
    // Need to set up the imported library so that the identifiers can be
    // resolved.
    String prefixName = "p";
    _definingLibrary.imports = <ImportElement>[
      ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
    ];
    ImportDirective directive =
        AstTestFactory.importDirective3(null, prefixName, [
      AstTestFactory.showCombinator2(["A"]),
      AstTestFactory.hideCombinator2(["B"])
    ]);
    _resolveNode(directive);
    _listener.assertNoErrors();
  }

  void fail_visitRedirectingConstructorInvocation() {
    _fail("Not yet tested");
    _listener.assertNoErrors();
  }

  @override
  void setUp() {
    super.setUp();
    _listener = new GatheringErrorListener();
    _createResolver();
  }

  test_lookUpMethodInInterfaces() async {
    InterfaceType intType = _typeProvider.intType;
    //
    // abstract class A { int operator[](int index); }
    //
    ClassElementImpl classA = ElementFactory.classElement2("A");
    MethodElement operator =
        ElementFactory.methodElement("[]", intType, [intType]);
    classA.methods = <MethodElement>[operator];
    //
    // class B implements A {}
    //
    ClassElementImpl classB = ElementFactory.classElement2("B");
    classB.interfaces = <InterfaceType>[classA.type];
    //
    // class C extends Object with B {}
    //
    ClassElementImpl classC = ElementFactory.classElement2("C");
    classC.mixins = <InterfaceType>[classB.type];
    //
    // class D extends C {}
    //
    ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
    //
    // D a;
    // a[i];
    //
    SimpleIdentifier array = AstTestFactory.identifier3("a");
    array.staticType = classD.type;
    IndexExpression expression =
        AstTestFactory.indexExpression(array, AstTestFactory.identifier3("i"));
    expect(_resolveIndexExpression(expression), same(operator));
    _listener.assertNoErrors();
  }

  test_visitAssignmentExpression_compound() async {
    InterfaceType intType = _typeProvider.intType;
    SimpleIdentifier leftHandSide = AstTestFactory.identifier3("a");
    leftHandSide.staticType = intType;
    AssignmentExpression assignment = AstTestFactory.assignmentExpression(
        leftHandSide, TokenType.PLUS_EQ, AstTestFactory.integer(1));
    _resolveNode(assignment);
    expect(
        assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
    _listener.assertNoErrors();
  }

  test_visitAssignmentExpression_simple() async {
    AssignmentExpression expression = AstTestFactory.assignmentExpression(
        AstTestFactory.identifier3("x"),
        TokenType.EQ,
        AstTestFactory.integer(0));
    _resolveNode(expression);
    expect(expression.staticElement, isNull);
    _listener.assertNoErrors();
  }

  test_visitBinaryExpression_bangEq() async {
    // String i;
    // var j;
    // i == j
    InterfaceType stringType = _typeProvider.stringType;
    SimpleIdentifier left = AstTestFactory.identifier3("i");
    left.staticType = stringType;
    BinaryExpression expression = AstTestFactory.binaryExpression(
        left, TokenType.BANG_EQ, AstTestFactory.identifier3("j"));
    _resolveNode(expression);
    var stringElement = stringType.element;
    expect(expression.staticElement, isNotNull);
    expect(
        expression.staticElement,
        stringElement.lookUpMethod(
            TokenType.EQ_EQ.lexeme, stringElement.library));
    _listener.assertNoErrors();
  }

  test_visitBinaryExpression_eq() async {
    // String i;
    // var j;
    // i == j
    InterfaceType stringType = _typeProvider.stringType;
    SimpleIdentifier left = AstTestFactory.identifier3("i");
    left.staticType = stringType;
    BinaryExpression expression = AstTestFactory.binaryExpression(
        left, TokenType.EQ_EQ, AstTestFactory.identifier3("j"));
    _resolveNode(expression);
    var stringElement = stringType.element;
    expect(
        expression.staticElement,
        stringElement.lookUpMethod(
            TokenType.EQ_EQ.lexeme, stringElement.library));
    _listener.assertNoErrors();
  }

  test_visitBinaryExpression_plus() async {
    // num i;
    // var j;
    // i + j
    InterfaceType numType = _typeProvider.numType;
    SimpleIdentifier left = AstTestFactory.identifier3("i");
    left.staticType = numType;
    BinaryExpression expression = AstTestFactory.binaryExpression(
        left, TokenType.PLUS, AstTestFactory.identifier3("j"));
    _resolveNode(expression);
    expect(expression.staticElement, getMethod(numType, "+"));
    _listener.assertNoErrors();
  }

  test_visitBreakStatement_withLabel() async {
    // loop: while (true) {
    //   break loop;
    // }
    String label = "loop";
    LabelElementImpl labelElement = new LabelElementImpl.forNode(
        AstTestFactory.identifier3(label), false, false);
    BreakStatement breakStatement = AstTestFactory.breakStatement2(label);
    Expression condition = AstTestFactory.booleanLiteral(true);
    WhileStatement whileStatement =
        AstTestFactory.whileStatement(condition, breakStatement);
    expect(_resolveBreak(breakStatement, labelElement, whileStatement),
        same(labelElement));
    expect(breakStatement.target, same(whileStatement));
    _listener.assertNoErrors();
  }

  test_visitBreakStatement_withoutLabel() async {
    BreakStatement statement = AstTestFactory.breakStatement();
    _resolveStatement(statement, null, null);
    _listener.assertNoErrors();
  }

  test_visitCommentReference_prefixedIdentifier_class_getter() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    // set accessors
    String propName = "p";
    PropertyAccessorElement getter =
        ElementFactory.getterElement(propName, false, _typeProvider.intType);
    PropertyAccessorElement setter =
        ElementFactory.setterElement(propName, false, _typeProvider.intType);
    classA.accessors = <PropertyAccessorElement>[getter, setter];
    // set name scope
    _visitor.nameScope = new EnclosedScope(null)
      ..defineNameWithoutChecking('A', classA);
    // prepare "A.p"
    PrefixedIdentifier prefixed = AstTestFactory.identifier5('A', 'p');
    CommentReference commentReference =
        astFactory.commentReference(null, prefixed);
    // resolve
    _resolveNode(commentReference);
    expect(prefixed.prefix.staticElement, classA);
    expect(prefixed.identifier.staticElement, getter);
    _listener.assertNoErrors();
  }

  test_visitCommentReference_prefixedIdentifier_class_method() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    // set method
    MethodElement method =
        ElementFactory.methodElement("m", _typeProvider.intType);
    classA.methods = <MethodElement>[method];
    // set name scope
    _visitor.nameScope = new EnclosedScope(null)
      ..defineNameWithoutChecking('A', classA);
    // prepare "A.m"
    PrefixedIdentifier prefixed = AstTestFactory.identifier5('A', 'm');
    CommentReference commentReference =
        astFactory.commentReference(null, prefixed);
    // resolve
    _resolveNode(commentReference);
    expect(prefixed.prefix.staticElement, classA);
    expect(prefixed.identifier.staticElement, method);
    _listener.assertNoErrors();
  }

  test_visitCommentReference_prefixedIdentifier_class_operator() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    // set method
    MethodElement method =
        ElementFactory.methodElement("==", _typeProvider.boolType);
    classA.methods = <MethodElement>[method];
    // set name scope
    _visitor.nameScope = new EnclosedScope(null)
      ..defineNameWithoutChecking('A', classA);
    // prepare "A.=="
    PrefixedIdentifier prefixed = AstTestFactory.identifier5('A', '==');
    CommentReference commentReference =
        astFactory.commentReference(null, prefixed);
    // resolve
    _resolveNode(commentReference);
    expect(prefixed.prefix.staticElement, classA);
    expect(prefixed.identifier.staticElement, method);
    _listener.assertNoErrors();
  }

  test_visitConstructorName_named() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String constructorName = "a";
    ConstructorElement constructor =
        ElementFactory.constructorElement2(classA, constructorName);
    classA.constructors = <ConstructorElement>[constructor];
    ConstructorName name = AstTestFactory.constructorName(
        AstTestFactory.typeName(classA), constructorName);
    _resolveNode(name);
    expect(name.staticElement, same(constructor));
    _listener.assertNoErrors();
  }

  test_visitConstructorName_unnamed() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String constructorName = null;
    ConstructorElement constructor =
        ElementFactory.constructorElement2(classA, constructorName);
    classA.constructors = <ConstructorElement>[constructor];
    ConstructorName name = AstTestFactory.constructorName(
        AstTestFactory.typeName(classA), constructorName);
    _resolveNode(name);
    expect(name.staticElement, same(constructor));
    _listener.assertNoErrors();
  }

  test_visitContinueStatement_withLabel() async {
    // loop: while (true) {
    //   continue loop;
    // }
    String label = "loop";
    LabelElementImpl labelElement = new LabelElementImpl.forNode(
        AstTestFactory.identifier3(label), false, false);
    ContinueStatement continueStatement =
        AstTestFactory.continueStatement(label);
    Expression condition = AstTestFactory.booleanLiteral(true);
    WhileStatement whileStatement =
        AstTestFactory.whileStatement(condition, continueStatement);
    expect(_resolveContinue(continueStatement, labelElement, whileStatement),
        same(labelElement));
    expect(continueStatement.target, same(whileStatement));
    _listener.assertNoErrors();
  }

  test_visitContinueStatement_withoutLabel() async {
    ContinueStatement statement = AstTestFactory.continueStatement();
    _resolveStatement(statement, null, null);
    _listener.assertNoErrors();
  }

  test_visitEnumDeclaration() async {
    CompilationUnitElementImpl compilationUnitElement =
        ElementFactory.compilationUnit('foo.dart');
    EnumElementImpl enumElement =
        ElementFactory.enumElement(_typeProvider, ('E'));
    compilationUnitElement.enums = <ClassElement>[enumElement];
    EnumDeclaration enumNode = AstTestFactory.enumDeclaration2('E', []);
    Annotation annotationNode =
        AstTestFactory.annotation(AstTestFactory.identifier3('a'));
    annotationNode.element = ElementFactory.classElement2('A');
    annotationNode.elementAnnotation =
        new ElementAnnotationImpl(compilationUnitElement);
    enumNode.metadata.add(annotationNode);
    enumNode.name.staticElement = enumElement;
    List<ElementAnnotation> metadata = <ElementAnnotation>[
      annotationNode.elementAnnotation
    ];
    _resolveNode(enumNode);
    expect(metadata[0].element, annotationNode.element);
  }

  test_visitExportDirective_noCombinators() async {
    ExportDirective directive = AstTestFactory.exportDirective2(null);
    directive.element = ElementFactory.exportFor(
        ElementFactory.library(_definingLibrary.context, "lib"));
    _resolveNode(directive);
    _listener.assertNoErrors();
  }

  test_visitFieldFormalParameter() async {
    String fieldName = "f";
    InterfaceType intType = _typeProvider.intType;
    FieldElementImpl fieldElement =
        ElementFactory.fieldElement(fieldName, false, false, false, intType);
    ClassElementImpl classA = ElementFactory.classElement2("A");
    classA.fields = <FieldElement>[fieldElement];
    FieldFormalParameter parameter =
        AstTestFactory.fieldFormalParameter2(fieldName);
    FieldFormalParameterElementImpl parameterElement =
        ElementFactory.fieldFormalParameter(parameter.identifier);
    parameterElement.field = fieldElement;
    parameterElement.type = intType;
    parameter.identifier.staticElement = parameterElement;
    _resolveInClass(parameter, classA);
    expect(resolutionMap.elementDeclaredByFormalParameter(parameter).type,
        same(intType));
  }

  test_visitImportDirective_noCombinators_noPrefix() async {
    ImportDirective directive = AstTestFactory.importDirective3(null, null);
    directive.element = ElementFactory.importFor(
        ElementFactory.library(_definingLibrary.context, "lib"), null);
    _resolveNode(directive);
    _listener.assertNoErrors();
  }

  test_visitImportDirective_noCombinators_prefix() async {
    String prefixName = "p";
    ImportElement importElement = ElementFactory.importFor(
        ElementFactory.library(_definingLibrary.context, "lib"),
        ElementFactory.prefix(prefixName));
    _definingLibrary.imports = <ImportElement>[importElement];
    ImportDirective directive =
        AstTestFactory.importDirective3(null, prefixName);
    directive.element = importElement;
    _resolveNode(directive);
    _listener.assertNoErrors();
  }

  test_visitImportDirective_withCombinators() async {
    ShowCombinator combinator = AstTestFactory.showCombinator2(["A", "B", "C"]);
    ImportDirective directive =
        AstTestFactory.importDirective3(null, null, [combinator]);
    LibraryElementImpl library =
        ElementFactory.library(_definingLibrary.context, "lib");
    TopLevelVariableElementImpl varA =
        ElementFactory.topLevelVariableElement2("A");
    TopLevelVariableElementImpl varB =
        ElementFactory.topLevelVariableElement2("B");
    TopLevelVariableElementImpl varC =
        ElementFactory.topLevelVariableElement2("C");
    CompilationUnitElementImpl unit =
        library.definingCompilationUnit as CompilationUnitElementImpl;
    unit.accessors = <PropertyAccessorElement>[
      varA.getter,
      varA.setter,
      varB.getter,
      varC.setter
    ];
    unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC];
    directive.element = ElementFactory.importFor(library, null);
    _resolveNode(directive);
    expect(combinator.shownNames[0].staticElement, same(varA));
    expect(combinator.shownNames[1].staticElement, same(varB));
    expect(combinator.shownNames[2].staticElement, same(varC));
    _listener.assertNoErrors();
  }

  test_visitIndexExpression_get() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    InterfaceType intType = _typeProvider.intType;
    MethodElement getter =
        ElementFactory.methodElement("[]", intType, [intType]);
    classA.methods = <MethodElement>[getter];
    SimpleIdentifier array = AstTestFactory.identifier3("a");
    array.staticType = classA.type;
    IndexExpression expression =
        AstTestFactory.indexExpression(array, AstTestFactory.identifier3("i"));
    expect(_resolveIndexExpression(expression), same(getter));
    _listener.assertNoErrors();
  }

  test_visitIndexExpression_set() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    InterfaceType intType = _typeProvider.intType;
    MethodElement setter =
        ElementFactory.methodElement("[]=", intType, [intType]);
    classA.methods = <MethodElement>[setter];
    SimpleIdentifier array = AstTestFactory.identifier3("a");
    array.staticType = classA.type;
    IndexExpression expression =
        AstTestFactory.indexExpression(array, AstTestFactory.identifier3("i"));
    AstTestFactory.assignmentExpression(
        expression, TokenType.EQ, AstTestFactory.integer(0));
    expect(_resolveIndexExpression(expression), same(setter));
    _listener.assertNoErrors();
  }

  test_visitInstanceCreationExpression_named() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String constructorName = "a";
    ConstructorElement constructor =
        ElementFactory.constructorElement2(classA, constructorName);
    classA.constructors = <ConstructorElement>[constructor];
    ConstructorName name = AstTestFactory.constructorName(
        AstTestFactory.typeName(classA), constructorName);
    name.staticElement = constructor;
    InstanceCreationExpression creation =
        AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
    _resolveNode(creation);
    expect(creation.staticElement, same(constructor));
    _listener.assertNoErrors();
  }

  test_visitInstanceCreationExpression_unnamed() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String constructorName = null;
    ConstructorElement constructor =
        ElementFactory.constructorElement2(classA, constructorName);
    classA.constructors = <ConstructorElement>[constructor];
    ConstructorName name = AstTestFactory.constructorName(
        AstTestFactory.typeName(classA), constructorName);
    name.staticElement = constructor;
    InstanceCreationExpression creation =
        AstTestFactory.instanceCreationExpression(Keyword.NEW, name);
    _resolveNode(creation);
    expect(creation.staticElement, same(constructor));
    _listener.assertNoErrors();
  }

  test_visitInstanceCreationExpression_unnamed_namedParameter() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String constructorName = null;
    ConstructorElementImpl constructor =
        ElementFactory.constructorElement2(classA, constructorName);
    String parameterName = "a";
    ParameterElement parameter = ElementFactory.namedParameter(parameterName);
    constructor.parameters = <ParameterElement>[parameter];
    classA.constructors = <ConstructorElement>[constructor];
    ConstructorName name = AstTestFactory.constructorName(
        AstTestFactory.typeName(classA), constructorName);
    name.staticElement = constructor;
    InstanceCreationExpression creation =
        AstTestFactory.instanceCreationExpression(Keyword.NEW, name, [
      AstTestFactory.namedExpression2(parameterName, AstTestFactory.integer(0))
    ]);
    _resolveNode(creation);
    expect(creation.staticElement, same(constructor));
    expect(
        (creation.argumentList.arguments[0] as NamedExpression)
            .name
            .label
            .staticElement,
        same(parameter));
    _listener.assertNoErrors();
  }

  test_visitMethodInvocation() async {
    InterfaceType numType = _typeProvider.numType;
    SimpleIdentifier left = AstTestFactory.identifier3("i");
    left.staticType = numType;
    String methodName = "abs";
    MethodInvocation invocation =
        AstTestFactory.methodInvocation(left, methodName);
    _resolveNode(invocation);
    expect(invocation.methodName.staticElement,
        same(getMethod(numType, methodName)));
    _listener.assertNoErrors();
  }

  test_visitPostfixExpression() async {
    InterfaceType numType = _typeProvider.numType;
    SimpleIdentifier operand = AstTestFactory.identifier3("i");
    operand.staticType = numType;
    PostfixExpression expression =
        AstTestFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
    _resolveNode(expression);
    expect(expression.staticElement, getMethod(numType, "+"));
    _listener.assertNoErrors();
  }

  @failingTest
  test_visitPostfixExpression_bang() async {
    InterfaceType numType = _typeProvider.numType;
    SimpleIdentifier operand = AstTestFactory.identifier3("i");
    operand.staticType = numType;
    PostfixExpression expression =
        AstTestFactory.postfixExpression(operand, TokenType.BANG);
    // TODO(danrubel): fails with Unsupported operation
    _resolveNode(expression);
    _listener.assertErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_OPERATOR]);
  }

  @failingTest
  test_visitPostfixExpression_bang_NNBD() async {
    // TODO(danrubel): enable NNBD
    InterfaceType numType = _typeProvider.numType;
    SimpleIdentifier operand = AstTestFactory.identifier3("i");
    operand.staticType = numType;
    PostfixExpression expression =
        AstTestFactory.postfixExpression(operand, TokenType.BANG);
    _resolveNode(expression);
    // TODO(danrubel): fails with Unsupported operation
    expect(expression.staticElement, getMethod(numType, "!"));
    _listener.assertNoErrors();
  }

  test_visitPrefixedIdentifier_dynamic() async {
    DartType dynamicType = _typeProvider.dynamicType;
    SimpleIdentifier target = AstTestFactory.identifier3("a");
    VariableElementImpl variable = ElementFactory.localVariableElement(target);
    variable.type = dynamicType;
    target.staticElement = variable;
    target.staticType = dynamicType;
    PrefixedIdentifier identifier =
        AstTestFactory.identifier(target, AstTestFactory.identifier3("b"));
    _resolveNode(identifier);
    expect(identifier.staticElement, isNull);
    expect(identifier.identifier.staticElement, isNull);
    _listener.assertNoErrors();
  }

  test_visitPrefixedIdentifier_nonDynamic() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String getterName = "b";
    PropertyAccessorElement getter =
        ElementFactory.getterElement(getterName, false, _typeProvider.intType);
    classA.accessors = <PropertyAccessorElement>[getter];
    SimpleIdentifier target = AstTestFactory.identifier3("a");
    VariableElementImpl variable = ElementFactory.localVariableElement(target);
    variable.type = classA.type;
    target.staticElement = variable;
    target.staticType = classA.type;
    PrefixedIdentifier identifier = AstTestFactory.identifier(
        target, AstTestFactory.identifier3(getterName));
    _resolveNode(identifier);
    expect(identifier.staticElement, same(getter));
    expect(identifier.identifier.staticElement, same(getter));
    _listener.assertNoErrors();
  }

  test_visitPrefixedIdentifier_staticClassMember_getter() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    // set accessors
    String propName = "b";
    PropertyAccessorElement getter =
        ElementFactory.getterElement(propName, false, _typeProvider.intType);
    PropertyAccessorElement setter =
        ElementFactory.setterElement(propName, false, _typeProvider.intType);
    classA.accessors = <PropertyAccessorElement>[getter, setter];
    // prepare "A.m"
    SimpleIdentifier target = AstTestFactory.identifier3("A");
    target.staticElement = classA;
    target.staticType = classA.type;
    PrefixedIdentifier identifier =
        AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
    // resolve
    _resolveNode(identifier);
    expect(identifier.staticElement, same(getter));
    expect(identifier.identifier.staticElement, same(getter));
    _listener.assertNoErrors();
  }

  test_visitPrefixedIdentifier_staticClassMember_method() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    // set methods
    String propName = "m";
    MethodElement method =
        ElementFactory.methodElement("m", _typeProvider.intType);
    classA.methods = <MethodElement>[method];
    // prepare "A.m"
    SimpleIdentifier target = AstTestFactory.identifier3("A");
    target.staticElement = classA;
    target.staticType = classA.type;
    PrefixedIdentifier identifier =
        AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
    AstTestFactory.assignmentExpression(
        identifier, TokenType.EQ, AstTestFactory.nullLiteral());
    // resolve
    _resolveNode(identifier);
    expect(identifier.staticElement, same(method));
    expect(identifier.identifier.staticElement, same(method));
    _listener.assertNoErrors();
  }

  test_visitPrefixedIdentifier_staticClassMember_setter() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    // set accessors
    String propName = "b";
    PropertyAccessorElement getter =
        ElementFactory.getterElement(propName, false, _typeProvider.intType);
    PropertyAccessorElement setter =
        ElementFactory.setterElement(propName, false, _typeProvider.intType);
    classA.accessors = <PropertyAccessorElement>[getter, setter];
    // prepare "A.b = null"
    SimpleIdentifier target = AstTestFactory.identifier3("A");
    target.staticElement = classA;
    target.staticType = classA.type;
    PrefixedIdentifier identifier =
        AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
    AstTestFactory.assignmentExpression(
        identifier, TokenType.EQ, AstTestFactory.nullLiteral());
    // resolve
    _resolveNode(identifier);
    expect(identifier.staticElement, same(setter));
    expect(identifier.identifier.staticElement, same(setter));
    _listener.assertNoErrors();
  }

  test_visitPrefixExpression() async {
    InterfaceType numType = _typeProvider.numType;
    SimpleIdentifier operand = AstTestFactory.identifier3("i");
    operand.staticType = numType;
    PrefixExpression expression =
        AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
    _resolveNode(expression);
    expect(expression.staticElement, getMethod(numType, "+"));
    _listener.assertNoErrors();
  }

  test_visitPropertyAccess_getter_identifier() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String getterName = "b";
    PropertyAccessorElement getter =
        ElementFactory.getterElement(getterName, false, _typeProvider.intType);
    classA.accessors = <PropertyAccessorElement>[getter];
    SimpleIdentifier target = AstTestFactory.identifier3("a");
    target.staticType = classA.type;
    PropertyAccess access = AstTestFactory.propertyAccess2(target, getterName);
    _resolveNode(access);
    expect(access.propertyName.staticElement, same(getter));
    _listener.assertNoErrors();
  }

  test_visitPropertyAccess_getter_super() async {
    //
    // class A {
    //  int get b;
    // }
    // class B {
    //   ... super.m ...
    // }
    //
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String getterName = "b";
    PropertyAccessorElement getter =
        ElementFactory.getterElement(getterName, false, _typeProvider.intType);
    classA.accessors = <PropertyAccessorElement>[getter];
    SuperExpression target = AstTestFactory.superExpression();
    target.staticType = ElementFactory.classElement("B", classA.type).type;
    PropertyAccess access = AstTestFactory.propertyAccess2(target, getterName);
    AstTestFactory.methodDeclaration2(
        null,
        null,
        null,
        null,
        AstTestFactory.identifier3("m"),
        AstTestFactory.formalParameterList(),
        AstTestFactory.expressionFunctionBody(access));
    _resolveNode(access);
    expect(access.propertyName.staticElement, same(getter));
    _listener.assertNoErrors();
  }

  test_visitPropertyAccess_setter_this() async {
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String setterName = "b";
    PropertyAccessorElement setter =
        ElementFactory.setterElement(setterName, false, _typeProvider.intType);
    classA.accessors = <PropertyAccessorElement>[setter];
    ThisExpression target = AstTestFactory.thisExpression();
    target.staticType = classA.type;
    PropertyAccess access = AstTestFactory.propertyAccess2(target, setterName);
    AstTestFactory.assignmentExpression(
        access, TokenType.EQ, AstTestFactory.integer(0));
    _resolveNode(access);
    expect(access.propertyName.staticElement, same(setter));
    _listener.assertNoErrors();
  }

  test_visitSimpleIdentifier_classScope() async {
    InterfaceType doubleType = _typeProvider.doubleType;
    String fieldName = "NAN";
    SimpleIdentifier node = AstTestFactory.identifier3(fieldName);
    _resolveInClass(node, doubleType.element);
    expect(node.staticElement, getGetter(doubleType, fieldName));
    _listener.assertNoErrors();
  }

  test_visitSimpleIdentifier_dynamic() async {
    SimpleIdentifier node = AstTestFactory.identifier3("dynamic");
    _resolveIdentifier(node);
    expect(node.staticElement, same(_typeProvider.dynamicType.element));
    expect(node.staticType, same(_typeProvider.typeType));
    _listener.assertNoErrors();
  }

  test_visitSimpleIdentifier_lexicalScope() async {
    SimpleIdentifier node = AstTestFactory.identifier3("i");
    VariableElementImpl element = ElementFactory.localVariableElement(node);
    expect(_resolveIdentifier(node, [element]), same(element));
    _listener.assertNoErrors();
  }

  test_visitSimpleIdentifier_lexicalScope_field_setter() async {
    InterfaceType intType = _typeProvider.intType;
    ClassElementImpl classA = ElementFactory.classElement2("A");
    String fieldName = "a";
    FieldElement field =
        ElementFactory.fieldElement(fieldName, false, false, false, intType);
    classA.fields = <FieldElement>[field];
    classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
    SimpleIdentifier node = AstTestFactory.identifier3(fieldName);
    AstTestFactory.assignmentExpression(
        node, TokenType.EQ, AstTestFactory.integer(0));
    _resolveInClass(node, classA);
    PropertyAccessorElement element = node.staticElement;
    expect(element.isSetter, isTrue);
    _listener.assertNoErrors();
  }

  test_visitSuperConstructorInvocation() async {
    ClassElementImpl superclass = ElementFactory.classElement2("A");
    ConstructorElementImpl superConstructor =
        ElementFactory.constructorElement2(superclass, null);
    superclass.constructors = <ConstructorElement>[superConstructor];
    ClassElementImpl subclass =
        ElementFactory.classElement("B", superclass.type);
    ConstructorElementImpl subConstructor =
        ElementFactory.constructorElement2(subclass, null);
    subclass.constructors = <ConstructorElement>[subConstructor];
    SuperConstructorInvocation invocation =
        AstTestFactory.superConstructorInvocation();
    AstTestFactory.classDeclaration(null, 'C', null, null, null, null, [
      AstTestFactory.constructorDeclaration(null, 'C', null, [invocation])
    ]);
    _resolveInClass(invocation, subclass);
    expect(invocation.staticElement, superConstructor);
    _listener.assertNoErrors();
  }

  test_visitSuperConstructorInvocation_namedParameter() async {
    ClassElementImpl superclass = ElementFactory.classElement2("A");
    ConstructorElementImpl superConstructor =
        ElementFactory.constructorElement2(superclass, null);
    String parameterName = "p";
    ParameterElement parameter = ElementFactory.namedParameter(parameterName);
    superConstructor.parameters = <ParameterElement>[parameter];
    superclass.constructors = <ConstructorElement>[superConstructor];
    ClassElementImpl subclass =
        ElementFactory.classElement("B", superclass.type);
    ConstructorElementImpl subConstructor =
        ElementFactory.constructorElement2(subclass, null);
    subclass.constructors = <ConstructorElement>[subConstructor];
    SuperConstructorInvocation invocation =
        AstTestFactory.superConstructorInvocation([
      AstTestFactory.namedExpression2(parameterName, AstTestFactory.integer(0))
    ]);
    AstTestFactory.classDeclaration(null, 'C', null, null, null, null, [
      AstTestFactory.constructorDeclaration(null, 'C', null, [invocation])
    ]);
    _resolveInClass(invocation, subclass);
    expect(invocation.staticElement, superConstructor);
    expect(
        (invocation.argumentList.arguments[0] as NamedExpression)
            .name
            .label
            .staticElement,
        same(parameter));
    _listener.assertNoErrors();
  }

  /**
   * Create and return the resolver used by the tests.
   */
  void _createResolver() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
        resourceProvider: resourceProvider);
    _typeProvider = context.typeProvider;

    var inheritance = new InheritanceManager2(context.typeSystem);
    Source source = new FileSource(getFile("/test.dart"));
    CompilationUnitElementImpl unit = new CompilationUnitElementImpl();
    unit.librarySource = unit.source = source;
    _definingLibrary = ElementFactory.library(context, "test");
    _definingLibrary.definingCompilationUnit = unit;
    _visitor = new ResolverVisitor(
        inheritance, _definingLibrary, source, _typeProvider, _listener,
        featureSet: FeatureSet.forTesting(),
        nameScope: new LibraryScope(_definingLibrary));
    _resolver = _visitor.elementResolver;
  }

  /**
   * Return the element associated with the label of [statement] after the
   * resolver has resolved it.  [labelElement] is the label element to be
   * defined in the statement's label scope, and [labelTarget] is the statement
   * the label resolves to.
   */
  Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
      Statement labelTarget) {
    _resolveStatement(statement, labelElement, labelTarget);
    return statement.label.staticElement;
  }

  /**
   * Return the element associated with the label [statement] after the
   * resolver has resolved it.  [labelElement] is the label element to be
   * defined in the statement's label scope, and [labelTarget] is the AST node
   * the label resolves to.
   *
   * @param statement the statement to be resolved
   * @param labelElement the label element to be defined in the statement's label scope
   * @return the element to which the statement's label was resolved
   */
  Element _resolveContinue(ContinueStatement statement,
      LabelElementImpl labelElement, AstNode labelTarget) {
    _resolveStatement(statement, labelElement, labelTarget);
    return statement.label.staticElement;
  }

  /**
   * 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
   */
  Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
    _resolveNode(node, definedElements);
    return node.staticElement;
  }

  /**
   * Return the element associated with the given identifier after the resolver has resolved the
   * identifier.
   *
   * @param node the expression to be resolved
   * @param enclosingClass the element representing the class enclosing the identifier
   * @return the element to which the expression was resolved
   */
  void _resolveInClass(AstNode node, ClassElement enclosingClass) {
    Scope outerScope = _visitor.nameScope;
    try {
      _visitor.enclosingClass = enclosingClass;
      EnclosedScope innerScope = new ClassScope(
          new TypeParameterScope(outerScope, enclosingClass), enclosingClass);
      _visitor.nameScope = innerScope;
      node.accept(_resolver);
    } finally {
      _visitor.enclosingClass = null;
      _visitor.nameScope = outerScope;
    }
  }

  /**
   * Return the element associated with the given expression after the resolver has resolved the
   * expression.
   *
   * @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
   */
  Element _resolveIndexExpression(IndexExpression node,
      [List<Element> definedElements]) {
    _resolveNode(node, definedElements);
    return node.staticElement;
  }

  /**
   * 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]) {
    Scope outerScope = _visitor.nameScope;
    try {
      EnclosedScope innerScope = new EnclosedScope(outerScope);
      if (definedElements != null) {
        for (Element element in definedElements) {
          innerScope.define(element);
        }
      }
      _visitor.nameScope = innerScope;
      node.accept(_resolver);
    } finally {
      _visitor.nameScope = outerScope;
    }
  }

  /**
   * Return the element associated with the label of the given statement after the resolver has
   * resolved the statement.
   *
   * @param statement the statement to be resolved
   * @param labelElement the label element to be defined in the statement's label scope
   * @return the element to which the statement's label was resolved
   */
  void _resolveStatement(
      Statement statement, LabelElementImpl labelElement, AstNode labelTarget) {
    LabelScope outerScope = _visitor.labelScope;
    try {
      LabelScope innerScope;
      if (labelElement == null) {
        innerScope = outerScope;
      } else {
        innerScope = new LabelScope(
            outerScope, labelElement.name, labelTarget, labelElement);
      }
      _visitor.labelScope = innerScope;
      statement.accept(_resolver);
    } finally {
      _visitor.labelScope = outerScope;
    }
  }
}

@reflectiveTest
class PreviewDart2Test extends ResolverTestCase {
  @override
  void setUp() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    resetWith(options: options);
  }

  /**
   * Tests and verifies that even with a explicit 'new' keyword, the
   * construction of the InstanceCreationExpression node with types and elements
   * is all correct.
   */
  test_visitMethodInvocations_explicit() async {
    String code = '''
class A {
  A() {}
}
main() {
  new A();
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;

    expect(creation.staticElement, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, isConstructorElement);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name, isNull);
  }

  /**
   * Test that the call to a constructor with an implicit unnamed constructor is
   * re-written as an InstanceCreationExpression AST node from a
   * MethodInvocation.
   *
   * C()
   */
  test_visitMethodInvocations_implicit() async {
    String code = '''
class A {
  A(a, {b}) {}
}
main() {
  A(0, b: 1);
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;
    ConstructorElement constructor = creation.staticElement;

    expect(constructor, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, constructor);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name, isNull);

    List<Expression> arguments = creation.argumentList.arguments;
    Expression argumentA = arguments[0];
    expect(argumentA.staticParameterElement, constructor.parameters[0]);
    NamedExpression argumentB = arguments[1];
    expect(argumentB.name.label.staticElement, constructor.parameters[1]);
  }

  /**
   * Test that the call to a constructor with an implicit unnamed constructor is
   * re-written as an InstanceCreationExpression AST node from a
   * MethodInvocation.
   *
   * C(), where class C has no constructors
   */
  test_visitMethodInvocations_implicit_implicit() async {
    String code = '''
class A {}
main() {
  A();
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;
    ConstructorElement constructor = creation.staticElement;

    expect(constructor, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, constructor);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name, isNull);

    expect(creation.argumentList.arguments, isEmpty);
  }

  /**
   * Test that the call to a constructor with an implicit named constructor is
   * re-written as an InstanceCreationExpression AST node from a
   * MethodInvocation.
   *
   * C.n()
   */
  test_visitMethodInvocations_implicit_named() async {
    String code = '''
class A {
  A.named() {}
}
main() {
  A.named();
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;
    ConstructorElement constructor = creation.staticElement;

    expect(constructor, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, constructor);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name.staticElement, constructor);
  }

  /**
   * Test that the call to a constructor with a prefixed implicit constructor is
   * re-written as an InstanceCreationExpression AST node from a
   * MethodInvocation.
   *
   * p.C()
   */
  test_visitMethodInvocations_implicit_prefixed() async {
    addNamedSource("/fileOne.dart", r'''
class A {
  A() {}
}
''');
    String code = '''
import 'fileOne.dart' as one;

main() {
  one.A();
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;
    ConstructorElement constructor = creation.staticElement;

    expect(constructor, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, constructor);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name, isNull);
  }

  /**
   * Test that the call to a constructor with a prefixed implicit named constructor is
   * re-written as an InstanceCreationExpression AST node from a
   * MethodInvocation.
   *
   * p.C.n()
   */
  test_visitMethodInvocations_implicit_prefixed_named() async {
    addNamedSource("/fileOne.dart", r'''
class A {
  A.named(a, {b}) {}
}
''');
    String code = '''
import 'fileOne.dart' as one;
main() {
  one.A.named(0, b: 1);
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;
    ConstructorElement constructor = creation.staticElement;

    expect(constructor, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, constructor);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name.staticElement, constructor);

    List<Expression> arguments = creation.argumentList.arguments;
    Expression argumentA = arguments[0];
    expect(argumentA.staticParameterElement, constructor.parameters[0]);
    NamedExpression argumentB = arguments[1];
    expect(argumentB.name.label.staticElement, constructor.parameters[1]);
  }

  /**
   * Test that the call to a constructor with a prefixed implicit constructor is
   * re-written as an InstanceCreationExpression AST node from a
   * MethodInvocation.
   *
   * p.C<>()
   */
  test_visitMethodInvocations_implicit_prefixed_typeArgs() async {
    addNamedSource("/fileOne.dart", r'''
class A<T> {
  final T x;
  A(this.x) {}
}
''');
    String code = '''
import 'fileOne.dart' as one;

main() {
  one.A<int>(42);
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;
    ConstructorElement constructor = creation.staticElement;

    expect(constructor, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, constructor);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name, isNull);
  }

  /**
   * Test that the call to a constructor with an implicit unnamed constructor is
   * re-written as an InstanceCreationExpression AST node from a
   * MethodInvocation.
   *
   * C<>()
   */
  test_visitMethodInvocations_implicit_typeArgs() async {
    String code = '''
class A<T> {
  final T x;
  A(this.x) {}
}
main() {
  A<int>(42);
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    InstanceCreationExpression creation = statement.expression;
    ConstructorElement constructor = creation.staticElement;

    expect(constructor, isConstructorElement);
    expect(creation.staticType, isNotNull);

    expect(creation.constructorName.staticElement, constructor);

    expect(creation.constructorName.type.type, isNotNull);
    expect(creation.constructorName.type.name.staticElement, isClassElement);

    expect(creation.constructorName.name, isNull);
  }

  test_visitMethodInvocations_importPrefix_function() async {
    String code = '''
import 'dart:math' as ma;
main() {
  ma.max(1, 2); // marker
}
''';
    CompilationUnit unit = await resolveSource(code);
    var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');

    ExpressionStatement statement = statements[0];
    MethodInvocation invocation = statement.expression;

    SimpleIdentifier prefix = invocation.target;
    expect(prefix.staticElement, isPrefixElement);

    expect(invocation.methodName.name, 'max');
  }

  /**
   * Test that the call to a static method will not be re-written as a
   * InstanceCreationExpression AST node.
   */
  test_visitMethodInvocations_not_implicit_constructor() async {
    String code = '''
class A {
  static staticMethod() {}
}
main() {
  A.staticMethod(); // marker
}
    ''';
    CompilationUnit unit = await resolveSource(code);
    AstNode node = findMarkedIdentifier(code, unit, "(); // marker");
    assert(node.parent is MethodInvocation);
  }
}
