// 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();
  testTopDownInference();
}

void testBottomUpInference() {
  // Lists.
  expectListOf<int>([if (true) 1]);
  expectListOf<int>([if (true) 1 else 2]);
  expectListOf<num>([if (true) 1 else 0.2]);
  expectListOf<int>([if (true) 1, 2]);
  expectListOf<num>([if (true) 1, 0.2]);
  expectListOf<dynamic>([if (true) ...[]]);
  expectListOf<int>([if (true) ...<int>[]]);

  // Maps.
  expectMapOf<int, int>({if (true) 1: 1});
  expectMapOf<int, int>({if (true) 1: 1 else 2: 2});
  expectMapOf<num, num>({if (true) 1: 0.1 else 0.2: 2});
  expectMapOf<int, int>({if (true) 1: 1, 2: 2});
  expectMapOf<num, num>({if (true) 1: 0.1, 0.2: 2});
  expectMapOf<dynamic, dynamic>({if (true) ...{}});
  expectMapOf<int, int>({if (true) ...<int, int>{}});

  // Sets.
  expectSetOf<int>({if (true) 1});
  expectSetOf<int>({if (true) 1 else 2});
  expectSetOf<num>({if (true) 1 else 0.2});
  expectSetOf<int>({if (true) 1, 2});
  expectSetOf<num>({if (true) 1, 0.2});
  expectSetOf<dynamic>({if (true) ...[]});
  expectSetOf<int>({if (true) ...<int>[]});

  // If a nested iterable's type is dynamic, the element type is dynamic.
  expectListOf<dynamic>([if (true) ...([] as dynamic)]);
  expectSetOf<dynamic>({1, if (true) ...([] as dynamic)});

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

void testTopDownInference() {
  // Lists.

  // The context element type is pushed into the branches.
  Expect.listEquals(<int>[1], <int>[if (true) expectInt(1)]);
  Expect.listEquals(<int>[1], <int>[if (false) 9 else expectInt(1)]);

  // Bottom up-inference from elements is not pushed back down into branches.
  Expect.listEquals(<int>[1, 2], [1, if (true) expectDynamic(2)]);
  Expect.listEquals(<int>[1, 2], [1, if (false) 9 else expectDynamic(2)]);

  // Maps.

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

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

  // Sets.

  // The context element type is pushed into the branches.
  Expect.setEquals(<int>{1}, <int>{if (true) expectInt(1)});
  Expect.setEquals(<int>{1}, <int>{if (false) 9 else expectInt(1)});

  // Bottom up-inference from elements is not pushed back down into branches.
  Expect.setEquals(<int>{1, 2}, {1, if (true) expectDynamic(2)});
  Expect.setEquals(<int>{1, 2}, {1, if (false) 9 else expectDynamic(2)});
}
