// Copyright (c) 2023, 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:test_reflective_loader/test_reflective_loader.dart';

import 'context_collection_resolution.dart';

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

@reflectiveTest
class FunctionTypedFormalParameterResolutionTest
    extends PubPackageResolutionTest {
  test_hasTypeParameters() async {
    await resolveTestCode('''
void f<V>(T p<T, U>(U a, V b)) {}
''');

    var node = findNode.singleFunctionTypedFormalParameter;
    assertResolvedNodeText(node, r'''
FunctionTypedFormalParameter
  returnType: NamedType
    name: T
    element: #E0 T
    type: T
  name: p
  typeParameters: TypeParameterList
    leftBracket: <
    typeParameters
      TypeParameter
        name: T
        declaredFragment: <testLibraryFragment> T@14
          defaultType: null
      TypeParameter
        name: U
        declaredFragment: <testLibraryFragment> U@17
          defaultType: null
    rightBracket: >
  parameters: FormalParameterList
    leftParenthesis: (
    parameter: SimpleFormalParameter
      type: NamedType
        name: U
        element: #E1 U
        type: U
      name: a
      declaredFragment: <testLibraryFragment> a@22
        element: isPublic
          type: U
    parameter: SimpleFormalParameter
      type: NamedType
        name: V
        element: #E2 V
        type: V
      name: b
      declaredFragment: <testLibraryFragment> b@27
        element: isPublic
          type: V
    rightParenthesis: )
  declaredFragment: <testLibraryFragment> p@12
    element: isPublic
      type: T Function<T, U>(U, V)
''');
  }

  test_simple() async {
    await resolveTestCode('''
void f(void p(int a)) {}
''');

    var node = findNode.singleFunctionTypedFormalParameter;
    assertResolvedNodeText(node, r'''
FunctionTypedFormalParameter
  returnType: NamedType
    name: void
    element: <null>
    type: void
  name: p
  parameters: FormalParameterList
    leftParenthesis: (
    parameter: SimpleFormalParameter
      type: NamedType
        name: int
        element: dart:core::@class::int
        type: int
      name: a
      declaredFragment: <testLibraryFragment> a@18
        element: isPublic
          type: int
    rightParenthesis: )
  declaredFragment: <testLibraryFragment> p@12
    element: isPublic
      type: void Function(int)
''');
  }
}
