Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Unified Diff: pkg/analyzer/test/generated/type_system_test.dart

Issue 1442883003: generic method type parameter inference (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rebase Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/test/generated/resolver_test.dart ('k') | pkg/analyzer/test/src/context/mock_sdk.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/test/generated/type_system_test.dart
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 289249aa8c6c7170f085fdc7ce54b026c703fa85..4588d891d4c32443f7361f5df54a0d727ad4836e 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -20,6 +20,7 @@ main() {
runReflectiveTests(TypeSystemTest);
runReflectiveTests(StrongSubtypingTest);
runReflectiveTests(StrongAssignabilityTest);
+ runReflectiveTests(StrongGenericFunctionInferenceTest);
}
@reflectiveTest
@@ -296,6 +297,202 @@ class StrongAssignabilityTest {
}
@reflectiveTest
+class StrongGenericFunctionInferenceTest {
+ TypeProvider typeProvider;
+ StrongTypeSystemImpl typeSystem;
+
+ DartType get bottomType => typeProvider.bottomType;
+ InterfaceType get doubleType => typeProvider.doubleType;
+ DartType get dynamicType => typeProvider.dynamicType;
+ InterfaceType get functionType => typeProvider.functionType;
+ InterfaceType get intType => typeProvider.intType;
+ InterfaceType get iterableType => typeProvider.iterableType;
+ InterfaceType get listType => typeProvider.listType;
+ InterfaceType get numType => typeProvider.numType;
+ InterfaceType get objectType => typeProvider.objectType;
+ InterfaceType get stringType => typeProvider.stringType;
+ DartType get voidType => VoidTypeImpl.instance;
+
+ void setUp() {
+ typeProvider = new TestTypeProvider();
+ typeSystem = new StrongTypeSystemImpl();
+ }
+
+ void test_boundedByAnotherTypeParameter() {
+ // <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
+ var tFrom = _typeParameter('TFrom');
+ var tTo = _typeParameter('TTo', iterableType.substitute4([tFrom]));
+ var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+ expect(_inferCall(cast, [stringType]), [
+ stringType,
+ iterableType.substitute4([stringType])
+ ]);
+ }
+
+ void test_boundedRecursively() {
+ // class Clonable<T extends Clonable<T>>
+ ClassElementImpl clonable =
+ ElementFactory.classElement('Clonable', objectType, ['T']);
+ (clonable.typeParameters[0] as TypeParameterElementImpl).bound =
+ clonable.type;
+ // class Foo extends Clonable<Foo>
+ ClassElementImpl foo = ElementFactory.classElement('Foo', null);
+ foo.supertype = clonable.type.substitute4([foo.type]);
+
+ // <S extends Clonable<S>>
+ var s = _typeParameter('S');
+ (s.element as TypeParameterElementImpl).bound =
+ clonable.type.substitute4([s]);
+ // (S, S) -> S
+ var clone = _functionType([s], [s, s], s);
+ expect(_inferCall(clone, [foo.type, foo.type]), [foo.type]);
+
+ // Something invalid...
+ expect(_inferCall(clone, [stringType, numType]), [
+ clonable.type.substitute4([dynamicType])
+ ]);
+ }
+
+ void test_genericCastFunction() {
+ // <TFrom, TTo>(TFrom) -> TTo
+ var tFrom = _typeParameter('TFrom');
+ var tTo = _typeParameter('TTo');
+ var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+ expect(_inferCall(cast, [intType]), [intType, dynamicType]);
+ }
+
+ void test_genericCastFunctionWithUpperBound() {
+ // <TFrom, TTo extends TFrom>(TFrom) -> TTo
+ var tFrom = _typeParameter('TFrom');
+ var tTo = _typeParameter('TTo', tFrom);
+ var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+ expect(_inferCall(cast, [intType]), [intType, intType]);
+ }
+
+ void test_parametersToFunctionParam() {
+ // <T>(f(T t)) -> T
+ var t = _typeParameter('T');
+ var cast = _functionType([
+ t
+ ], [
+ _functionType([], [t], dynamicType)
+ ], t);
+ expect(
+ _inferCall(cast, [
+ _functionType([], [numType], dynamicType)
+ ]),
+ [numType]);
+ }
+
+ void test_parametersUseLeastUpperBound() {
+ // <T>(T x, T y) -> T
+ var t = _typeParameter('T');
+ var cast = _functionType([t], [t, t], t);
+ expect(_inferCall(cast, [intType, doubleType]), [numType]);
+ }
+
+ void test_parameterTypeUsesUpperBound() {
+ // <T extends num>(T) -> dynamic
+ var t = _typeParameter('T', numType);
+ var f = _functionType([t], [t], dynamicType);
+ expect(_inferCall(f, [intType]), [intType]);
+ }
+
+ void test_returnFunctionWithGenericParameter() {
+ // <T>(T -> T) -> (T -> void)
+ var t = _typeParameter('T');
+ var f = _functionType([
+ t
+ ], [
+ _functionType([], [t], t)
+ ], _functionType([], [t], voidType));
+ expect(
+ _inferCall(f, [
+ _functionType([], [numType], intType)
+ ]),
+ [numType]);
+ }
+
+ void test_returnFunctionWithGenericParameterAndReturn() {
+ // <T>(T -> T) -> (T -> T)
+ var t = _typeParameter('T');
+ var f = _functionType([
+ t
+ ], [
+ _functionType([], [t], t)
+ ], _functionType([], [t], t));
+ expect(
+ _inferCall(f, [
+ _functionType([], [numType], intType)
+ ]),
+ [numType]);
+ }
+
+ void test_returnFunctionWithGenericReturn() {
+ // <T>(T -> T) -> (() -> T)
+ var t = _typeParameter('T');
+ var f = _functionType([
+ t
+ ], [
+ _functionType([], [t], t)
+ ], _functionType([], [], t));
+ expect(
+ _inferCall(f, [
+ _functionType([], [numType], intType)
+ ]),
+ [intType]);
+ }
+
+ void test_unifyParametersToFunctionParam() {
+ // <T>(f(T t), g(T t)) -> T
+ var t = _typeParameter('T');
+ var cast = _functionType([
+ t
+ ], [
+ _functionType([], [t], dynamicType),
+ _functionType([], [t], dynamicType)
+ ], t);
+ expect(
+ _inferCall(cast, [
+ _functionType([], [intType], dynamicType),
+ _functionType([], [doubleType], dynamicType)
+ ]),
+ [dynamicType]);
+ }
+
+ void test_unusedReturnTypeIsDynamic() {
+ // <T>() -> T
+ var t = _typeParameter('T');
+ var f = _functionType([t], [], t);
+ expect(_inferCall(f, []), [dynamicType]);
+ }
+
+ void test_unusedReturnTypeWithUpperBound() {
+ // <T extends num>() -> T
+ var t = _typeParameter('T', numType);
+ var f = _functionType([t], [], t);
+ expect(_inferCall(f, []), [numType]);
+ }
+
+ FunctionTypeImpl _functionType(
+ List<DartType> typeParams, List<DartType> params, DartType result) {
+ FunctionElementImpl f = ElementFactory.functionElement8(params, result);
+ f.typeParameters =
+ new List<TypeParameterElement>.from(typeParams.map((t) => t.element));
+ return f.type = new FunctionTypeImpl(f);
+ }
+
+ List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments) {
+ FunctionType inferred = typeSystem.inferCallFromArguments(
+ typeProvider, ft, ft.parameters.map((p) => p.type).toList(), arguments);
+ return inferred.typeArguments;
+ }
+
+ TypeParameterType _typeParameter(String name, [DartType bound]) =>
+ ElementFactory.typeParameterWithType(name, bound).type;
+}
+
+@reflectiveTest
class StrongSubtypingTest {
TypeProvider typeProvider;
TypeSystem typeSystem;
« no previous file with comments | « pkg/analyzer/test/generated/resolver_test.dart ('k') | pkg/analyzer/test/src/context/mock_sdk.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698