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

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../src/dart/resolution/context_collection_resolution.dart';

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

@reflectiveTest
class NonErrorResolverTest extends PubPackageResolutionTest {
  test_ambiguousExport() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library lib1;
class M {}
''');
    newFile("$testPackageLibPath/lib2.dart", r'''
library lib2;
class N {}
''');
    await assertNoErrorsInCode(r'''
library L;
export 'lib1.dart';
export 'lib2.dart';
''');
  }

  test_ambiguousExport_combinators_hide() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library L1;
class A {}
class B {}
''');
    newFile("$testPackageLibPath/lib2.dart", r'''
library L2;
class B {}
class C {}
''');
    await assertNoErrorsInCode(r'''
library L;
export 'lib1.dart';
export 'lib2.dart' hide B;
''');
  }

  test_ambiguousExport_combinators_show() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library L1;
class A {}
class B {}
''');
    newFile("$testPackageLibPath/lib2.dart", r'''
library L2;
class B {}
class C {}
''');
    await assertNoErrorsInCode(r'''
library L;
export 'lib1.dart';
export 'lib2.dart' show C;
''');
  }

  test_ambiguousExport_sameDeclaration() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library lib;
class N {}
''');
    await assertErrorsInCode(
      r'''
library L;
export 'lib.dart';
export 'lib.dart';
''',
      [error(diag.duplicateExport, 37, 10)],
    );
  }

  test_ambiguousImport_dart_implicitHide() async {
    newFile('$testPackageLibPath/lib.dart', r'''
class Future {
  static const zero = 0;
}
''');
    await assertNoErrorsInCode(r'''
import 'lib.dart';
main() {
  print(Future.zero);
}
''');
  }

  test_ambiguousImport_hideCombinator() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library lib1;
class N {}
class N1 {}
''');
    newFile("$testPackageLibPath/lib2.dart", r'''
library lib2;
class N {}
class N2 {}
''');
    newFile("$testPackageLibPath/lib3.dart", r'''
library lib3;
class N {}
class N3 {}
''');
    await assertNoErrorsInCode(r'''
import 'lib1.dart';
import 'lib2.dart';
import 'lib3.dart' hide N;
main() {
  new N1();
  new N2();
  new N3();
}
''');
  }

  test_ambiguousImport_showCombinator() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library lib1;
class N {}
class N1 {}
''');
    newFile("$testPackageLibPath/lib2.dart", r'''
library lib2;
class N {}
class N2 {}
''');
    await assertErrorsInCode(
      r'''
import 'lib1.dart';
import 'lib2.dart' show N, N2;
main() {
  new N1();
  new N2();
}
''',
      [error(diag.unusedShownName, 44, 1)],
    );
  }

  test_annotated_partOfDeclaration() async {
    newFile('$testPackageLibPath/part.dart', '''
@deprecated
part of 'test.dart';
''');

    await assertNoErrorsInCode('''
part "part.dart";
''');
  }

  test_argumentTypeNotAssignable_classWithCall_Function() async {
    await assertNoErrorsInCode(r'''
caller(Function callee) {
  callee();
}

class CallMeBack {
  call() => 0;
}

main() {
  caller(new CallMeBack());
}
''');
  }

  test_argumentTypeNotAssignable_fieldFormalParameterElement_member() async {
    await assertNoErrorsInCode(r'''
class ObjectSink<T> {
  void sink(T object) {
    new TimestampedObject<T>(object);
  }
}
class TimestampedObject<E> {
  E object2;
  TimestampedObject(this.object2);
}
''');
  }

  test_argumentTypeNotAssignable_invocation_functionParameter_generic() async {
    await assertNoErrorsInCode(r'''
class A<K> {
  m(f(K k), K v) {
    f(v);
  }
}
''');
  }

  test_argumentTypeNotAssignable_invocation_typedef_generic() async {
    await assertNoErrorsInCode(r'''
typedef A<T>(T p);
f(A<int> a) {
  a(1);
}
''');
  }

  test_argumentTypeNotAssignable_Object_Function() async {
    await assertNoErrorsInCode(r'''
main() {
  process(() {});
}
process(Object x) {}''');
  }

  test_argumentTypeNotAssignable_optionalNew() async {
    await assertNoErrorsInCode(r'''
class Widget { }

class MaterialPageRoute {
  final Widget Function() builder;
  const MaterialPageRoute({this.builder = f});
}

Widget f() => Widget();

void main() {
  MaterialPageRoute(builder: () {
      return Widget();
    },
  );
}
''');
  }

  test_argumentTypeNotAssignable_typedef_local() async {
    await assertNoErrorsInCode(r'''
typedef A(int p1, String p2);
A getA() => (int p1, String p2) {};
f() {
  A a = getA();
  a(1, '2');
}
''');
  }

  test_argumentTypeNotAssignable_typedef_parameter() async {
    await assertNoErrorsInCode(r'''
typedef A(int p1, String p2);
f(A a) {
  a(1, '2');
}
''');
  }

  test_assert_with_message_await() async {
    await assertNoErrorsInCode('''
f() async {
  assert(false, await g());
}
Future<String> g() => Future.value('');
''');
  }

  test_assert_with_message_dynamic() async {
    await assertNoErrorsInCode('''
f() {
  assert(false, g());
}
g() => null;
''');
  }

  test_assert_with_message_non_string() async {
    await assertNoErrorsInCode('''
f() {
  assert(false, 3);
}
''');
  }

  test_assert_with_message_null() async {
    await assertNoErrorsInCode('''
f() {
  assert(false, null);
}
''');
  }

  test_assert_with_message_string() async {
    await assertNoErrorsInCode('''
f() {
  assert(false, 'message');
}
''');
  }

  test_assert_with_message_suppresses_unused_var_hint() async {
    await assertNoErrorsInCode('''
f() {
  String message = 'msg';
  assert(true, message);
}
''');
  }

  test_assignability_function_expr_rettype_from_typedef_cls() async {
    // In the code below, the type of (() => f()) has a return type which is
    // a class, and that class is inferred from the return type of the typedef
    // F.
    await assertNoErrorsInCode('''
class C {}
typedef C F();
F f = () => C();
main() {
  F f2 = (() => f());
  f2;
}
''');
  }

  test_assignability_function_expr_rettype_from_typedef_typedef() async {
    // In the code below, the type of (() => f()) has a return type which is
    // a typedef, and that typedef is inferred from the return type of the
    // typedef F.
    await assertNoErrorsInCode('''
typedef G F();
typedef G();
F f = () => () => {};
main() {
  F f2 = (() => f());
  f2;
}
''');
  }

  test_assignmentToFinal_prefixNegate() async {
    await assertErrorsInCode(
      r'''
f() {
  final x = 0;
  -x;
}
''',
      [error(diag.unusedLocalVariable, 14, 1)],
    );
  }

  test_assignmentToFinalNoSetter_prefixedIdentifier() async {
    await assertNoErrorsInCode(r'''
class A {
  int get x => 0;
  set x(v) {}
}
main() {
  A a = new A();
  a.x = 0;
}
''');
  }

  test_assignmentToFinalNoSetter_propertyAccess() async {
    await assertNoErrorsInCode(r'''
class A {
  int get x => 0;
  set x(v) {}
}
class B {
  static A a = A();
}
main() {
  B.a.x = 0;
}
''');
  }

  test_assignmentToFinals_importWithPrefix() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library lib1;
bool x = false;''');
    await assertNoErrorsInCode(r'''
library lib;
import 'lib1.dart' as foo;
main() {
  foo.x = true;
}
''');
  }

  test_async_callback_in_with_unknown_return_type_context() async {
    await assertNoErrorsInCode('''
abstract class C {
  R run<R>(R Function() action);
}
f(C c) {
  c.run(() async {});
}
''');
  }

  test_async_dynamic_with_return() async {
    await assertNoErrorsInCode('''
dynamic f() async {
  return;
}
''');
  }

  test_async_dynamic_with_return_value() async {
    await assertNoErrorsInCode('''
dynamic f() async {
  return 5;
}
''');
  }

  test_async_dynamic_without_return() async {
    await assertNoErrorsInCode('''
dynamic f() async {}
''');
  }

  test_async_expression_function_type() async {
    await assertErrorsInCode(
      '''
typedef Future<int> F(int i);
main() {
  F f = (int i) async => i;
}
''',
      [error(diag.unusedLocalVariable, 43, 1)],
    );
  }

  test_async_flattened() async {
    await assertNoErrorsInCode('''
typedef Future<int> CreatesFutureInt();
main() {
  CreatesFutureInt createFutureInt = () async => f();
  Future<int> futureInt = createFutureInt();
  futureInt.then((int i) => print(i));
}
Future<int> f() => Future.value(0);
''');
  }

  test_async_future_dynamic_with_return() async {
    await assertNoErrorsInCode('''
Future<dynamic> f() async {
  return;
}
''');
  }

  test_async_future_dynamic_with_return_value() async {
    await assertNoErrorsInCode('''
Future<dynamic> f() async {
  return 5;
}
''');
  }

  test_async_future_dynamic_without_return() async {
    await assertNoErrorsInCode('''
