blob: 11c7b95672d46bd30c180535e48ba8d02fdf3a17 [file] [log] [blame]
// 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.
// 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)});
}