| Index: tests/compiler/dart2js/type_substitution_test.dart
|
| diff --git a/tests/compiler/dart2js/type_substitution_test.dart b/tests/compiler/dart2js/type_substitution_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8c841cce10d38f0871e35e34b6e3364988b94b0f
|
| --- /dev/null
|
| +++ b/tests/compiler/dart2js/type_substitution_test.dart
|
| @@ -0,0 +1,183 @@
|
| +// Copyright (c) 2012, 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.
|
| +
|
| +library type_substitution_test;
|
| +
|
| +import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
|
| +import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
|
| +import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
|
| +import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
|
| +import "compiler_helper.dart";
|
| +import "parser_helper.dart";
|
| +import "dart:uri";
|
| +
|
| +DartType getElementType(compiler, String name) {
|
| + var element = findElement(compiler, name);
|
| + Expect.isNotNull(element);
|
| + if (identical(element.kind, ElementKind.CLASS)) {
|
| + element.ensureResolved(compiler);
|
| + }
|
| + return element.computeType(compiler);
|
| +}
|
| +
|
| +DartType getType(compiler, String name) {
|
| + var clazz = findElement(compiler, "Class");
|
| + clazz.ensureResolved(compiler);
|
| + var element = clazz.buildScope().lookup(buildSourceString(name));
|
| + Expect.isNotNull(element);
|
| + Expect.equals(element.kind, ElementKind.FUNCTION);
|
| + FunctionSignature signature = element.computeSignature(compiler);
|
| +
|
| + // Function signatures are used to be to provide void types (only occuring as
|
| + // as return types) and (inlined) function types (only occuring as method
|
| + // parameter types).
|
| + //
|
| + // Only a single type is used from each signature. That is, it is not the
|
| + // intention to check the whole signatures against eachother.
|
| + if (signature.requiredParameterCount == 0) {
|
| + // If parameters is empty, use return type.
|
| + return signature.returnType;
|
| + } else {
|
| + // Otherwise use the first argument type.
|
| + return signature.requiredParameters.head.computeType(compiler);
|
| + }
|
| +}
|
| +
|
| +int length(Link link) {
|
| + int count = 0;
|
| + while (!link.isEmpty) {
|
| + count++;
|
| + link = link.tail;
|
| + }
|
| + return count;
|
| +}
|
| +
|
| +/**
|
| + * Test that substitution of [parameters] by [arguments] in the type found
|
| + * through [name1] is the same as the type found through [name2].
|
| + */
|
| +bool test(compiler, arguments, parameters,
|
| + String name1, String name2) {
|
| + DartType type1 = getType(compiler, name1);
|
| + DartType type2 = getType(compiler, name2);
|
| + DartType subst = type1.subst(arguments, parameters);
|
| + print('$type1.subst($arguments,$parameters)=$subst');
|
| + Expect.equals(type2, subst,
|
| + "$type1.subst($arguments,$parameters)=$subst != $type2");
|
| +}
|
| +
|
| +
|
| +void main() {
|
| + var uri = new Uri.fromComponents(scheme: 'source');
|
| + var compiler = compilerFor(
|
| + r"""
|
| + typedef void Typedef1<X,Y>(X x1, Y y2);
|
| + typedef void Typedef2<Z>(Z z1);
|
| +
|
| + class Class<T,S> {
|
| + void void1() {}
|
| + void void2() {}
|
| + void dynamic1(dynamic a) {}
|
| + void dynamic2(dynamic b) {}
|
| + void int1(int a) {}
|
| + void int2(int a) {}
|
| + void String1(String a) {}
|
| + void String2(String a) {}
|
| + void ListInt1(List<int> a) {}
|
| + void ListInt2(List<int> b) {}
|
| + void ListT1(List<T> a) {}
|
| + void ListT2(List<int> b) {}
|
| + void ListS1(List<S> a) {}
|
| + void ListS2(List<String> b) {}
|
| + void ListListT1(List<List<T>> a) {}
|
| + void ListListT2(List<List<int>> b) {}
|
| + void ListRaw1(List a) {}
|
| + void ListRaw2(List b) {}
|
| + void ListDynamic1(List<dynamic> a) {}
|
| + void ListDynamic2(List<dynamic> b) {}
|
| + void MapIntString1(Map<T,S> a) {}
|
| + void MapIntString2(Map<int,String> b) {}
|
| + void MapTString1(Map<T,String> a) {}
|
| + void MapTString2(Map<int,String> b) {}
|
| + void MapDynamicString1(Map<dynamic,String> a) {}
|
| + void MapDynamicString2(Map<dynamic,String> b) {}
|
| + void TypeVarT1(T t1) {}
|
| + void TypeVarT2(int t2) {}
|
| + void TypeVarS1(S s1) {}
|
| + void TypeVarS2(String s2) {}
|
| + void Function1a(int a(String s1)) {}
|
| + void Function2a(int b(String s2)) {}
|
| + void Function1b(void a(T t1, S s1)) {}
|
| + void Function2b(void b(int t2, String s2)) {}
|
| + void Function1c(void a(dynamic t1, dynamic s1)) {}
|
| + void Function2c(void b(dynamic t2, dynamic s2)) {}
|
| + void Typedef1a(Typedef1<T,S> a) {}
|
| + void Typedef2a(Typedef1<int,String> b) {}
|
| + void Typedef1b(Typedef1<dynamic,dynamic> a) {}
|
| + void Typedef2b(Typedef1<dynamic,dynamic> b) {}
|
| + void Typedef1c(Typedef1 a) {}
|
| + void Typedef2c(Typedef1 b) {}
|
| + void Typedef1d(Typedef2<T> a) {}
|
| + void Typedef2d(Typedef2<int> b) {}
|
| + void Typedef1e(Typedef2<S> a) {}
|
| + void Typedef2e(Typedef2<String> b) {}
|
| + }
|
| +
|
| + void main() {}
|
| + """,
|
| + uri);
|
| + compiler.runCompiler(uri);
|
| +
|
| + DartType Class_T_S = getElementType(compiler, "Class");
|
| + Expect.isNotNull(Class_T_S);
|
| + Expect.identical(Class_T_S.kind, TypeKind.INTERFACE);
|
| + Expect.equals(2, length(Class_T_S.typeArguments));
|
| +
|
| + DartType T = Class_T_S.typeArguments.head;
|
| + Expect.isNotNull(T);
|
| + Expect.identical(T.kind, TypeKind.TYPE_VARIABLE);
|
| +
|
| + DartType S = Class_T_S.typeArguments.tail.head;
|
| + Expect.isNotNull(S);
|
| + Expect.identical(S.kind, TypeKind.TYPE_VARIABLE);
|
| +
|
| + DartType intType = getType(compiler, "int1");
|
| + Expect.isNotNull(intType);
|
| + Expect.identical(intType.kind, TypeKind.INTERFACE);
|
| +
|
| + DartType StringType = getType(compiler, "String1");
|
| + Expect.isNotNull(StringType);
|
| + Expect.identical(StringType.kind, TypeKind.INTERFACE);
|
| +
|
| + var parameters = new Link<DartType>.fromList(<DartType>[T, S]);
|
| + var arguments = new Link<DartType>.fromList(<DartType>[intType, StringType]);
|
| +
|
| + // TODO(johnniwinther): Create types directly from strings to improve test
|
| + // readability.
|
| +
|
| + test(compiler, arguments, parameters, "void1", "void2");
|
| + test(compiler, arguments, parameters, "dynamic1", "dynamic2");
|
| + test(compiler, arguments, parameters, "int1", "int2");
|
| + test(compiler, arguments, parameters, "String1", "String2");
|
| + test(compiler, arguments, parameters, "ListInt1", "ListInt2");
|
| + test(compiler, arguments, parameters, "ListT1", "ListT2");
|
| + test(compiler, arguments, parameters, "ListS1", "ListS2");
|
| + test(compiler, arguments, parameters, "ListListT1", "ListListT2");
|
| + test(compiler, arguments, parameters, "ListRaw1", "ListRaw2");
|
| + test(compiler, arguments, parameters, "ListDynamic1", "ListDynamic2");
|
| + test(compiler, arguments, parameters, "MapIntString1", "MapIntString2");
|
| + test(compiler, arguments, parameters, "MapTString1", "MapTString2");
|
| + test(compiler, arguments, parameters,
|
| + "MapDynamicString1", "MapDynamicString2");
|
| + test(compiler, arguments, parameters, "TypeVarT1", "TypeVarT2");
|
| + test(compiler, arguments, parameters, "TypeVarS1", "TypeVarS2");
|
| + test(compiler, arguments, parameters, "Function1a", "Function2a");
|
| + test(compiler, arguments, parameters, "Function1b", "Function2b");
|
| + test(compiler, arguments, parameters, "Function1c", "Function2c");
|
| + test(compiler, arguments, parameters, "Typedef1a", "Typedef2a");
|
| + test(compiler, arguments, parameters, "Typedef1b", "Typedef2b");
|
| + test(compiler, arguments, parameters, "Typedef1c", "Typedef2c");
|
| + test(compiler, arguments, parameters, "Typedef1d", "Typedef2d");
|
| + test(compiler, arguments, parameters, "Typedef1e", "Typedef2e");
|
| +}
|
|
|