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

// SharedOptions=--enable-experiment=spread-collections

// Test how spread interacts with inference.
import 'package:expect/expect.dart';

void main() {
  testBottomUpInference();
  testTopDownInference();
}

void testBottomUpInference() {
  // Lists.
  Expect.type<List<dynamic>>([...[]]);
  Expect.type<List<int>>([...<int>[]]);
  Expect.type<List<int>>([...[1]]);
  Expect.type<List<int>>([1, ...[2]]);
  Expect.type<List<num>>([1, ...[0.2]]);
  Expect.type<List<int>>([...[1, 2]]);
  Expect.type<List<num>>([...[1, 0.2]]);
  Expect.type<List<int>>([...[1], ...[2]]);
  Expect.type<List<num>>([...[1], ...[0.2]]);

  // Maps.
  Expect.type<Map<dynamic, dynamic>>({...{}});
  Expect.type<Map<int, int>>({...<int, int>{}});
  Expect.type<Map<int, int>>({...{1: 1}});
  Expect.type<Map<int, int>>({1: 1, ...{2: 2}});
  Expect.type<Map<num, num>>({1: 1, ...{0.2: 0.2}});
  Expect.type<Map<int, int>>({...{1: 1, 2: 2}});
  Expect.type<Map<num, num>>({...{1: 1, 0.2: 0.2}});
  Expect.type<Map<int, int>>({...{1: 1}, ...{2: 2}});
  Expect.type<Map<num, num>>({...{1: 1}, ...{0.2: 0.2}});

  // Sets.
  Expect.type<Set<dynamic>>({...[]});
  Expect.type<Set<int>>({...<int>[]});
  Expect.type<Set<int>>({...[1]});
  Expect.type<Set<int>>({1, ...[2]});
  Expect.type<Set<num>>({1, ...[0.2]});
  Expect.type<Set<int>>({...[1, 2]});
  Expect.type<Set<num>>({...[1, 0.2]});
  Expect.type<Set<int>>({...[1], ...[2]});
  Expect.type<Set<num>>({...[1], ...[0.2]});
  Expect.type<Set<num>>({...{1}, ...[0.2]});
  Expect.type<Set<num>>({...{1}, ...{0.2}});

  // If the iterable's type is dynamic, the element type is inferred as dynamic.
  Expect.type<List<dynamic>>([...([] as dynamic)]);
  Expect.type<Set<dynamic>>({1, ...([] as dynamic)});

  // If the iterable's type is dynamic, the key and value types are inferred as
  // dynamic.
  Expect.type<Map<dynamic, dynamic>>({1: 1, ...({} as dynamic)});
}

void testTopDownInference() {
  // Lists.
  Iterable<T> expectIntIterable<T>() {
    Expect.identical(int, T);
    return [];
  }

  Iterable<T> expectDynamicIterable<T>() {
    Expect.identical(dynamic, T);
    return [];
  }

  // The context element type is pushed into the spread expression if it is
  // Iterable<T>.
  Expect.listEquals(<int>[], <int>[...expectIntIterable()]);

  // Bottom up-inference from elements is not pushed back down into spread.
  Expect.listEquals(<int>[1], [1, ...expectDynamicIterable()]);

  // Maps.
  Map<K, V> expectIntStringMap<K, V>() {
    Expect.identical(int, K);
    Expect.identical(String, V);
    return {};
  }

  Map<K, V> expectDynamicDynamicMap<K, V>() {
    Expect.identical(dynamic, K);
    Expect.identical(dynamic, V);
    return {};
  }

  // The context element type is pushed into the spread expression if it is
  // Map<K, V>.
  Expect.mapEquals(<int, String>{}, <int, String>{...expectIntStringMap()});

  // Bottom up-inference from elements is not pushed back down into spread.
  Expect.mapEquals(<int, String>{1: "s"},
      {1: "s", ...expectDynamicDynamicMap()});

  // Sets.
  Set<T> expectIntSet<T>() {
    Expect.identical(int, T);
    return Set();
  }

  Set<T> expectDynamicSet<T>() {
    Expect.identical(dynamic, T);
    return Set();
  }

  // The context element type is pushed into the spread expression if it is
  // Iterable<T>.
  Expect.setEquals(<int>{}, <int>{...expectIntSet()});

  // Bottom up-inference from elements is not pushed back down into spread.
  Expect.setEquals(<int>{1}, {1, ...expectDynamicSet()});
}