Future<dynamic> f() async {}
''');
  }

  test_async_future_int_with_return_future_int() async {
    await assertNoErrorsInCode('''
Future<int> f() async {
  return new Future<int>.value(5);
}
''');
  }

  test_async_future_int_with_return_value() async {
    await assertNoErrorsInCode('''
Future<int> f() async {
  return 5;
}
''');
  }

  test_async_future_null_with_return() async {
    await assertNoErrorsInCode('''
Future<Null> f() async {
  return;
}
''');
  }

  test_async_future_null_without_return() async {
    await assertNoErrorsInCode('''
Future<Null> f() async {}
''');
  }

  test_async_future_object_with_return_value() async {
    await assertNoErrorsInCode('''
Future<Object> f() async {
  return 5;
}
''');
  }

  test_async_future_with_return() async {
    await assertNoErrorsInCode('''
Future f() async {
  return;
}
''');
  }

  test_async_future_with_return_value() async {
    await assertNoErrorsInCode('''
Future f() async {
  return 5;
}
''');
  }

  test_async_future_without_return() async {
    await assertNoErrorsInCode('''
Future f() async {}
''');
  }

  test_async_with_return() async {
    await assertNoErrorsInCode('''
f() async {
  return;
}
''');
  }

  test_async_with_return_value() async {
    await assertNoErrorsInCode('''
f() async {
  return 5;
}
''');
  }

  test_async_without_return() async {
    await assertNoErrorsInCode('''
f() async {}
''');
  }

  test_asyncForInWrongContext_async() async {
    await assertErrorsInCode(
      r'''
f(list) async {
  await for (var e in list) {
  }
}
''',
      [error(diag.unusedLocalVariable, 33, 1)],
    );
  }

  test_asyncForInWrongContext_asyncStar() async {
    await assertErrorsInCode(
      r'''
f(list) async* {
  await for (var e in list) {
  }
}
''',
      [error(diag.unusedLocalVariable, 34, 1)],
    );
  }

  test_await_flattened() async {
    await assertNoErrorsInCode('''
Future<Future<int>>? ffi() => null;
f() async {
  Future<int>? b = await ffi();
  b;
}
''');
  }

  test_await_simple() async {
    await assertNoErrorsInCode('''
Future<int> fi() => Future.value(0);
f() async {
  int a = await fi();
  a;
}
''');
  }

  test_awaitInWrongContext_async() async {
    await assertNoErrorsInCode(r'''
f(x, y) async {
  return await x + await y;
}
''');
  }

  test_awaitInWrongContext_asyncStar() async {
    await assertNoErrorsInCode(r'''
f(x, y) async* {
  yield await x + await y;
}
''');
  }

  test_breakWithoutLabelInSwitch() async {
    await assertNoErrorsInCode(r'''
class A {
  void m(int i) {
    switch (i) {
      case 0:
        break;
    }
  }
}
''');
  }

  test_breakWithoutLabelInSwitch_language219() async {
    await assertNoErrorsInCode(r'''
// @dart = 2.19
class A {
  void m(int i) {
    switch (i) {
      case 0:
        break;
    }
  }
}
''');
  }

  test_bug_24539_getter() async {
    await assertNoErrorsInCode('''
class C<T> {
  List<Foo> get x => [];
}

typedef Foo(param);
''');
  }

  test_bug_24539_setter() async {
    await assertNoErrorsInCode('''
class C<T> {
  void set x(List<Foo> value) {}
}

typedef Foo(param);
''');
  }

  test_builtInIdentifierAsType_dynamic() async {
    await assertErrorsInCode(
      r'''
f() {
  dynamic x;
}
''',
      [error(diag.unusedLocalVariable, 16, 1)],
    );
  }

  test_castFrom() async {
    // This test exercises a corner case of legacy erasure: due to the type
    // substitution in the `newSet` parameter of `Set.castFrom`, we wind up with
    // a synthetic `ParameterMember` that belongs to no library.  We need to
    // make sure this doesn't lead to a crash.
    await assertErrorsInCode(
      '''
class C {}

void testNewSet(Set<C> setEls) {
  var customNewSet;
  Set.castFrom<C, Object>(setEls,
      newSet: <T>() => customNewSet = new Set<T>());
}
''',
      [error(diag.unusedLocalVariable, 51, 12)],
    );
  }

  test_class_type_alias_documentationComment() async {
    await assertNoErrorsInCode('''
/**
 * Documentation
 */
class C = D with E;

class D {}
mixin E {}
''');
    CompilationUnit unit = result.unit;
    ClassElement classC = unit.declaredFragment!.element.getClass('C')!;
    expect(classC.documentationComment, isNotNull);
  }

  test_closure_in_type_inferred_variable_in_other_lib() async {
    newFile('$testPackageLibPath/other.dart', '''
var y = (Object x) => x is int && x.isEven;
''');
    await assertNoErrorsInCode('''
import 'other.dart';
var x = y;
''');
  }

  test_concreteClassWithAbstractMember() async {
    await assertNoErrorsInCode(r'''
abstract class A {
  m();
}
''');
  }

  test_concreteClassWithAbstractMember_inherited() async {
    await assertNoErrorsInCode(r'''
class A {
  m() {}
}
class B extends A {
  m();
}
''');
  }

  test_conflictingConstructorNameAndMember_setter() async {
    await assertNoErrorsInCode(r'''
class A {
A.x() {}
set x(_) {}
}
''');
  }

  test_const_constructor_with_named_generic_parameter() async {
    await assertNoErrorsInCode('''
class C<T> {
  const C({required T t});
}
const c = const C(t: 1);
''');
  }

  test_const_dynamic() async {
    await assertNoErrorsInCode('''
const Type d = dynamic;
''');
  }

  test_const_imported_defaultParameterValue_withImportPrefix() async {
    newFile('$testPackageLibPath/b.dart', r'''
import 'c.dart' as ccc;
class B {
  const B([p = ccc.value]);
}
''');
    newFile('$testPackageLibPath/c.dart', r'''
const int value = 12345;
''');
    await assertNoErrorsInCode(r'''
import 'b.dart';
const b = const B();
''');
  }

  test_constConstructorWithNonConstSuper_explicit() async {
    await assertNoErrorsInCode(r'''
class A {
  const A();
}
class B extends A {
  const B(): super();
}
''');
  }

  test_constConstructorWithNonConstSuper_redirectingFactory() async {
    await assertNoErrorsInCode(r'''
class A {
  A();
}
class B implements C {
  const B();
}
class C extends A {
  const factory C() = B;
}
''');
  }

  test_constConstructorWithNonConstSuper_unresolved() async {
    await assertErrorsInCode(
      r'''
class A {
  A.a();
}
class B extends A {
  const B(): super();
}
''',
      [error(diag.undefinedConstructorInInitializerDefault, 54, 7)],
    );
  }

  test_constConstructorWithNonFinalField_finalInstanceVar() async {
    await assertNoErrorsInCode(r'''
class A {
  final int x = 0;
  const A();
}
''');
  }

  test_constConstructorWithNonFinalField_static() async {
    await assertNoErrorsInCode(r'''
class A {
  static int x = 0;
  const A();
}
''');
  }

  test_constConstructorWithNonFinalField_syntheticField() async {
    await assertNoErrorsInCode(r'''
class A {
  const A();
  set x(value) {}
  get x {return 0;}
}
''');
  }

  test_constDeferredClass_new() async {
    newFile('$testPackageLibPath/lib.dart', r'''
class A {
  const A.b();
}
''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' deferred as a;
main() {
  new a.A.b();
}
''');
  }

  test_constEval_functionTypeLiteral() async {
    await assertNoErrorsInCode(r'''
typedef F();
const C = F;
''');
  }

  test_constEval_propertyExtraction_fieldStatic_targetType() async {
    newFile("$testPackageLibPath/math.dart", r'''
library math;
const PI = 3.14;
''');
    await assertNoErrorsInCode(r'''
import 'math.dart' as math;
const C = math.PI;
''');
  }

  test_constEval_propertyExtraction_methodStatic_targetType() async {
    await assertNoErrorsInCode(r'''
class A {
  const A();
  static m() {}
}
const C = A.m;
''');
  }

  test_constEval_symbol() async {
    newFile("$testPackageLibPath/math.dart", r'''
library math;
const PI = 3.14;
''');
    await assertNoErrorsInCode(r'''
const C = #foo;
foo() {}
''');
  }

  test_constEvalTypeBoolNumString_equal() async {
    await assertNoErrorsInCode(r'''
class B {
  final v;
  const B.a1(bool p) : v = p == true;
  const B.a2(bool p) : v = p == false;
  const B.a3(bool p) : v = p == 0;
  const B.a4(bool p) : v = p == 0.0;
  const B.a5(bool p) : v = p == '';
  const B.b1(int p) : v = p == true;
  const B.b2(int p) : v = p == false;
  const B.b3(int p) : v = p == 0;
  const B.b4(int p) : v = p == 0.0;
  const B.b5(int p) : v = p == '';
  const B.c1(String p) : v = p == true;
  const B.c2(String p) : v = p == false;
  const B.c3(String p) : v = p == 0;
  const B.c4(String p) : v = p == 0.0;
  const B.c5(String p) : v = p == '';
}
''');
  }

  test_constEvalTypeBoolNumString_equal_null() async {
    await assertNoErrorsInCode(r'''
