// Copyright (c) 2018, 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 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'driver_resolution.dart';

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

@reflectiveTest
class MethodInvocationResolutionTest extends DriverResolutionTest {
  test_error_abstractSuperMemberReference() async {
    addTestFile(r'''
abstract class A {
  void foo(int _);
}
abstract class B extends A {
  void bar() {
    super.foo(0);
  }

  void foo(int _) {} // does not matter
}
''');
    await resolveTestFile();
    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.method('foo', of: 'A'),
      '(int) → void',
    );
    assertSuperExpression(invocation.target);
  }

  test_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
    addTestFile('''
class A {
  int foo();
  noSuchMethod(im) => 42;
}

class B extends Object with A {
  foo() => super.foo(); // ref
  noSuchMethod(im) => 87;
}
''');
    await resolveTestFile();
    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);

    var invocation = findNode.methodInvocation('foo(); // ref');
    assertMethodInvocation(
      invocation,
      findElement.method('foo', of: 'A'),
      '() → int',
    );
    assertSuperExpression(invocation.target);
  }

  test_error_abstractSuperMemberReference_OK_mixinHasConcrete() async {
    addTestFile('''
class A {}

class M {
  void foo(int _) {}
}

class B = A with M;

class C extends B {
  void bar() {
    super.foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.method('foo', of: 'M'),
      '(int) → void',
    );
    assertSuperExpression(invocation.target);
  }

  test_error_abstractSuperMemberReference_OK_superHasNoSuchMethod() async {
    addTestFile(r'''
class A {
  int foo();
  noSuchMethod(im) => 42;
}

class B extends A {
  int foo() => super.foo(); // ref
  noSuchMethod(im) => 87;
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('super.foo(); // ref');
    assertMethodInvocation(
      invocation,
      findElement.method('foo', of: 'A'),
      '() → int',
    );
    assertSuperExpression(invocation.target);
  }

  test_error_abstractSuperMemberReference_OK_superSuperHasConcrete() async {
    addTestFile('''
abstract class A {
  void foo(int _) {}
}

abstract class B extends A {
  void foo(int _);
}

class C extends B {
  void bar() {
    super.foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.method('foo', of: 'A'),
      '(int) → void',
    );
    assertSuperExpression(invocation.target);
  }

  test_error_ambiguousImport_topFunction() async {
    newFile('/test/lib/a.dart', content: r'''
void foo(int _) {}
''');
    newFile('/test/lib/b.dart', content: r'''
void foo(int _) {}
''');

    addTestFile(r'''
import 'a.dart';
import 'b.dart';

main() {
  foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.AMBIGUOUS_IMPORT,
    ]);

    var invocation = findNode.methodInvocation('foo(0)');
    assertInvokeType(invocation, '(int) → void');
    assertType(invocation, 'void');
  }

  test_error_ambiguousImport_topFunction_prefixed() async {
    newFile('/test/lib/a.dart', content: r'''
void foo(int _) {}
''');
    newFile('/test/lib/b.dart', content: r'''
void foo(int _) {}
''');

    addTestFile(r'''
import 'a.dart' as p;
import 'b.dart' as p;

main() {
  p.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.AMBIGUOUS_IMPORT,
    ]);

    var invocation = findNode.methodInvocation('foo(0)');
    assertInvokeType(invocation, '(int) → void');
    assertType(invocation, 'void');
  }

  test_error_instanceAccessToStaticMember_method() async {
    addTestFile(r'''
class A {
  static void foo(int _) {}
}

main(A a) {
  a.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
    ]);
    _assertInvalidInvocation(
      'a.foo(0)',
      findElement.method('foo'),
      expectedNameType: '(int) → void',
    );
  }

  test_error_invocationOfNonFunction_interface_hasCall_field() async {
    addTestFile(r'''
class C {
  void Function() call;
}

main(C c) {
  c();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
    ]);
    _assertInvalidInvocation(
      'c()',
      findElement.parameter('c'),
    );
  }

  test_error_invocationOfNonFunction_localVariable() async {
    addTestFile(r'''
main() {
  Object foo;
  foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
    ]);
    _assertInvalidInvocation(
      'foo()',
      findElement.localVar('foo'),
      expectedNameType: 'Object',
    );
  }

  test_error_invocationOfNonFunction_OK_dynamic_localVariable() async {
    addTestFile(r'''
main() {
  var foo;
  foo();
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertInvalidInvocation('foo();', findElement.localVar('foo'));
  }

  test_error_invocationOfNonFunction_OK_dynamicGetter_instance() async {
    addTestFile(r'''
class C {
  var foo;
}

main(C c) {
  c.foo();
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertInvalidInvocation('c.foo();', findElement.getter('foo'));
  }

  test_error_invocationOfNonFunction_OK_dynamicGetter_superClass() async {
    addTestFile(r'''
class A {
  var foo;
}

class B extends A {
  main() {
    foo();
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertInvalidInvocation('foo();', findElement.getter('foo'));
  }

  test_error_invocationOfNonFunction_OK_dynamicGetter_thisClass() async {
    addTestFile(r'''
class C {
  var foo;

  main() {
    foo();
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertInvalidInvocation('foo();', findElement.getter('foo'));
  }

  test_error_invocationOfNonFunction_OK_Function() async {
    addTestFile(r'''
f(Function foo) {
  foo(1, 2);
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertInvalidInvocation('foo(1, 2);', findElement.parameter('foo'));
  }

  test_error_invocationOfNonFunction_OK_functionTypeTypeParameter() async {
    addTestFile(r'''
typedef MyFunction = double Function(int _);

class C<T extends MyFunction> {
  T foo;
  
  main() {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    assertMethodInvocation(
      findNode.methodInvocation('foo(0)'),
      findElement.getter('foo'),
      '(int) → double',
    );
  }

  test_error_invocationOfNonFunction_static_hasTarget() async {
    addTestFile(r'''
class C {
  static int foo;
}

main() {
  C.foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
    ]);
    _assertInvalidInvocation(
      'foo()',
      findElement.getter('foo'),
    );
  }

  test_error_invocationOfNonFunction_static_noTarget() async {
    addTestFile(r'''
class C {
  static int foo;
  
  main() {
    foo();
  }
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
    ]);
    _assertInvalidInvocation(
      'foo()',
      findElement.getter('foo'),
    );
  }

  test_error_invocationOfNonFunction_super_getter() async {
    addTestFile(r'''
class A {
  int get foo => 0;
}

class B extends A {
  main() {
    super.foo();
  }
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
    ]);
    _assertInvalidInvocation(
      'foo()',
      findElement.getter('foo'),
    );
  }

  test_error_prefixIdentifierNotFollowedByDot() async {
    newFile('/test/lib/a.dart', content: r'''
void foo() {}
''');

    addTestFile(r'''
import 'a.dart' as prefix;

main() {
  prefix?.foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
    ]);

    var import = _importFinder('package:test/a.dart');

    var invocation = findNode.methodInvocation('foo();');
    assertMethodInvocation(
      invocation,
      import.topFunction('foo'),
      '() → void',
    );
    assertImportPrefix(invocation.target, import.prefix);
  }

  test_error_prefixIdentifierNotFollowedByDot_deferred() async {
    addTestFile(r'''
import 'dart:math' deferred as math;

main() {
  math?.loadLibrary();
}
''');
    await resolveTestFile();
    assertTestErrors([
      CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
    ]);

    var import = _importFinder('dart:math');

    var invocation = findNode.methodInvocation('loadLibrary()');
    assertMethodInvocation(
      invocation,
      import.importedLibrary.loadLibraryFunction,
      '() → Future<dynamic>',
    );
    assertImportPrefix(invocation.target, import.prefix);
  }

  test_error_prefixIdentifierNotFollowedByDot_invoke() async {
    addTestFile(r'''
import 'dart:math' as foo;

main() {
  foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
    ]);
    _assertInvalidInvocation(
      'foo()',
      findElement.import('dart:math').prefix,
      dynamicNameType: true,
    );
  }

  test_error_undefinedFunction() async {
    addTestFile(r'''
main() {
  foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_FUNCTION,
    ]);
    _assertUnresolvedMethodInvocation('foo(0)');
  }

  test_error_undefinedFunction_hasTarget_importPrefix() async {
    addTestFile(r'''
import 'dart:math' as math;

main() {
  math.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_FUNCTION,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
  }

  test_error_undefinedIdentifier_target() async {
    addTestFile(r'''
main() {
  bar.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.UNDEFINED_IDENTIFIER,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
  }

  test_error_undefinedMethod_hasTarget_class() async {
    addTestFile(r'''
class C {}
main() {
  C.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
  }

  test_error_undefinedMethod_hasTarget_class_arguments() async {
    addTestFile(r'''
class C {}

int x;
main() {
  C.foo(x);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);

    _assertUnresolvedMethodInvocation('foo(x);');
    assertTopGetRef('x)', 'x');
  }

  test_error_undefinedMethod_hasTarget_class_inSuperclass() async {
    addTestFile(r'''
class S {
  static void foo(int _) {}
}

class C extends S {}

main() {
  C.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
  }

  test_error_undefinedMethod_hasTarget_class_typeArguments() async {
    addTestFile(r'''
class C {}

main() {
  C.foo<int>();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);

    _assertUnresolvedMethodInvocation('foo<int>();');
    assertTypeName(findNode.typeName('int>'), intElement, 'int');
  }

  test_error_undefinedMethod_hasTarget_class_typeParameter() async {
    addTestFile(r'''
class C<T> {
  static main() => C.T();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('C.T();');
  }

  test_error_undefinedMethod_hasTarget_instance() async {
    addTestFile(r'''
main() {
  42.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
  }

  test_error_undefinedMethod_hasTarget_localVariable_function() async {
    addTestFile(r'''
main() {
  var v = () {};
  v.foo(0);
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
  }

  test_error_undefinedMethod_noTarget() async {
    addTestFile(r'''
class C {
  main() {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
  }

  test_error_undefinedMethod_object_call() async {
    addTestFile(r'''
main(Object o) {
  o.call();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
  }

  test_error_undefinedMethod_OK_null() async {
    addTestFile(r'''
main() {
  null.foo();
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertUnresolvedMethodInvocation('foo();');
  }

  test_error_undefinedMethod_private() async {
    newFile('/test/lib/a.dart', content: r'''
class A {
  void _foo(int _) {}
}
''');
    addTestFile(r'''
import 'a.dart';

class B extends A {
  main() {
    _foo(0);
  }
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('_foo(0);');
  }

  test_error_undefinedMethod_typeLiteral_cascadeTarget() async {
    addTestFile(r'''
class C {
  static void foo() {}
}

main() {
  C..foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
  }

  test_error_undefinedMethod_typeLiteral_conditional() async {
    // When applied to a type literal, the conditional access operator '?.'
    // cannot be used to access instance methods of Type.
    addTestFile(r'''
class A {}
main() {
  A?.toString();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_METHOD,
    ]);
  }

  test_error_undefinedSuperMethod() async {
    addTestFile(r'''
class A {}

class B extends A {
  void foo(int _) {
    super.foo(0);
  }
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
    ]);
    _assertUnresolvedMethodInvocation('foo(0);');
    assertSuperExpression(findNode.super_('super.foo'));
  }

  test_error_unqualifiedReferenceToNonLocalStaticMember_method() async {
    addTestFile(r'''
class A {
  static void foo() {}
}

class B extends A {
  main() {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
    ]);

    _assertInvalidInvocation(
      'foo(0)',
      findElement.method('foo'),
      expectedNameType: '(int) → void',
    );
  }

  /// The primary purpose of this test is to ensure that we are only getting a
  /// single error generated when the only problem is that an imported file
  /// does not exist.
  test_error_uriDoesNotExist_prefixed() async {
    addTestFile(r'''
import 'missing.dart' as p;

main() {
  p.foo(1);
  p.bar(2);
}
''');
    await resolveTestFile();
    assertTestErrors([
      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
    ]);
    _assertUnresolvedMethodInvocation('foo(1);');
    _assertUnresolvedMethodInvocation('bar(2);');
  }

  /// The primary purpose of this test is to ensure that we are only getting a
  /// single error generated when the only problem is that an imported file
  /// does not exist.
  test_error_uriDoesNotExist_show() async {
    addTestFile(r'''
import 'missing.dart' show foo, bar;

main() {
  foo(1);
  bar(2);
}
''');
    await resolveTestFile();
    assertTestErrors([
      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
    ]);
    _assertUnresolvedMethodInvocation('foo(1);');
    _assertUnresolvedMethodInvocation('bar(2);');
  }

  test_error_useOfVoidResult_name_getter() async {
    addTestFile(r'''
class C<T>{
  T foo;
}

main(C<void> c) {
  c.foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.USE_OF_VOID_RESULT,
    ]);
    _assertInvalidInvocation(
      'c.foo()',
      findElement.getter('foo'),
      expectedNameType: 'void',
    );
  }

  test_error_useOfVoidResult_name_localVariable() async {
    addTestFile(r'''
main() {
  void foo;
  foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.USE_OF_VOID_RESULT,
    ]);
    _assertInvalidInvocation(
      'foo()',
      findElement.localVar('foo'),
      expectedNameType: 'void',
    );
  }

  test_error_useOfVoidResult_name_topFunction() async {
    addTestFile(r'''
void foo() {}

main() {
  foo()();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.USE_OF_VOID_RESULT,
    ]);
    assertMethodInvocation(
      findNode.methodInvocation('foo()()'),
      findElement.topFunction('foo'),
      '() → void',
    );
  }

  test_error_useOfVoidResult_name_topVariable() async {
    addTestFile(r'''
void foo;

main() {
  foo();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.USE_OF_VOID_RESULT,
    ]);
    _assertInvalidInvocation(
      'foo()',
      findElement.topGet('foo'),
      expectedNameType: 'void',
    );
  }

  test_error_useOfVoidResult_receiver() async {
    addTestFile(r'''
main() {
  void foo;
  foo.toString();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.USE_OF_VOID_RESULT,
    ]);
    // TODO(scheglov) Resolve fully, or don't resolve at all.
    assertMethodInvocation(
      findNode.methodInvocation('toString()'),
      null,
      '() → String',
    );
  }

  test_error_useOfVoidResult_receiver_cascade() async {
    addTestFile(r'''
main() {
  void foo;
  foo..toString();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.USE_OF_VOID_RESULT,
    ]);
    // TODO(scheglov) Resolve fully, or don't resolve at all.
    assertMethodInvocation(
      findNode.methodInvocation('toString()'),
      null,
      '() → String',
    );
  }

  test_error_useOfVoidResult_receiver_withNull() async {
    addTestFile(r'''
main() {
  void foo;
  foo?.toString();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticWarningCode.USE_OF_VOID_RESULT,
    ]);
    // TODO(scheglov) Resolve fully, or don't resolve at all.
    assertMethodInvocation(
      findNode.methodInvocation('toString()'),
      null,
      '() → String',
    );
  }

  test_error_wrongNumberOfTypeArgumentsMethod_01() async {
    addTestFile(r'''
void foo() {}

main() {
  foo<int>();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
    ]);
    assertMethodInvocation(
      findNode.methodInvocation('foo<int>()'),
      findElement.topFunction('foo'),
      '() → void',
    );
    assertTypeName(findNode.typeName('int>'), intElement, 'int');
  }

  test_error_wrongNumberOfTypeArgumentsMethod_21() async {
    addTestFile(r'''
Map<T, U> foo<T extends num, U>() => null;

main() {
  foo<int>();
}
''');
    await resolveTestFile();
    assertTestErrors([
      StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
    ]);
    assertMethodInvocation(
      findNode.methodInvocation('foo<int>()'),
      findElement.topFunction('foo'),
      '() → Map<num, dynamic>',
    );
    assertTypeName(findNode.typeName('int>'), intElement, 'int');
  }

  test_hasReceiver_class_staticGetter() async {
    addTestFile(r'''
class C {
  static double Function(int) get foo => null;
}

main() {
  C.foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0);');
    assertMethodInvocation(
      invocation,
      findElement.getter('foo'),
      '(int) → double',
    );
    assertClassRef(invocation.target, findElement.class_('C'));
  }

  test_hasReceiver_class_staticMethod() async {
    addTestFile(r'''
class C {
  static void foo(int _) {}
}

main() {
  C.foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0);');
    assertMethodInvocation(
      invocation,
      findElement.method('foo'),
      '(int) → void',
    );
    assertClassRef(invocation.target, findElement.class_('C'));
  }

  test_hasReceiver_deferredImportPrefix_loadLibrary() async {
    addTestFile(r'''
import 'dart:math' deferred as math;

main() {
  math.loadLibrary();
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var import = _importFinder('dart:math');

    var invocation = findNode.methodInvocation('loadLibrary()');
    assertMethodInvocation(
      invocation,
      import.importedLibrary.loadLibraryFunction,
      '() → Future<dynamic>',
    );
    assertImportPrefix(invocation.target, import.prefix);
  }

  test_hasReceiver_functionTyped_call() async {
    addTestFile(r'''
void foo(int _) {}

main() {
  foo.call(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('call(0)');
    assertMethodInvocation(
      invocation,
      null,
      '(int) → void',
    );
    assertElement(invocation.target, findElement.topFunction('foo'));
    assertType(invocation.target, '(int) → void');
  }

  test_hasReceiver_importPrefix_topFunction() async {
    newFile('/test/lib/a.dart', content: r'''
T foo<T extends num>(T a, T b) => a;
''');

    addTestFile(r'''
import 'a.dart' as prefix;

main() {
  prefix.foo(1, 2);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var import = _importFinder('package:test/a.dart');

    var invocation = findNode.methodInvocation('foo(1, 2)');
    assertMethodInvocation(
      invocation,
      import.topFunction('foo'),
      '(int, int) → int',
    );
    assertImportPrefix(invocation.target, import.prefix);
  }

  test_hasReceiver_importPrefix_topGetter() async {
    newFile('/test/lib/a.dart', content: r'''
T Function<T>(T a, T b) get foo => null;
''');

    addTestFile(r'''
import 'a.dart' as prefix;

main() {
  prefix.foo(1, 2);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var import = _importFinder('package:test/a.dart');

    var invocation = findNode.methodInvocation('foo(1, 2)');
    assertMethodInvocation(
      invocation,
      import.topGetter('foo'),
      '(int, int) → int',
    );
    assertImportPrefix(invocation.target, import.prefix);
  }

  test_hasReceiver_instance_Function_call_localVariable() async {
    addTestFile(r'''
void main() {
  Function foo;

  foo.call(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertInvalidInvocation('call(0)', null);
  }

  test_hasReceiver_instance_Function_call_topVariable() async {
    addTestFile(r'''
Function foo;

void main() {
  foo.call(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertInvalidInvocation('call(0)', null);
  }

  test_hasReceiver_instance_getter() async {
    addTestFile(r'''
class C {
  double Function(int) get foo => null;
}

main(C c) {
  c.foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0);');
    assertMethodInvocation(
      invocation,
      findElement.getter('foo'),
      '(int) → double',
    );
  }

  test_hasReceiver_instance_method() async {
    addTestFile(r'''
class C {
  void foo(int _) {}
}

main(C c) {
  c.foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0);');
    assertMethodInvocation(
      invocation,
      findElement.method('foo'),
      '(int) → void',
    );
  }

  test_hasReceiver_instance_method_issue30552() async {
    addTestFile(r'''
abstract class I1 {
  void foo(int i);
}

abstract class I2 {
  void foo(Object o);
}

abstract class C implements I1, I2 {}

class D extends C {
  void foo(Object o) {}
}

void main(C c) {
  c.foo('hi');
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation("foo('hi')");
    assertMethodInvocation(
      invocation,
      findElement.method('foo', of: 'I2'),
      '(Object) → void',
    );
  }

  test_hasReceiver_instance_typeParameter() async {
    addTestFile(r'''
class A {
  void foo(int _) {}
}

class C<T extends A> {
  T a;
  
  main() {
    a.foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0);');
    assertMethodInvocation(
      invocation,
      findElement.method('foo'),
      '(int) → void',
    );
  }

  test_hasReceiver_prefixed_class_staticGetter() async {
    newFile('/test/lib/a.dart', content: r'''
class C {
  static double Function(int) get foo => null;
}
''');

    addTestFile(r'''
import 'a.dart' as prefix;

main() {
  prefix.C.foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var import = _importFinder('package:test/a.dart');

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      import.class_('C').getGetter('foo'),
      '(int) → double',
    );

    PrefixedIdentifier target = invocation.target;
    assertImportPrefix(target.prefix, import.prefix);
    assertClassRef(target.identifier, import.class_('C'));
  }

  test_hasReceiver_prefixed_class_staticMethod() async {
    newFile('/test/lib/a.dart', content: r'''
class C {
  static void foo(int _) => null;
}
''');

    addTestFile(r'''
import 'a.dart' as prefix;

main() {
  prefix.C.foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var import = _importFinder('package:test/a.dart');

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      import.class_('C').getMethod('foo'),
      '(int) → void',
    );

    PrefixedIdentifier target = invocation.target;
    assertImportPrefix(target.prefix, import.prefix);
    assertClassRef(target.identifier, import.class_('C'));
  }

  test_hasReceiver_super_getter() async {
    addTestFile(r'''
class A {
  double Function(int) get foo => null;
}

class B extends A {
  void bar() {
    super.foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0);');
    assertMethodInvocation(
      invocation,
      findElement.getter('foo', of: 'A'),
      '(int) → double',
    );
    assertSuperExpression(invocation.target);
  }

  test_hasReceiver_super_method() async {
    addTestFile(r'''
class A {
  void foo(int _) {}
}

class B extends A {
  void foo(int _) {
    super.foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0);');
    assertMethodInvocation(
      invocation,
      findElement.method('foo', of: 'A'),
      '(int) → void',
    );
    assertSuperExpression(invocation.target);
  }

  test_namedArgument() async {
    addTestFile(r'''
void foo({int a, bool b}) {}

main() {
  foo(b: false, a: 0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(b:');
    assertMethodInvocation(
      invocation,
      findElement.topFunction('foo'),
      '({a: int, b: bool}) → void',
    );
    assertNamedParameterRef('b: false', 'b');
    assertNamedParameterRef('a: 0', 'a');
  }

  test_noReceiver_getter_superClass() async {
    addTestFile(r'''
class A {
  double Function(int) get foo => null;
}

class B extends A {
  void bar() {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.getter('foo'),
      '(int) → double',
    );
  }

  test_noReceiver_getter_thisClass() async {
    addTestFile(r'''
class C {
  double Function(int) get foo => null;

  void bar() {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.getter('foo'),
      '(int) → double',
    );
  }

  test_noReceiver_importPrefix() async {
    addTestFile(r'''
import 'dart:math' as math;

main() {
  math();
}
''');
    await resolveTestFile();
    assertTestErrors([
      CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
    ]);
    assertElement(findNode.simple('math()'), findElement.prefix('math'));
  }

  test_noReceiver_localFunction() async {
    addTestFile(r'''
main() {
  void foo(int _) {}

  foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.localFunction('foo'),
      '(int) → void',
    );
  }

  test_noReceiver_localVariable() async {
    addTestFile(r'''
main() {
  void Function(int) foo;

  foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.localVar('foo'),
      '(int) → void',
    );
  }

  test_noReceiver_localVariable_call() async {
    addTestFile(r'''
class C {
  void call(int _) {}
}

main(C c) {
  c(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('c(0);');
    assertMethodInvocation(
      invocation,
      findElement.parameter('c'),
      '(int) → void',
    );
  }

  test_noReceiver_localVariable_promoted() async {
    addTestFile(r'''
main() {
  var foo;
  if (foo is void Function(int)) {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.localVar('foo'),
      '(int) → void',
    );
  }

  test_noReceiver_method_superClass() async {
    addTestFile(r'''
class A {
  void foo(int _) {}
}

class B extends A {
  void bar() {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.method('foo'),
      '(int) → void',
    );
  }

  test_noReceiver_method_thisClass() async {
    addTestFile(r'''
class C {
  void foo(int _) {}

  void bar() {
    foo(0);
  }
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.method('foo'),
      '(int) → void',
    );
  }

  test_noReceiver_topFunction() async {
    addTestFile(r'''
void foo(int _) {}

main() {
  foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.topFunction('foo'),
      '(int) → void',
    );
  }

  test_noReceiver_topGetter() async {
    addTestFile(r'''
double Function(int) get foo => null;

main() {
  foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.topGet('foo'),
      '(int) → double',
    );
  }

  test_noReceiver_topVariable() async {
    addTestFile(r'''
void Function(int) foo;

main() {
  foo(0);
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('foo(0)');
    assertMethodInvocation(
      invocation,
      findElement.topGet('foo'),
      '(int) → void',
    );
  }

  test_objectMethodOnDynamic() async {
    addTestFile(r'''
main() {
  var v;
  v.toString(42);
}
''');
    await resolveTestFile();
    assertNoTestErrors();
    _assertUnresolvedMethodInvocation('toString(42);');
  }

  test_objectMethodOnFunction() async {
    addTestFile(r'''
void f() {}

main() {
  f.toString();
}
''');
    await resolveTestFile();
    assertNoTestErrors();

    var invocation = findNode.methodInvocation('toString();');
    assertMethodInvocation(
      invocation,
      typeProvider.objectType.getMethod('toString'),
      '() → String',
    );
  }

  void _assertInvalidInvocation(String search, Element expectedElement,
      {String expectedNameType, bool dynamicNameType: false}) {
    var invocation = findNode.methodInvocation(search);
    if (dynamicNameType) {
      assertTypeDynamic(invocation.methodName);
    }
    // TODO(scheglov) I think `invokeType` should be `null`.
    assertMethodInvocation(
      invocation,
      expectedElement,
      'dynamic',
      expectedNameType: expectedNameType,
      expectedType: 'dynamic',
    );
  }

  void _assertUnresolvedMethodInvocation(String search) {
    // TODO(scheglov) clean up
    _assertInvalidInvocation(search, null);
//    var invocation = findNode.methodInvocation(search);
//    assertTypeDynamic(invocation.methodName);
//    // TODO(scheglov) I think `invokeType` should be `null`.
//    assertMethodInvocation(
//      invocation,
//      null,
//      'dynamic',
//      expectedType: 'dynamic',
//    );
  }

  _ImportElementFinder _importFinder(String targetUri) {
    var import = findElement.import(targetUri);
    return _ImportElementFinder(import);
  }
}

class _ImportElementFinder {
  final ImportElement import;

  _ImportElementFinder(this.import);

  CompilationUnitElement get definingUnit {
    return importedLibrary.definingCompilationUnit;
  }

  LibraryElement get importedLibrary => import.importedLibrary;

  PrefixElement get prefix => import.prefix;

  ClassElement class_(String name) {
    for (var class_ in definingUnit.types) {
      if (class_.name == name) {
        return class_;
      }
    }
    fail('Not found class: $name');
  }

  FunctionElement topFunction(String name) {
    for (var function in definingUnit.functions) {
      if (function.name == name) {
        return function;
      }
    }
    fail('Not found top-level function: $name');
  }

  PropertyAccessorElement topGetter(String name) {
    for (var accessor in definingUnit.accessors) {
      if (accessor.name == name && accessor.isGetter) {
        return accessor;
      }
    }
    fail('Not found top-level getter: $name');
  }
}
