// 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. import "package:expect/expect.dart"; R constFunction(T _) => null; C getC() => const C(constFunction); List getList() => const []; Set getSet() => const {}; Map getMap() => const {}; R Function(T) getFunction() { List list = const [constFunction]; return list[0]; } C getImplicitConstC() { List> list = const [C(constFunction)]; return list[0]; } List getImplicitConstList() { List> list = const [[]]; return list[0]; } Set getImplicitConstSet() { List> list = const [{}]; return list[0]; } Map getImplicitConstMap() { List> list = const [{}]; return list[0]; } class C { final Object fn; const C(T Function(T) this.fn); } void expectOfType(Object obj) { // An exact type test would be better, but since `Null` is a subtype of all // types that can be written in Dart 2.0, it should not matter in practice. // // (`obj.runtimeType == T` does not work for List/Map/Sets because the runtime // type is an implementation-specific subtype of those interfaces.) Expect.isTrue(obj is T, "`$obj` should be of type `$T`"); } testClassInstance() { expectOfType>(getC()); expectOfType>(getC()); expectOfType>(getC()); } testImplicitConstClassInstance() { expectOfType>(getImplicitConstC()); expectOfType>(getImplicitConstC()); expectOfType>(getImplicitConstC()); } testDownwardsClassInference() { expectOfType(getC().fn); expectOfType(getC().fn); expectOfType(getC().fn); } testList() { expectOfType>(getList()); expectOfType>(getList()); expectOfType>(getList()); } testImplicitConstList() { expectOfType>(getImplicitConstList()); expectOfType>(getImplicitConstList()); expectOfType>(getImplicitConstList()); } testImplicitConstSet() { expectOfType>(getImplicitConstSet()); expectOfType>(getImplicitConstSet()); expectOfType>(getImplicitConstSet()); } testSet() { expectOfType>(getSet()); expectOfType>(getSet()); expectOfType>(getSet()); } testMap() { expectOfType>(getMap()); expectOfType>(getMap()); expectOfType>(getMap()); expectOfType>(getMap()); expectOfType>(getMap()); expectOfType>(getMap()); } testImplicitConstMap() { expectOfType>(getImplicitConstMap()); expectOfType>(getImplicitConstMap()); expectOfType>(getImplicitConstMap()); expectOfType>(getImplicitConstMap()); expectOfType>(getImplicitConstMap()); expectOfType>(getImplicitConstMap()); } testFunction() { expectOfType(getFunction()); expectOfType(getFunction()); expectOfType(getFunction()); expectOfType(getFunction()); expectOfType(getFunction()); expectOfType(getFunction()); } /// Tests that use type inference for constants do not reference the type /// parameter. Instead, free type parameters are substituted to obtain the /// least closure (e.g. `List` becomes `List` and `R Function(T)` /// becomes `Null Function(Object?)`). main() { testClassInstance(); testImplicitConstClassInstance(); testDownwardsClassInference(); testList(); testImplicitConstList(); testSet(); testImplicitConstSet(); testMap(); testImplicitConstMap(); testFunction(); }