blob: d31698868cc272b1bd7952620555d235835a2d16 [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.
import "package:async_helper/async_helper.dart" show asyncTest;
import "package:expect/expect.dart" show Expect;
import "package:kernel/ast.dart"
show Class, Component, DartType, InterfaceType, Library, Nullability;
import "package:kernel/core_types.dart";
import "package:kernel/library_index.dart" show LibraryIndex;
import 'package:kernel/testing/type_parser_environment.dart'
as kernel_type_parser show parseComponent;
final Uri libraryUri = Uri.parse("org-dartlang-test:///library.dart");
abstract class LegacyUpperBoundTest {
Component component;
CoreTypes coreTypes;
LibraryIndex index;
DartType get objectType => coreTypes.objectLegacyRawType;
DartType get intType => coreTypes.intLegacyRawType;
DartType get stringType => coreTypes.intLegacyRawType;
DartType get doubleType => coreTypes.doubleLegacyRawType;
DartType get boolType => coreTypes.boolLegacyRawType;
void parseComponent(String source) {
component = kernel_type_parser.parseComponent(source, libraryUri);
coreTypes = new CoreTypes(component);
index = new LibraryIndex.all(component);
}
Class getClass(String name) {
return index.getClass("$libraryUri", name);
}
Class getCoreClass(String name) {
return index.getClass("dart:core", name);
}
DartType getLegacyLeastUpperBound(
DartType a, DartType b, Library clientLibrary);
void checkGetLegacyLeastUpperBound(
DartType a, DartType b, Library clientLibrary, DartType expected) {
DartType actual = getLegacyLeastUpperBound(a, b, clientLibrary);
Expect.equals(expected, actual);
}
Future<void> test() {
return asyncTest(() async {
await test_getLegacyLeastUpperBound_expansive();
await test_getLegacyLeastUpperBound_generic();
await test_getLegacyLeastUpperBound_nonGeneric();
});
}
/// Copy of the tests/language/least_upper_bound_expansive_test.dart test.
Future<void> test_getLegacyLeastUpperBound_expansive() async {
await parseComponent("""
class N<T>;
class C1<T> extends N<N<C1<T*>*>*>;
class C2<T> extends N<N<C2<N<C2<T*>*>*>*>*>;
""");
Class N = getClass("N");
Class C1 = getClass("C1");
Class C2 = getClass("C2");
Library testLib = N.enclosingLibrary;
// The least upper bound of C1<int> and N<C1<String>> is Object since the
// supertypes are
// {C1<int>, N<N<C1<int>>>, Object} for C1<int> and
// {N<C1<String>>, Object} for N<C1<String>> and
// Object is the most specific type in the intersection of the supertypes.
checkGetLegacyLeastUpperBound(
new InterfaceType(C1, Nullability.legacy, [intType]),
new InterfaceType(N, Nullability.legacy, [
new InterfaceType(C1, Nullability.legacy, [stringType])
]),
testLib,
objectType);
// The least upper bound of C2<int> and N<C2<String>> is Object since the
// supertypes are
// {C2<int>, N<N<C2<N<C2<int>>>>>, Object} for C2<int> and
// {N<C2<String>>, Object} for N<C2<String>> and
// Object is the most specific type in the intersection of the supertypes.
checkGetLegacyLeastUpperBound(
new InterfaceType(C2, Nullability.legacy, [intType]),
new InterfaceType(N, Nullability.legacy, [
new InterfaceType(C2, Nullability.legacy, [stringType])
]),
testLib,
objectType);
}
Future<void> test_getLegacyLeastUpperBound_generic() async {
await parseComponent("""
class A;
class B<T> implements A;
class C<U> implements A;
class D<T, U> implements B<T*>, C<U*>;
class E implements D<int*, double*>;
class F implements D<int*, bool*>;
""");
Class a = getClass("A");
Class b = getClass("B");
Class c = getClass("C");
Class d = getClass("D");
Class e = getClass("E");
Class f = getClass("F");
Library testLib = a.enclosingLibrary;
checkGetLegacyLeastUpperBound(
new InterfaceType(d, Nullability.legacy, [intType, doubleType]),
new InterfaceType(d, Nullability.legacy, [intType, doubleType]),
testLib,
new InterfaceType(d, Nullability.legacy, [intType, doubleType]));
checkGetLegacyLeastUpperBound(
new InterfaceType(d, Nullability.legacy, [intType, doubleType]),
new InterfaceType(d, Nullability.legacy, [intType, boolType]),
testLib,
new InterfaceType(b, Nullability.legacy, [intType]));
checkGetLegacyLeastUpperBound(
new InterfaceType(d, Nullability.legacy, [intType, doubleType]),
new InterfaceType(d, Nullability.legacy, [boolType, doubleType]),
testLib,
new InterfaceType(c, Nullability.legacy, [doubleType]));
checkGetLegacyLeastUpperBound(
new InterfaceType(d, Nullability.legacy, [intType, doubleType]),
new InterfaceType(d, Nullability.legacy, [boolType, intType]),
testLib,
coreTypes.legacyRawType(a));
checkGetLegacyLeastUpperBound(
coreTypes.legacyRawType(e),
coreTypes.legacyRawType(f),
testLib,
new InterfaceType(b, Nullability.legacy, [intType]));
}
Future<void> test_getLegacyLeastUpperBound_nonGeneric() async {
await parseComponent("""
class A;
class B;
class C implements A;
class D implements A;
class E implements A;
class F implements C, D;
class G implements C, D;
class H implements C, D, E;
class I implements C, D, E;
""");
Class a = getClass("A");
Class b = getClass("B");
Class c = getClass("C");
Class d = getClass("D");
Class f = getClass("F");
Class g = getClass("G");
Class h = getClass("H");
Class i = getClass("I");
Library testLib = a.enclosingLibrary;
checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(a),
coreTypes.legacyRawType(b), testLib, objectType);
checkGetLegacyLeastUpperBound(
coreTypes.legacyRawType(a), objectType, testLib, objectType);
checkGetLegacyLeastUpperBound(
objectType, coreTypes.legacyRawType(b), testLib, objectType);
checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(c),
coreTypes.legacyRawType(d), testLib, coreTypes.legacyRawType(a));
checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(c),
coreTypes.legacyRawType(a), testLib, coreTypes.legacyRawType(a));
checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(a),
coreTypes.legacyRawType(d), testLib, coreTypes.legacyRawType(a));
checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(f),
coreTypes.legacyRawType(g), testLib, coreTypes.legacyRawType(a));
checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(h),
coreTypes.legacyRawType(i), testLib, coreTypes.legacyRawType(a));
}
}