// 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=control-flow-collections,spread-collections

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

import 'utils.dart';

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

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

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

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

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

  // If a nested maps's type is dynamic, the key and value types are dynamic.
  Expect.type<Map<dynamic, dynamic>>({1: 1, for (; false;) ...({} as dynamic)});
}

void testLoopVariableInference() {
  // Infers loop variable from iterable.
  Expect.type<List<int>>([for (var i in <int>[1]) i]);
  Expect.type<List<String>>([for (var i in <int>[1]) i.toRadixString(10)]);

  // Infers loop variable from initializer.
  Expect.type<List<int>>([for (var i = 1; i < 2; i++) i]);
  Expect.type<List<String>>([for (var i = 1; i < 2; i++) i.toRadixString(10)]);

  // Loop variable type is not pushed into iterable.
  Expect.listEquals(<int>[1], [for (int i in expectDynamic([1])) i]);

  // Loop variable type is pushed into initializer.
  Expect.listEquals(<int>[1], [for (int i = expectInt(1); i < 2; i++) i]);
}

void testTopDownInference() {
  // Lists.

  // The context element type is pushed into the body.
  Expect.listEquals(<int>[1], <int>[for (; false;) expectInt(1)]);

  // Bottom up-inference from elements is not pushed back down into the body.
  Expect.listEquals(<int>[1, 2], [1, for (; false;) expectDynamic(2)]);

  // Maps.

  // The context element type is pushed into the body.
  Expect.mapEquals(<int, String>{1: "s"},
      <int, String>{for (; false;) expectInt(1): expectString("s")});

  // Bottom up-inference from elements is not pushed back down into the body.
  Expect.mapEquals(<int, String>{1: "s", 2: "t"},
      {1: "s", for (; false;) expectDynamic(2): expectDynamic("t")});

  // Sets.

  // The context element type is pushed into the body.
  Expect.setEquals(<int>{1}, <int>{for (; false;) expectInt(1)});

  // Bottom up-inference from elements is not pushed back down into the body.
  Expect.setEquals(<int>{1, 2}, {1, for (; false;) expectDynamic(2)});
}
