// Copyright (c) 2022, 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.

// Tests that when the feature is enabled, inferred types can flow
// "horizontally" from a non-closure argument of an invocation to a closure
// argument.

// SharedOptions=--enable-experiment=inference-update-1

import '../static_type_helper.dart';

testLaterUnnamedParameter(void Function<T>(T, void Function(T)) f) {
  f(0, (x) {
    x.expectStaticType<Exactly<int>>();
  });
}

/// This special case verifies that the implementations correctly associate the
/// zeroth positional parameter with the corresponding argument (even if that
/// argument isn't in the zeroth position at the call site).
testLaterUnnamedParameterDependsOnNamedParameter(
    void Function<T>(void Function(T), {required T a}) f) {
  f(a: 0, (x) {
    x.expectStaticType<Exactly<int>>();
  });
}

testEarlierUnnamedParameter(void Function<T>(void Function(T), T) f) {
  f((x) {
    x.expectStaticType<Exactly<int>>();
  }, 0);
}

testLaterNamedParameter(
    void Function<T>({required T a, required void Function(T) b}) f) {
  f(
      a: 0,
      b: (x) {
        x.expectStaticType<Exactly<int>>();
      });
}

testEarlierNamedParameter(
    void Function<T>({required void Function(T) a, required T b}) f) {
  f(
      a: (x) {
        x.expectStaticType<Exactly<int>>();
      },
      b: 0);
}

/// This special case verifies that the implementations correctly associate the
/// zeroth positional parameter with the corresponding argument (even if that
/// argument isn't in the zeroth position at the call site).
testEarlierNamedParameterDependsOnUnnamedParameter(
    void Function<T>(T b, {required void Function(T) a}) f) {
  f(a: (x) {
    x.expectStaticType<Exactly<int>>();
  }, 0);
}

testPropagateToReturnType(U Function<T, U>(T, U Function(T)) f) {
  f(0, (x) => [x]).expectStaticType<Exactly<List<int>>>();
}

testFold(List<int> list) {
  var a = list.fold(
      0,
      (x, y) =>
          (x..expectStaticType<Exactly<int>>()) +
          (y..expectStaticType<Exactly<int>>()));
  a.expectStaticType<Exactly<int>>();
}

// The test cases below exercise situations where there are multiple closures in
// the invocation, and they need to be inferred in the right order.

testClosureAsParameterType(U Function<T, U>(T, U Function(T)) f) {
  f(() => 0, (h) => [h()]..expectStaticType<Exactly<List<int>>>())
      .expectStaticType<Exactly<List<int>>>();
}

testPropagateToEarlierClosure(U Function<T, U>(U Function(T), T Function()) f) {
  f((x) => [x]..expectStaticType<Exactly<List<int>>>(), () => 0)
      .expectStaticType<Exactly<List<int>>>();
}

testPropagateToLaterClosure(U Function<T, U>(T Function(), U Function(T)) f) {
  f(() => 0, (x) => [x]..expectStaticType<Exactly<List<int>>>())
      .expectStaticType<Exactly<List<int>>>();
}

testLongDependencyChain(
    V Function<T, U, V>(T Function(), U Function(T), V Function(U)) f) {
  f(() => [0], (x) => x.single..expectStaticType<Exactly<int>>(),
          (y) => {y}..expectStaticType<Exactly<Set<int>>>())
      .expectStaticType<Exactly<Set<int>>>();
}

testDependencyCycle(Map<T, U> Function<T, U>(T Function(U), U Function(T)) f) {
  f((x) => [x]..expectStaticType<Exactly<List<Object?>>>(),
          (y) => {y}..expectStaticType<Exactly<Set<Object?>>>())
      .expectStaticType<Exactly<Map<List<Object?>, Set<Object?>>>>();
}

testNecessaryDueToWrongExplicitParameterType(List<int> list) {
  var a = list.fold(
      0,
      (x, int y) =>
          (x..expectStaticType<Exactly<int>>()) +
          (y..expectStaticType<Exactly<int>>()));
  a.expectStaticType<Exactly<int>>();
}

testPropagateFromContravariantReturnType(
    U Function<T, U>(void Function(T) Function(), U Function(T)) f) {
  f(() => (int i) {}, (x) => [x]..expectStaticType<Exactly<List<int>>>())
      .expectStaticType<Exactly<List<int>>>();
}

testPropagateToContravariantParameterType(
    U Function<T, U>(T Function(), U Function(void Function(T))) f) {
  f(() => 0, (x) => [x]..expectStaticType<Exactly<List<void Function(int)>>>())
      .expectStaticType<Exactly<List<void Function(int)>>>();
}

testReturnTypeRefersToMultipleTypeVars(
    void Function<T, U>(
            Map<T, U> Function(), void Function(T), void Function(U))
        f) {
  f(() => {0: ''}, (k) {
    k.expectStaticType<Exactly<int>>();
  }, (v) {
    v.expectStaticType<Exactly<String>>();
  });
}

testUnnecessaryDueToNoDependency(T Function<T>(T Function(), T) f) {
  f(() => 0, null).expectStaticType<Exactly<int?>>();
}

testUnnecessaryDueToExplicitParameterType(List<int> list) {
  var a = list.fold(null, (int? x, y) => (x ?? 0) + y);
  a.expectStaticType<Exactly<int?>>();
}

testUnnecessaryDueToExplicitParameterTypeNamed(
    T Function<T>(T, T Function({required T x, required int y})) f) {
  var a = f(null, ({int? x, required y}) => (x ?? 0) + y);
  a.expectStaticType<Exactly<int?>>();
}

testParenthesized(void Function<T>(T, void Function(T)) f) {
  f(0, ((x) {
    x.expectStaticType<Exactly<int>>();
  }));
}

testParenthesizedNamed(
    void Function<T>({required T a, required void Function(T) b}) f) {
  f(
      a: 0,
      b: ((x) {
        x.expectStaticType<Exactly<int>>();
      }));
}

testParenthesizedTwice(void Function<T>(T, void Function(T)) f) {
  f(0, (((x) {
    x.expectStaticType<Exactly<int>>();
  })));
}

testParenthesizedTwiceNamed(
    void Function<T>({required T a, required void Function(T) b}) f) {
  f(
      a: 0,
      b: (((x) {
        x.expectStaticType<Exactly<int>>();
      })));
}

main() {}