class B {
  final v;
  const B.n1(num? p) : v = p == null;
  const B.n2(num? p) : v = null == p;
  const B.n3(Object? p) : v = p == null;
  const B.n4(Object? p) : v = null == p;
}
''');
  }

  test_constEvalTypeBoolNumString_notEqual() async {
    await assertNoErrorsInCode(r'''
class B {
  final v;
  const B.a1(bool p) : v = p != true;
  const B.a2(bool p) : v = p != false;
  const B.a3(bool p) : v = p != 0;
  const B.a4(bool p) : v = p != 0.0;
  const B.a5(bool p) : v = p != '';
  const B.b1(int p) : v = p != true;
  const B.b2(int p) : v = p != false;
  const B.b3(int p) : v = p != 0;
  const B.b4(int p) : v = p != 0.0;
  const B.b5(int p) : v = p != '';
  const B.c1(String p) : v = p != true;
  const B.c2(String p) : v = p != false;
  const B.c3(String p) : v = p != 0;
  const B.c4(String p) : v = p != 0.0;
  const B.c5(String p) : v = p != '';
}
''');
  }

  test_constEvalTypeBoolNumString_notEqual_null() async {
    await assertNoErrorsInCode('''
class B {
  final v;
  const B.n1(num? p) : v = p != null;
  const B.n2(num? p) : v = null != p;
  const B.n3(Object? p) : v = p != null;
  const B.n4(Object? p) : v = null != p;
}
''');
  }

  test_constEvAlTypeNum_String() async {
    await assertNoErrorsInCode(r'''
const String A = 'a';
const String B = A + 'b';
''');
  }

  test_constNotInitialized_field() async {
    await assertNoErrorsInCode(r'''
class A {
  static const int x = 0;
}
''');
  }

  test_constNotInitialized_local() async {
    await assertErrorsInCode(
      r'''
main() {
  const int x = 0;
}
''',
      [error(diag.unusedLocalVariable, 21, 1)],
    );
  }

  test_constRedirectSkipsSupertype() async {
    // Since C redirects to C.named, it doesn't implicitly refer to B's
    // unnamed constructor.  Therefore there is no cycle.
    await assertNoErrorsInCode('''
class B {
  final x;
  const B() : x = y;
  const B.named() : x = null;
}
class C extends B {
  const C() : this.named();
  const C.named() : super.named();
}
const y = const C();
''');
  }

  test_constructorDeclaration_scope_signature() async {
    await assertNoErrorsInCode(r'''
const app = 0;
class A {
  A(@app int app) {}
}
''');
  }

  test_constWithNonConstantArgument_constField() async {
    await assertNoErrorsInCode(r'''
class A {
  const A(x);
}
main() {
  const A(double.infinity);
}
''');
  }

  test_constWithNonConstantArgument_literals() async {
    await assertNoErrorsInCode(r'''
class A {
  const A(a, b, c, d);
}
f() { return const A(true, 0, 1.0, '2'); }
''');
  }

  test_constWithTypeParameters_direct() async {
    await assertNoErrorsInCode(r'''
class A<T> {
  static const V = const A<int>();
  const A();
}
''');
  }

  test_constWithUndefinedConstructor() async {
    await assertNoErrorsInCode(r'''
class A {
  const A.name();
}
f() {
  return const A.name();
}
''');
  }

  test_constWithUndefinedConstructorDefault() async {
    await assertNoErrorsInCode(r'''
class A {
  const A();
}
f() {
  return const A();
}
''');
  }

  test_defaultValueInFunctionTypeAlias() async {
    await assertNoErrorsInCode('''
typedef F([x]);
''');
  }

  test_defaultValueInFunctionTypedParameter_named() async {
    await assertNoErrorsInCode('''
f(g({p})) {}
''');
  }

  test_defaultValueInFunctionTypedParameter_optional() async {
    await assertNoErrorsInCode("f(g([p])) {}");
  }

  test_deprecatedMemberUse_hide() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library lib1;
class A {}
@deprecated
class B {}
''');
    await assertNoErrorsInCode(r'''
library lib;
import 'lib1.dart' hide B;
A a = new A();
''');
  }

  test_dynamicIdentifier() async {
    await assertErrorsInCode(
      r'''
main() {
  var v = dynamic;
}
''',
      [error(diag.unusedLocalVariable, 15, 1)],
    );
  }

  test_empty_generator_async() async {
    await assertNoErrorsInCode('''
Stream<int> f() async* {
}
''');
  }

  test_empty_generator_sync() async {
    await assertNoErrorsInCode('''
Iterable<int> f() sync* {
}
''');
  }

  test_extraPositionalArguments_Function() async {
    await assertNoErrorsInCode(r'''
f(Function a) {
  a(1, 2);
}
''');
  }

  test_extraPositionalArguments_function() async {
    await assertNoErrorsInCode(r'''
f(p1, p2) {}
main() {
  f(1, 2);
}
''');
  }

  test_extraPositionalArguments_typedef_local() async {
    await assertNoErrorsInCode(r'''
typedef A(p1, p2);
A getA() => (p1, p2) {};
f() {
  A a = getA();
  a(1, 2);
}
''');
  }

  test_extraPositionalArguments_typedef_parameter() async {
    await assertNoErrorsInCode(r'''
typedef A(p1, p2);
f(A a) {
  a(1, 2);
}
''');
  }

  test_fieldFormalParameter_functionTyped_named() async {
    await assertNoErrorsInCode(r'''
class C {
  final Function field;

  C({String this.field(int value) = f});
}
String f(int value) => '';
''');
  }

  test_fieldFormalParameter_genericFunctionTyped() async {
    await assertNoErrorsInCode(r'''
class C {
  final Object Function(int, double) field;

  C(String Function(num, Object) this.field);
}
''');
  }

  test_fieldFormalParameter_genericFunctionTyped_named() async {
    await assertNoErrorsInCode(r'''
class C {
  final Object Function(int, double) field;

  C({String Function(num, Object) this.field = f});
}
String f(num a, Object b) => '';
''');
  }

  test_fieldInitializedInInitializerAndDeclaration_fieldNotFinal() async {
    await assertNoErrorsInCode(r'''
class A {
  int x = 0;
  A() : x = 1 {}
}
''');
  }

  test_fieldInitializedInInitializerAndDeclaration_finalFieldNotSet() async {
    await assertNoErrorsInCode(r'''
class A {
  final int x;
  A() : x = 1 {}
}
''');
  }

  test_fieldInitializerOutsideConstructor() async {
    await assertNoErrorsInCode(r'''
class A {
  int x;
  A(this.x) {}
}
''');
  }

  test_fieldInitializerOutsideConstructor_defaultParameters() async {
    await assertNoErrorsInCode(r'''
class A {
  int x = 0;
  A([this.x = 1]) {}
}
''');
  }

  test_fieldInitializerRedirectingConstructor_super() async {
    await assertNoErrorsInCode(r'''
class A {
  A() {}
}
class B extends A {
  int x;
  B(this.x) : super();
}
''');
  }

  test_finalInitializedInDeclarationAndConstructor_initializer() async {
    await assertNoErrorsInCode(r'''
class A {
  final x;
  A() : x = 1 {}
}
''');
  }

  test_finalInitializedInDeclarationAndConstructor_initializingFormal() async {
    await assertNoErrorsInCode(r'''
class A {
  final x;
  A(this.x) {}
}
''');
  }

  test_finalNotInitialized_atDeclaration() async {
    await assertNoErrorsInCode(r'''
class A {
  final int x = 0;
  A() {}
}
''');
  }

  test_finalNotInitialized_fieldFormal() async {
    await assertNoErrorsInCode(r'''
class A {
  final int x = 0;
  A() {}
}
''');
  }

  test_finalNotInitialized_functionTypedFieldFormal() async {
    await assertNoErrorsInCode(r'''
class A {
  final Function x;
  A(int this.x(int p)) {}
}
''');
  }

  test_finalNotInitialized_hasNativeClause_hasConstructor() async {
    await assertErrorsInCode(
      r'''
class A native 'something' {
  final int x;
  A() {}
}
''',
      [error(diag.nativeClauseInNonSdkCode, 8, 18)],
    );
  }

  test_finalNotInitialized_hasNativeClause_noConstructor() async {
    await assertErrorsInCode(
      r'''
class A native 'something' {
  final int x;
}
''',
      [error(diag.nativeClauseInNonSdkCode, 8, 18)],
    );
  }

  test_finalNotInitialized_initializer() async {
    await assertNoErrorsInCode(r'''
class A {
  final int x;
  A() : x = 0 {}
}
''');
  }

  test_finalNotInitialized_redirectingConstructor() async {
    await assertNoErrorsInCode(r'''
class A {
  final int x;
  A(this.x);
  A.named() : this (42);
}
''');
  }

  test_functionDeclaration_scope_returnType() async {
    await assertNoErrorsInCode('''
int f(int) { return 0; }
''');
  }

  test_functionDeclaration_scope_signature() async {
    await assertNoErrorsInCode(r'''
const app = 0;
f(@app int app) {}
''');
  }

  test_functionTypeAlias_scope_returnType() async {
    await assertNoErrorsInCode('''
typedef int f(int);
''');
  }

  test_functionTypeAlias_scope_signature() async {
    await assertNoErrorsInCode(r'''
const app = 0;
typedef int f(@app int app);
''');
  }

  test_generic_staticParameterElement_annotation() async {
    await assertNoErrorsInCode('''
class C<T> {
  const C.named({arg});
}
@C<bool>.named(arg: true)
test() {}
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y, TypeMatcher<SubstitutedFormalParameterElementImpl>());
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_annotation_implicitTypeArg() async {
    await assertNoErrorsInCode('''
class C<T> {
  const C.named({required T arg});
}
@C.named(arg: true)
test() {}
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y, TypeMatcher<SubstitutedFormalParameterElementImpl>());
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_functionCall_explicitTypeArg() async {
    await assertNoErrorsInCode('''
void generic<T>({arg}) {}

void test() {
  generic<bool>(arg: true);
}
''');

    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y.enclosingElement, isNotNull);
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_functionCall_implicitTypeArg() async {
    await assertNoErrorsInCode('''
void generic<T>({arg}) {}

void test() {
  generic(arg: true);
}
''');

    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y.enclosingElement, isNotNull);
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_instanceCreation_explicitNew() async {
    await assertNoErrorsInCode('''
class C<T> {
  C.named({arg});
}
test() => new C<bool>.named(arg: true);
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y, TypeMatcher<SubstitutedFormalParameterElementImpl>());
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_instanceCreation_explicitNew_implicitTypeArg() async {
    await assertNoErrorsInCode('''
class C<T> {
  C.named({arg});
}
C<bool> test() => new C.named(arg: true);
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y, TypeMatcher<SubstitutedFormalParameterElementImpl>());
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_instanceCreation_implicitNew() async {
    await assertNoErrorsInCode('''
class C<T> {
  C.named({arg});
}
test() => C<bool>.named(arg: true);
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y, TypeMatcher<SubstitutedFormalParameterElementImpl>());
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_instanceCreation_implicitNew_implicitTypeArg() async {
    await assertNoErrorsInCode('''
class C<T> {
  C.named({arg});
}
C<bool> test() => C.named(arg: true);
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y, TypeMatcher<SubstitutedFormalParameterElementImpl>());
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_methodCall() async {
    await assertNoErrorsInCode('''
abstract class C {
  T method<T>({arg});
}
test(C c) => c.method<bool>(arg: true);
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y.enclosingElement, isNotNull);
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_methodCall_implicitTypeArg() async {
    await assertNoErrorsInCode('''
abstract class C {
  T method<T>({arg});
}
bool test(C c) => c.method(arg: true);
''');
    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y.enclosingElement, isNotNull);
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_staticMethodCall_explicitTypeArg() async {
    await assertNoErrorsInCode('''
class C {
  static void generic<T>({arg}) {}
}

void test() {
  C.generic<bool>(arg: true);
}
''');

    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y.enclosingElement, isNotNull);
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_generic_staticParameterElement_staticMethodCall_implicitTypeArg() async {
    await assertNoErrorsInCode('''
class C {
  static void generic<T>({arg}) {}
}

void test() {
  C.generic(arg: true);
}
''');

    var x = findNode.namedExpression('arg: true');
    var y = x.correspondingParameter!;
    expect(y.enclosingElement, isNotNull);
    expect(y.baseElement, findElement2.parameter('arg'));
  }

  test_genericTypeAlias_fieldAndReturnType_noTypeParameters() async {
    await assertNoErrorsInCode(r'''
typedef Foo = int Function<T>(T x);
int foo<T>(T x) => 3;
Foo bar() => foo;
void test1() {
  bar()<String>("hello");
}

class A {
  Foo f = <T>(T x) => 0;
  void test() {
    f<String>("hello");
  }
}
''');
  }

  test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments() async {
    await assertNoErrorsInCode(r'''
typedef Foo<S> = S Function<T>(T x);
int foo<T>(T x) => 3;
Foo<int> bar() => foo;
void test1() {
  bar()<String>("hello");
}

class A {
  Foo<int> f = <T>(T x) => 0;
  void test() {
    f<String>("hello");
  }
}
''');
  }

  test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments() async {
    await assertNoErrorsInCode(r'''
typedef Foo<S> = S Function<T>(T x);
int foo<T>(T x) => 3;
Foo bar() => foo;
void test1() {
  bar()<String>("hello");
}

class A {
  Foo f = <T>(T x) {};
  void test() {
    f<String>("hello");
  }
}
''');
  }

  test_genericTypeAlias_invalidGenericFunctionType() async {
    await assertNoErrorsInCode('''
typedef F = int;
main(p) {
  p is F;
}
''');
  }

  test_genericTypeAlias_noTypeParameters() async {
    await assertNoErrorsInCode(r'''
typedef Foo = int Function<T>(T x);
int foo<T>(T x) => 3;
void test1() {
  Foo y = foo;
  // These two should be equivalent
  foo<String>("hello");
  y<String>("hello");
}
''');
  }

  test_genericTypeAlias_typeParameters() async {
    await assertNoErrorsInCode(r'''
typedef Foo<S> = S Function<T>(T x);
int foo<T>(T x) => 3;
void test1() {
  Foo<int> y = foo;
  // These two should be equivalent
  foo<String>("hello");
  y<String>("hello");
}
''');
  }

  test_implicit_call_reference_in_top_level_type_inference() async {
    // This test case is important because the variable `map` is subject to top
    // level type inference, which means it gets resolved twice.  We need to
    // make sure that on the second resolution pass, the resolver can handle the
    // ImplicitCallReference node
    await assertNoErrorsInCode(r'''
typedef Object Func(Object x);

class Bar {
  int x = 42;

  Object call(Object x) {
    return 'Bar $x';
  }
}

var map = <String, Func>{'bar': new Bar()};
''');
  }

  test_implicit_call_tearoff_assignment_rhs() async {
    await assertNoErrorsInCode('''
class C {
  void call() {}
}
test() {
  void Function() f;
  f = C();
  return f;
}
''');
    assertType(findNode.assignment('f = C()'), 'void Function()');
  }

  test_importDuplicatedLibraryName() async {
    newFile("$testPackageLibPath/lib.dart", "library lib;");
    await assertErrorsInCode(
      r'''
library test;
import 'lib.dart';
import 'lib.dart';
''',
      [
        error(diag.unusedImport, 21, 10),
        error(diag.unusedImport, 40, 10),
        error(diag.duplicateImport, 40, 10),
      ],
    );
  }

  test_importDuplicatedLibraryUnnamed() async {
    newFile("$testPackageLibPath/lib1.dart", '');
    newFile("$testPackageLibPath/lib2.dart", '');
    // No warning on duplicate import (https://github.com/dart-lang/sdk/issues/24156)
    await assertErrorsInCode(
      r'''
library test;
import 'lib1.dart';
import 'lib2.dart';
''',
      [error(diag.unusedImport, 21, 11), error(diag.unusedImport, 41, 11)],
    );
  }

  test_importOfNonLibrary_libraryDeclared() async {
    newFile("$testPackageLibPath/part.dart", r'''
library lib1;
class A {}
''');
    await assertNoErrorsInCode(r'''
library lib;
import 'part.dart';
A a = A();
''');
  }

  test_importOfNonLibrary_libraryNotDeclared() async {
    newFile("$testPackageLibPath/part.dart", '''
class A {}
''');
    await assertNoErrorsInCode(r'''
library lib;
import 'part.dart';
A a = A();
''');
  }

  test_importPrefixes_withFirstLetterDifference() async {
    newFile("$testPackageLibPath/lib1.dart", r'''
library lib1;
test1() {}
''');
    newFile("$testPackageLibPath/lib2.dart", r'''
library lib2;
test2() {}
''');
    await assertNoErrorsInCode(r'''
library L;
import 'lib1.dart' as math;
import 'lib2.dart' as path;
main() {
  math.test1();
  path.test2();
}
''');
  }

  test_inconsistentMethodInheritance_accessors_typeParameters1() async {
    await assertNoErrorsInCode(r'''
abstract class A<E> {
  E? get x;
}
abstract class B<E> {
  E? get x;
}
class C<E> implements A<E>, B<E> {
  E? get x => null;
}
''');
  }

  test_inconsistentMethodInheritance_accessors_typeParameters2() async {
    await assertNoErrorsInCode(r'''
abstract class A<E> {
  E? get x {return null;}
}
class B<E> {
  E? get x {return null;}
}
class C<E> extends A<E> implements B<E> {}
''');
  }

  test_inconsistentMethodInheritance_accessors_typeParameters_diamond() async {
    await assertNoErrorsInCode(r'''
abstract class F<E> extends B<E> {}
class D<E> extends F<E> {
  external E? get g;
}
abstract class C<E> {
  E? get g;
}
abstract class B<E> implements C<E> {
  E? get g { return null; }
}
class A<E> extends B<E> implements D<E> {
}
''');
  }

  test_inconsistentMethodInheritance_methods_typeParameter2() async {
    await assertNoErrorsInCode(r'''
class A<E> {
  x(E e) {}
}
class B<E> {
  x(E e) {}
}
class C<E> extends A<E> implements B<E> {
  x(E e) {}
}
''');
  }

  test_inconsistentMethodInheritance_methods_typeParameters1() async {
    await assertNoErrorsInCode(r'''
class A<E> {
  x(E e) {}
}
class B<E> {
  x(E e) {}
}
class C<E> implements A<E>, B<E> {
  x(E e) {}
}
''');
  }

  test_inconsistentMethodInheritance_simple() async {
    await assertNoErrorsInCode(r'''
abstract class A {
  x();
}
abstract class B {
  x();
}
class C implements A, B {
  x() {}
}
''');
  }

  test_initializingFormalForNonExistentField() async {
    await assertNoErrorsInCode(r'''
class A {
  int x;
  A(this.x) {}
}
''');
  }

  test_instance_creation_inside_annotation() async {
    await assertNoErrorsInCode('''
class C {
  const C();
}
class D {
  final C c;
  const D(this.c);
}
@D(const C())
f() {}
''');
  }

  test_instanceAccessToStaticMember_fromComment() async {
    await assertNoErrorsInCode(r'''
class A {
  static m() {}
}
/// [A.m]
main() {
}
''');
  }

  test_instanceAccessToStaticMember_topLevel() async {
    await assertNoErrorsInCode(r'''
m() {}
main() {
  m();
}
''');
  }

  test_instanceMemberAccessFromStatic_fromComment() async {
    await assertNoErrorsInCode(r'''
class A {
  m() {}
  /// [m]
  static foo() {
  }
}
''');
  }

  test_instanceMethodNameCollidesWithSuperclassStatic_field() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library L;
class A {
  static var _m;
}
''');
    await assertErrorsInCode(
      r'''
import 'lib.dart';
class B extends A {
  _m() {}
}
''',
      [error(diag.unusedElement, 41, 2)],
    );
  }

  test_instanceMethodNameCollidesWithSuperclassStatic_method() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library L;
class A {
  static _m() {}
}
''');
    await assertErrorsInCode(
      r'''
import 'lib.dart';
class B extends A {
  _m() {}
}
''',
      [error(diag.unusedElement, 41, 2)],
    );
  }

  test_instantiateGenericFunctionWithNamedParameterAsGenericArg() async {
    // This test case reproduces the problem encountered in
    // https://dart-review.googlesource.com/c/sdk/+/402341/comment/b1669e20_15938fcd/.
    await assertNoErrorsInCode(r'''
abstract class C<T> {
  S f<S>(S Function(C<T>) g);
}

T h<T>(C<T> c, {bool b = false}) => throw '';

T test<T>(C<T> c) => c.f(h);
''');
  }

  test_integerLiteralOutOfRange_negative_leadingZeros() async {
    await assertNoErrorsInCode('''
int x = -000923372036854775809;
''');
  }

  test_integerLiteralOutOfRange_negative_small() async {
    await assertNoErrorsInCode('''
int x = -42;
''');
  }

  test_integerLiteralOutOfRange_negative_valid() async {
    await assertNoErrorsInCode('''
int x = -9223372036854775808;
''');
  }

  test_integerLiteralOutOfRange_positive_leadingZeros() async {
    await assertNoErrorsInCode('''
int x = 000923372036854775808;
''');
  }

  test_integerLiteralOutOfRange_positive_valid() async {
    await assertNoErrorsInCode('''
int x = 9223372036854775807;
''');
  }

  test_integerLiteralOutOfRange_positive_zero() async {
    await assertNoErrorsInCode('''
int x = 0;
''');
  }

  test_intLiteralInDoubleContext() async {
    await assertNoErrorsInCode(r'''
void takeDouble(double x) {}
void main() {
  takeDouble(0);
  takeDouble(-0);
  takeDouble(0x0);
  takeDouble(-0x0);
}
''');
  }

  test_invalidAnnotation_constantVariable_field() async {
    await assertNoErrorsInCode(r'''
@A.C
class A {
  static const C = 0;
}
''');
  }

  test_invalidAnnotation_constantVariable_field_importWithPrefix() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library lib;
class A {
  static const C = 0;
}
''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' as p;
@p.A.C
main() {
}
''');
  }

  test_invalidAnnotation_constantVariable_topLevel() async {
    await assertNoErrorsInCode(r'''
const C = 0;
@C
main() {
}
''');
  }

  test_invalidAnnotation_constantVariable_topLevel_importWithPrefix() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library lib;
const C = 0;
''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' as p;
@p.C
main() {
}
''');
  }

  test_invalidAnnotation_constConstructor_importWithPrefix() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library lib;
class A {
  const A(int p);
}
''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' as p;
@p.A(42)
main() {
}
''');
  }

  test_invalidAnnotation_constConstructor_named_importWithPrefix() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library lib;
class A {
  const A.named(int p);
}
''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' as p;
@p.A.named(42)
main() {
}
''');
  }

  test_invalidIdentifierInAsync() async {
    await assertErrorsInCode(
      r'''
class A {
  m() {
    int async;
    int await;
    int yield;
  }
}
''',
      [
        error(diag.unusedLocalVariable, 26, 5),
        error(diag.unusedLocalVariable, 41, 5),
        error(diag.unusedLocalVariable, 56, 5),
      ],
    );
  }

  test_invalidMethodOverrideNamedParamType() async {
    await assertNoErrorsInCode(r'''
class A {
  m({int a = 1}) {}
}
class B implements A {
  m({int a = 1, int b = 2}) {}
}
''');
  }

  test_invalidOverrideNamed_unorderedNamedParameter() async {
    await assertNoErrorsInCode(r'''
class A {
  m({a, b}) {}
}
class B extends A {
  m({b, a}) {}
}
''');
  }

  test_invalidOverrideRequired_less() async {
    await assertNoErrorsInCode(r'''
class A {
  m(a, b) {}
}
class B extends A {
  m(a, [b]) {}
}
''');
  }

  test_invalidOverrideRequired_same() async {
    await assertNoErrorsInCode(r'''
class A {
  m(a) {}
}
class B extends A {
  m(a) {}
}
''');
  }

  test_invalidOverrideReturnType_returnType_interface() async {
    await assertNoErrorsInCode(r'''
abstract class A {
  num m();
}
class B implements A {
  int m() { return 1; }
}
''');
  }

  test_invalidOverrideReturnType_returnType_interface2() async {
    await assertNoErrorsInCode(r'''
abstract class A {
  num m();
}
abstract class B implements A {
}
class C implements B {
  int m() { return 1; }
}
''');
  }

  test_invalidOverrideReturnType_returnType_mixin() async {
    await assertNoErrorsInCode(r'''
mixin A {
  num m() { return 0; }
}
class B extends Object with A {
  int m() { return 1; }
}
''');
  }

  test_invalidOverrideReturnType_returnType_parameterizedTypes() async {
    await assertNoErrorsInCode(r'''
abstract class A<E> {
  List<E> m();
}
class B extends A<dynamic> {
  List<dynamic> m() { return <dynamic>[]; }
}
''');
  }

  test_invalidOverrideReturnType_returnType_sameType() async {
    await assertNoErrorsInCode(r'''
class A {
  int m() { return 0; }
}
class B extends A {
  int m() { return 1; }
}
''');
  }

  test_invalidOverrideReturnType_returnType_superclass() async {
    await assertNoErrorsInCode(r'''
class A {
  num m() { return 0; }
}
class B extends A {
  int m() { return 1; }
}
''');
  }

  test_invalidOverrideReturnType_returnType_superclass2() async {
    await assertNoErrorsInCode(r'''
class A {
  num m() { return 0; }
}
class B extends A {
}
class C extends B {
  int m() { return 1; }
}
''');
  }

  test_invalidOverrideReturnType_returnType_void() async {
    await assertNoErrorsInCode(r'''
class A {
  void m() {}
}
class B extends A {
  int m() { return 0; }
}
''');
  }

  test_invalidTypeArgumentForKey() async {
    await assertNoErrorsInCode(r'''
class A {
  m() {
    return const <int, int>{};
  }
}
''');
  }

  Future test_issue32114() async {
    newFile('$testPackageLibPath/a.dart', '''
class O {}

typedef T Func<T extends O>(T e);
''');
    newFile('$testPackageLibPath/b.dart', '''
import 'a.dart';
export 'a.dart' show Func;

abstract class A<T extends O> {
  Func<T> get func;
}
''');
    await assertNoErrorsInCode('''
import 'b.dart';

class B extends A {
  Func get func => (x) => x;
}
''');
  }

  test_issue_24191() async {
    await assertNoErrorsInCode('''
abstract class S extends Stream {}
f(S s) async {
  await for (var v in s) {
    print(v);
  }
}
''');
  }

  test_issue_32394() async {
    await assertErrorsInCode(
      '''
var x = y.map((a) => a.toString());
var y = [3];
var z = x.toList();

void main() {
  String p = z;
}
''',
      [
        error(diag.unusedLocalVariable, 93, 1),
        error(diag.invalidAssignment, 97, 1),
      ],
    );
    var z = result.unit.declaredFragment!.element.topLevelVariables
        .where((e) => e.name == 'z')
        .single;
    assertType(z.type, 'List<String>');
  }

  test_issue_35320_lists() async {
    newFile('$testPackageLibPath/lib.dart', '''
const x = const <String>['a'];
''');
    await assertNoErrorsInCode('''
import 'lib.dart';
const y = const <String>['b'];
int f(v) {
  switch(v) {
    case x:
      return 0;
    case y:
      return 1;
    default:
      return 2;
  }
}
''');
  }

  test_issue_35320_maps() async {
    newFile('$testPackageLibPath/lib.dart', '''
const x = const <String, String>{'a': 'b'};
''');
    await assertNoErrorsInCode('''
import 'lib.dart';
const y = const <String, String>{'c': 'd'};
int f(v) {
  switch(v) {
    case x:
      return 0;
    case y:
      return 1;
    default:
      return 2;
  }
}
''');
  }

  test_librarySource_of_type_substituted_synthetic_parameter() async {
    await assertErrorsInCode(
      '''
Map<int, T> f<T>(T t) => throw '';
Map<double, T> g<T>(T t) => throw '';
h(bool b) {
  Map<num, String> m = (b ? f : g)('x');
}
''',
      [error(diag.unusedLocalVariable, 104, 1)],
    );
    var parameter = findNode.stringLiteral("'x'").correspondingParameter;
    expect(parameter!.library, isNull);
    expect(parameter.library?.firstFragment.source, isNull);
  }

  test_loadLibraryDefined() async {
    newFile('$testPackageLibPath/lib.dart', r'''
library lib;
foo() => 22;''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' deferred as other;
main() {
  other.loadLibrary().then((_) => other.foo());
}
''');
  }

  test_local_generator_async() async {
    await assertNoErrorsInCode('''
f() {
  return () async* { yield 0; };
}
''');
  }

  test_local_generator_sync() async {
    await assertNoErrorsInCode('''
f() {
  return () sync* { yield 0; };
}
''');
  }

  test_metadata_enumConstantDeclaration() async {
    await assertNoErrorsInCode(r'''
const x = 1;
enum E {
  aaa,
  @x
  bbb
}
''');
  }

  test_methodDeclaration_scope_signature() async {
    await assertNoErrorsInCode(r'''
const app = 0;
class A {
  foo(@app int app) {}
}
''');
  }

  test_missingEnumConstantInSwitch_all() async {
    await assertNoErrorsInCode(r'''
enum E { A, B, C }

f(E e) {
  switch (e) {
    case E.A: break;
    case E.B: break;
    case E.C: break;
  }
}
''');
  }

  test_missingEnumConstantInSwitch_all_language219() async {
    await assertNoErrorsInCode(r'''
// @dart = 2.19
enum E { A, B, C }

f(E e) {
  switch (e) {
    case E.A: break;
    case E.B: break;
    case E.C: break;
  }
}
''');
  }

  test_missingEnumConstantInSwitch_default() async {
    await assertNoErrorsInCode(r'''
enum E { A, B, C }

f(E e) {
  switch (e) {
    case E.B: break;
    default: break;
  }
}
''');
  }

  test_missingEnumConstantInSwitch_default_language219() async {
    await assertNoErrorsInCode(r'''
// @dart = 2.19
enum E { A, B, C }

f(E e) {
  switch (e) {
    case E.B: break;
    default: break;
  }
}
''');
  }

  test_mixedReturnTypes_differentScopes() async {
    await assertNoErrorsInCode(r'''
class C {
  m(int x) {
    f(int y) {
      return;
    }
    f(x);
    return 0;
  }
}
''');
  }

  test_mixedReturnTypes_ignoreImplicit() async {
    await assertNoErrorsInCode(r'''
f(bool p) {
  if (p) return 42;
  // implicit 'return;' is ignored
}
''');
  }

  test_mixedReturnTypes_ignoreImplicit2() async {
    await assertNoErrorsInCode(r'''
f(bool p) {
  if (p) {
    return 42;
  } else {
    return 42;
  }
  // implicit 'return;' is ignored
}
''');
  }

  test_mixedReturnTypes_sameKind() async {
    await assertNoErrorsInCode(r'''
class C {
  m(int x) {
    if (x < 0) {
      return 1;
    }
    return 0;
  }
}
''');
  }

  test_mixinDeclaresConstructor() async {
    await assertNoErrorsInCode(r'''
mixin class A {
  m() {}
}
class B extends Object with A {}
''');
  }

  test_mixinDeclaresConstructor_factory() async {
    await assertNoErrorsInCode(r'''
mixin class A {
  factory A() => throw 0;
}
class B extends Object with A {}
''');
  }

  test_multipleSuperInitializers_no() async {
    await assertNoErrorsInCode(r'''
class A {}
class B extends A {
  B() {}
}
''');
  }

  test_multipleSuperInitializers_single() async {
    await assertNoErrorsInCode(r'''
class A {}
class B extends A {
  B() : super() {}
}
''');
  }

  test_newWithAbstractClass_factory() async {
    await assertNoErrorsInCode(r'''
abstract class A {
  factory A() { return new B(); }
}
class B implements A {
  B() {}
}
A f() {
  return new A();
}
''');
  }

  test_no_call_tearoff_on_promoted_var() async {
    await assertNoErrorsInCode('''
class B {
  Object call() => '';
}
void test(Object x) {
  x as Object Function();
  x; // promoted
  x = B(); // No implicit tearoff of `.call`, demotes x
  x; // demoted
}
''');
    assertType(findNode.simple('x; // promoted'), 'Object Function()');
    assertType(findNode.assignment('x = B()'), 'B');
    assertType(findNode.simple('x; // demoted'), 'Object');
  }

  test_nonBoolExpression_interfaceType() async {
    await assertNoErrorsInCode(r'''
f() {
  assert(true);
}
''');
  }

  test_nonBoolNegationExpression() async {
    await assertNoErrorsInCode(r'''
f(bool pb, pd) {
  !true;
  !false;
  !pb;
  !pd;
}
''');
  }

  test_nonBoolNegationExpression_dynamic() async {
    await assertErrorsInCode(
      r'''
f1(bool dynamic) {
  !dynamic;
}
f2() {
  bool dynamic = true;
  !dynamic;
}
''',
      [error(diag.unusedLocalVariable, 47, 7)],
    );
  }

  test_nonBoolOperand_and_bool() async {
    await assertNoErrorsInCode(r'''
bool f(bool left, bool right) {
  return left && right;
}
''');
  }

  test_nonBoolOperand_and_dynamic() async {
    await assertNoErrorsInCode(r'''
bool f(left, dynamic right) {
  return left && right;
}
''');
  }

  test_nonBoolOperand_or_bool() async {
    await assertNoErrorsInCode(r'''
bool f(bool left, bool right) {
  return left || right;
}
''');
  }

  test_nonBoolOperand_or_dynamic() async {
    await assertNoErrorsInCode(r'''
bool f(dynamic left, right) {
  return left || right;
}
''');
  }

  test_nonConstantDefaultValue_constField() async {
    await assertNoErrorsInCode(r'''
f([a = double.infinity]) {
}
''');
  }

  test_nonConstantDefaultValue_function_named() async {
    await assertNoErrorsInCode('''
f({x = 2 + 3}) {}
''');
  }

  test_nonConstantDefaultValue_function_positional() async {
    await assertNoErrorsInCode('''
f([x = 2 + 3]) {}
''');
  }

  test_nonConstantDefaultValue_inConstructor_named() async {
    await assertNoErrorsInCode(r'''
class A {
  A({x = 2 + 3}) {}
}
''');
  }

  test_nonConstantDefaultValue_inConstructor_positional() async {
    await assertNoErrorsInCode(r'''
class A {
  A([x = 2 + 3]) {}
}
''');
  }

  test_nonConstantDefaultValue_method_named() async {
    await assertNoErrorsInCode(r'''
class A {
  m({x = 2 + 3}) {}
}
''');
  }

  test_nonConstantDefaultValue_method_positional() async {
    await assertNoErrorsInCode(r'''
class A {
  m([x = 2 + 3]) {}
}
''');
  }

  test_nonConstantDefaultValue_typedConstList() async {
    await assertNoErrorsInCode(r'''
class A {
  m([p111 = const <String>[]]) {}
}
class B extends A {
  m([p222 = const <String>[]]) {}
}
''');
  }

  test_nonConstantValueInInitializer_namedArgument() async {
    await assertNoErrorsInCode(r'''
class A {
  final a;
  const A({this.a});
}
class B extends A {
  const B({b}) : super(a: b);
}
''');
  }

  test_nonConstListElement_constField() async {
    await assertNoErrorsInCode(r'''
main() {
  const [double.infinity];
}
''');
  }

  test_nonConstMapAsExpressionStatement_const() async {
    await assertNoErrorsInCode(r'''
f() {
  const {'a' : 0, 'b' : 1};
}
''');
  }

  test_nonConstMapAsExpressionStatement_notExpressionStatement() async {
    await assertErrorsInCode(
      r'''
f() {
  var m = {'a' : 0, 'b' : 1};
}
''',
      [error(diag.unusedLocalVariable, 12, 1)],
    );
  }

  test_nonConstMapAsExpressionStatement_typeArguments() async {
    await assertNoErrorsInCode(r'''
f() {
  <String, int> {'a' : 0, 'b' : 1};
}
''');
  }

  test_nonConstMapValue_constField() async {
    await assertNoErrorsInCode(r'''
main() {
  const {0: double.infinity};
}
''');
  }

  test_nonConstValueInInitializer_binary_bool() async {
    await assertErrorsInCode(
      r'''
class A {
  final v;
  const A.a1(bool p) : v = p && true;
  const A.a2(bool p) : v = true && p;
  const A.b1(bool p) : v = p || true;
  const A.b2(bool p) : v = true || p;
}
''',
      [error(diag.deadCode, 167, 4)],
    );
  }

  test_nonConstValueInInitializer_binary_dynamic() async {
    await assertNoErrorsInCode(r'''
class A {
  final v;
  const A.a1(p) : v = p + 5;
  const A.a2(p) : v = 5 + p;
  const A.b1(p) : v = p - 5;
  const A.b2(p) : v = 5 - p;
  const A.c1(p) : v = p * 5;
  const A.c2(p) : v = 5 * p;
  const A.d1(p) : v = p / 5;
  const A.d2(p) : v = 5 / p;
  const A.e1(p) : v = p ~/ 5;
  const A.e2(p) : v = 5 ~/ p;
  const A.f1(p) : v = p > 5;
  const A.f2(p) : v = 5 > p;
  const A.g1(p) : v = p < 5;
  const A.g2(p) : v = 5 < p;
  const A.h1(p) : v = p >= 5;
  const A.h2(p) : v = 5 >= p;
  const A.i1(p) : v = p <= 5;
  const A.i2(p) : v = 5 <= p;
  const A.j1(p) : v = p % 5;
  const A.j2(p) : v = 5 % p;
}
''');
  }

  test_nonConstValueInInitializer_binary_int() async {
    await assertNoErrorsInCode(r'''
class A {
  final v;
  const A.a1(int p) : v = p ^ 5;
  const A.a2(int p) : v = 5 ^ p;
  const A.b1(int p) : v = p & 5;
  const A.b2(int p) : v = 5 & p;
  const A.c1(int p) : v = p | 5;
  const A.c2(int p) : v = 5 | p;
  const A.d1(int p) : v = p >> 5;
  const A.d2(int p) : v = 5 >> p;
  const A.e1(int p) : v = p << 5;
  const A.e2(int p) : v = 5 << p;
}
''');
  }

  test_nonConstValueInInitializer_binary_num() async {
    await assertNoErrorsInCode(r'''
class A {
  final v;
  const A.a1(num p) : v = p + 5;
  const A.a2(num p) : v = 5 + p;
  const A.b1(num p) : v = p - 5;
  const A.b2(num p) : v = 5 - p;
  const A.c1(num p) : v = p * 5;
  const A.c2(num p) : v = 5 * p;
  const A.d1(num p) : v = p / 5;
  const A.d2(num p) : v = 5 / p;
  const A.e1(num p) : v = p ~/ 5;
  const A.e2(num p) : v = 5 ~/ p;
  const A.f1(num p) : v = p > 5;
  const A.f2(num p) : v = 5 > p;
  const A.g1(num p) : v = p < 5;
  const A.g2(num p) : v = 5 < p;
  const A.h1(num p) : v = p >= 5;
  const A.h2(num p) : v = 5 >= p;
  const A.i1(num p) : v = p <= 5;
  const A.i2(num p) : v = 5 <= p;
  const A.j1(num p) : v = p % 5;
  const A.j2(num p) : v = 5 % p;
}
''');
  }

  test_nonConstValueInInitializer_field() async {
    await assertNoErrorsInCode(r'''
class A {
  final int a;
  const A() : a = 5;
}
''');
  }

  test_nonConstValueInInitializer_redirecting() async {
    await assertNoErrorsInCode(r'''
class A {
  const A.named(p);
  const A() : this.named(42);
}
''');
  }

  test_nonConstValueInInitializer_super() async {
    await assertNoErrorsInCode(r'''
class A {
  const A(p);
}
class B extends A {
  const B() : super(42);
}
''');
  }

  test_nonConstValueInInitializer_unary() async {
    await assertNoErrorsInCode(r'''
class A {
  final v;
  const A.a(bool p) : v = !p;
  const A.b(int p) : v = ~p;
  const A.c(num p) : v = -p;
}
''');
  }

  @failingTest
  test_null_callOperator() async {
    await assertErrorsInCode(
      r'''
main() {
  null + 5;
  null == 5;
  null[0];
}
''',
      [error(diag.undefinedMethod, 0, 0), error(diag.undefinedMethod, 0, 0)],
    );
  }

  test_optionalNew_rewrite() async {
    newFile("$testPackageLibPath/a.dart", r'''
class A {
  const A();
  const A.named();
}
''');
    newFile("$testPackageLibPath/b.dart", r'''
import 'a.dart';
import 'a.dart' as p;

const _a1 = A();
const _a2 = A.named();
const _a3 = p.A();
const _a4 = p.A.named();

class B {
  const B.named1({this.a: _a1}) : assert(a != null);
  const B.named2({this.a: _a2}) : assert(a != null);
  const B.named3({this.a: _a3}) : assert(a != null);
  const B.named4({this.a: _a4}) : assert(a != null);

  final A a;
}
''');
    await assertNoErrorsInCode(r'''
import 'b.dart';
main() {
  const B.named1();
  const B.named2();
  const B.named3();
  const B.named4();
}
''');
  }

  test_optionalNew_rewrite_instantiatesToBounds() async {
    newFile("$testPackageLibPath/a.dart", r'''
class Unbounded<T> {
  const Unbounded();
  const Unbounded.named();
}
class Bounded<T extends String> {
  const Bounded();
  const Bounded.named();
}
''');
    newFile("$testPackageLibPath/b.dart", r'''
import 'a.dart';
import 'a.dart' as p;

const unbounded1 = Unbounded();
const unbounded2 = Unbounded.named();
const unbounded3 = p.Unbounded();
const unbounded4 = p.Unbounded.named();
const bounded1 = Bounded();
const bounded2 = Bounded.named();
const bounded3 = p.Bounded();
const bounded4 = p.Bounded.named();

class B {
  const B.named1({this.unbounded: unbounded1}) : bounded = null;
  const B.named2({this.unbounded: unbounded2}) : bounded = null;
  const B.named3({this.unbounded: unbounded3}) : bounded = null;
  const B.named4({this.unbounded: unbounded4}) : bounded = null;
  const B.named5({this.bounded: bounded1}) : unbounded = null;
  const B.named6({this.bounded: bounded2}) : unbounded = null;
  const B.named7({this.bounded: bounded3}) : unbounded = null;
  const B.named8({this.bounded: bounded4}) : unbounded = null;

  final Unbounded? unbounded;
  final Bounded? bounded;
}
''');
    await assertNoErrorsInCode(r'''
import 'b.dart';

@B.named1()
@B.named2()
@B.named3()
@B.named4()
@B.named5()
@B.named6()
@B.named7()
@B.named8()
main() {}
''');
    expect(result.unit.declarations, hasLength(1));
    var mainDecl = result.unit.declarations[0];
    expect(mainDecl.metadata, hasLength(8));
    for (var metadata in mainDecl.metadata) {
      var value = metadata.elementAnnotation!.computeConstantValue()!;
      expect(value, isNotNull);
      assertType(value.type, 'B');
      var unbounded = value.getField('unbounded')!;
      var bounded = value.getField('bounded')!;
      if (!unbounded.isNull) {
        expect(bounded.isNull, true);
        assertType(unbounded.type, 'Unbounded<dynamic>');
      } else {
        expect(unbounded.isNull, true);
        assertType(bounded.type, 'Bounded<String>');
      }
    }
  }

  test_parameterScope_local() async {
    // Parameter names shouldn't conflict with the name of the function they
    // are enclosed in.
    await assertErrorsInCode(
      r'''
f() {
  g(g) {
    h(g);
  }
}
h(x) {}
''',
      [error(diag.unusedElement, 8, 1)],
    );
  }

  test_parameterScope_method() async {
    // Parameter names shouldn't conflict with the name of the function they
    // are enclosed in.
    await assertNoErrorsInCode(r'''
class C {
  g(g) {
    h(g);
  }
}
h(x) {}
''');
  }

  test_parameterScope_topLevel() async {
    // Parameter names shouldn't conflict with the name of the function they
    // are enclosed in.
    await assertNoErrorsInCode(r'''
g(g) {
  h(g);
}
h(x) {}
''');
  }

  test_parametricCallFunction() async {
    await assertNoErrorsInCode(r'''
f() {
  var c = new C();
  c<String>('').codeUnits;
}

class C {
  T call<T>(T a) => a;
}
''');
  }

  test_propagateTypeArgs_intoBounds() async {
    await assertNoErrorsInCode(r'''
abstract class A<E> {}
abstract class B<F> implements A<F>{}
abstract class C<G, H extends A<G>> {}
class D<I> extends C<I, B<I>> {}
''');
  }

  test_propagateTypeArgs_intoSupertype() async {
    await assertNoErrorsInCode(r'''
class A<T> {
  A(T p);
  A.named(T p);
}
class B<S> extends A<S> {
  B(S p) : super(p);
  B.named(S p) : super.named(p);
}
''');
  }

  test_referenceToDeclaredVariableInInitializer_constructorName() async {
    await assertErrorsInCode(
      r'''
class A {
  A.x() {}
}
f() {
  var x = new A.x();
}
''',
      [error(diag.unusedLocalVariable, 35, 1)],
    );
  }

  test_referenceToDeclaredVariableInInitializer_methodName() async {
    await assertErrorsInCode(
      r'''
class A {
  x() {}
}
f(A a) {
  var x = a.x();
}
''',
      [error(diag.unusedLocalVariable, 36, 1)],
    );
  }

  test_referenceToDeclaredVariableInInitializer_propertyName() async {
    await assertErrorsInCode(
      r'''
class A {
  var x;
}
f(A a) {
  var x = a.x;
}
''',
      [error(diag.unusedLocalVariable, 36, 1)],
    );
  }

  test_regress34906() async {
    await assertNoErrorsInCode(r'''
typedef G<X, Y extends Function(X)> = X Function(Function(Y));
f(G<dynamic, Function(Null)> superBoundedG) {}
''');
  }

  test_reversedTypeArguments() async {
    await assertNoErrorsInCode(r'''
class Codec<S1, T1> {
  Codec<T1, S1> get inverted => new _InvertedCodec<T1, S1>(this);
}
class _InvertedCodec<T2, S2> extends Codec<T2, S2> {
  _InvertedCodec(Codec<S2, T2> codec);
}
''');
  }

  test_sharedDeferredPrefix() async {
    newFile('$testPackageLibPath/lib1.dart', r'''
f1() {}
''');
    newFile('$testPackageLibPath/lib2.dart', r'''
f2() {}
''');
    newFile('$testPackageLibPath/lib3.dart', r'''
f3() {}
''');
    await assertNoErrorsInCode(r'''
import 'lib1.dart' deferred as lib1;
import 'lib2.dart' as lib;
import 'lib3.dart' as lib;
main() { lib1.f1(); lib.f2(); lib.f3(); }
''');
  }

  test_type_parameter_extends_futureOr_of_extension_type() async {
    await assertNoErrorsInCode('''
import 'dart:async';

extension type E(int i) {}

void f<T extends FutureOr<E>>() {}
''');
  }

  test_typeArgument_boundToFunctionType() async {
    await assertNoErrorsInCode('''
class A<T extends void Function(T)>{}
''');
  }

  test_typedef_not_function() async {
    newFile('$testPackageLibPath/a.dart', '''
typedef F = int;
''');
    await assertNoErrorsInCode('''
import 'a.dart';
F f = 0;
''');
  }

  test_typePromotion_booleanAnd_useInRight() async {
    await assertNoErrorsInCode(r'''
main(Object p) {
  p is String && p.length != 0;
}
''');
  }

  test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() async {
    await assertNoErrorsInCode(r'''
callMe(f()) { f(); }
main(Object p) {
  (p is String) && callMe(() { p.length; });
}
''');
  }

  test_typePromotion_conditional_useInThen() async {
    await assertNoErrorsInCode(r'''
main(Object p) {
  p is String ? p.length : 0;
}''');
  }

  test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() async {
    await assertNoErrorsInCode(r'''
callMe(f()) { f(); }
main(Object p) {
  p is String ? callMe(() { p.length; }) : 0;
}
''');
  }

  test_typePromotion_functionType_arg_ignoreIfNotMoreSpecific() async {
    await assertNoErrorsInCode(r'''
typedef FuncB(B b);
typedef FuncA(A a);
class A {}
class B {}
void f(FuncA f) {
  if (f is FuncB) {
    f(new A());
  }
}
''');
  }

  test_typePromotion_functionType_return_ignoreIfNotMoreSpecific() async {
    await assertNoErrorsInCode(r'''
class A {}
typedef FuncAtoDyn(A a);
typedef FuncDynToDyn(x);
void f(FuncAtoDyn f, A a) {
  if (f is FuncDynToDyn) {
    a = f(new A());
  }
}
''');
  }

  test_typePromotion_functionType_return_voidToDynamic() async {
    await assertNoErrorsInCode(r'''
typedef FuncDynToDyn(x);
typedef void FuncDynToVoid(x);
class A {}
void f(FuncDynToVoid? f, A a) {
  if (f is FuncDynToDyn) {
    a = f(null);
  }
}
''');
  }

  test_typePromotion_if_accessedInClosure_noAssignment() async {
    await assertNoErrorsInCode(r'''
callMe(f()) { f(); }
main(Object p) {
  if (p is String) {
    callMe(() {
      p.length;
    });
  }
}
''');
  }

  test_typePromotion_if_extends_moreSpecific() async {
    await assertNoErrorsInCode(r'''
class V {}
class VP extends V {}
class A<T> {}
class B<S> extends A<S> {
  var b;
}

void f(A<V> p) {
  if (p is B<VP>) {
    p.b;
  }
}
''');
  }

  test_typePromotion_if_hasAssignment_outsideAfter() async {
    await assertNoErrorsInCode(r'''
main(Object p) {
  if (p is String) {
    p.length;
  }
  p = 0;
}
''');
  }

  test_typePromotion_if_hasAssignment_outsideBefore() async {
    await assertNoErrorsInCode(r'''
main(Object p, Object p2) {
  p = p2;
  if (p is String) {
    p.length;
  }
}''');
  }

  test_typePromotion_if_implements_moreSpecific() async {
    await assertNoErrorsInCode(r'''
class V {}
class VP extends V {}
class A<T> {}
class B<S> implements A<S> {
  var b;
}

void f(A<V> p) {
  if (p is B<VP>) {
    p.b;
  }
}
''');
  }

  test_typePromotion_if_inClosure_assignedAfter_inSameFunction() async {
    await assertErrorsInCode(
      r'''
main() {
  f(Object p) {
    if (p is String) {
      p.length;
    }
    p = 0;
  };
}
''',
      [error(diag.unusedElement, 11, 1)],
    );
  }

  test_typePromotion_if_is_and_left() async {
    await assertNoErrorsInCode(r'''
bool tt() => true;
main(Object p) {
  if (p is String && tt()) {
    p.length;
  }
}
''');
  }

  test_typePromotion_if_is_and_right() async {
    await assertNoErrorsInCode(r'''
bool tt() => true;
main(Object p) {
  if (tt() && p is String) {
    p.length;
  }
}
''');
  }

  test_typePromotion_if_is_parenthesized() async {
    await assertNoErrorsInCode(r'''
main(Object p) {
  if ((p is String)) {
    p.length;
  }
}
''');
  }

  test_typePromotion_if_is_single() async {
    await assertNoErrorsInCode(r'''
main(Object p) {
  if (p is String) {
    p.length;
  }
}
''');
  }

  test_typePromotion_parentheses() async {
    await assertNoErrorsInCode(r'''
main(Object p) {
  (p is String) ? p.length : 0;
  (p) is String ? p.length : 0;
  ((p)) is String ? p.length : 0;
  ((p) is String) ? p.length : 0;
}
''');
  }

  test_typeType_class() async {
    await assertNoErrorsInCode(r'''
class C {}
f(Type t) {}
main() {
  f(C);
}
''');
  }

  test_typeType_class_prefixed() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library lib;
class C {}''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' as p;
f(Type t) {}
main() {
  f(p.C);
}
''');
  }

  test_typeType_functionTypeAlias() async {
    await assertNoErrorsInCode(r'''
typedef F();
f(Type t) {}
main() {
  f(F);
}
''');
  }

  test_typeType_functionTypeAlias_prefixed() async {
    newFile("$testPackageLibPath/lib.dart", r'''
library lib;
typedef F();''');
    await assertNoErrorsInCode(r'''
import 'lib.dart' as p;
f(Type t) {}
main() {
  f(p.F);
}
''');
  }

  test_undefinedSuperMethod_field() async {
    await assertNoErrorsInCode(r'''
class A {
  var m;
}
class B extends A {
  f() {
    super.m();
  }
}
''');
  }

  test_undefinedSuperMethod_method() async {
    await assertNoErrorsInCode(r'''
class A {
  m() {}
}
class B extends A {
  f() {
    super.m();
  }
}
''');
  }

  Future test_useDynamicWithPrefix() async {
    await assertNoErrorsInCode('''
import 'dart:core' as core;

core.dynamic dynamicVariable;
''');
  }

  test_yieldStar_inside_method_async() async {
    await assertNoErrorsInCode('''
class A {
  m() async* {
    yield* Stream.fromIterable([1]);
  }
}
''');

    assertType(
      findNode
          .yieldStatement('yield* Stream.fromIterable([1]);')
          .expression
          .staticType,
      'Stream<int>',
    );
  }

  test_yieldStar_inside_method_sync() async {
    await assertNoErrorsInCode('''
class A {
  m() sync* {
    yield* [1];
  }
}
''');

    assertType(
      findNode.yieldStatement('yield* [1];').expression.staticType,
      'List<int>',
    );
  }
}
