blob: c8af98e13b3a915a3ca52ff217fb8cac609808c5 [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:expect/expect.dart" show Expect;
import "package:kernel/ast.dart" show Component, DartType, Library;
import "package:kernel/class_hierarchy.dart" show ClassHierarchy;
import "package:kernel/core_types.dart" show CoreTypes;
import "package:kernel/text/ast_to_text.dart" show Printer;
import "package:kernel/type_environment.dart" show TypeEnvironment;
import "kernel_type_parser.dart"
show KernelEnvironment, KernelFromParsedType, parseLibrary;
import "mock_sdk.dart" show mockSdk;
import "shared_type_tests.dart" show SubtypeTest;
import "type_parser.dart" as type_parser show parse, parseTypeVariables;
const String testSdk = """
typedef Typedef<T> <S>(T) -> S;
typedef VoidFunction () -> void;
class DefaultTypes<S, T extends Object, U extends List<S>, V extends List<T>, W extends Comparable<W>, X extends (W) -> void, Y extends () -> W>;
typedef TestDefaultTypes () -> DefaultTypes;
typedef Id<T> T;
typedef TestSorting ({int c, int b, int a}) -> void;
class Super implements Comparable<Sub>;
class Sub extends Super;
class FBound<T extends FBound<T>>;
class MixinApplication extends Object with FBound<MixinApplication>;
""";
const String expectedSdk = """
library core;
import self as self;
typedef Typedef<T extends self::Object* = dynamic> = <S extends self::Object* = dynamic>(T*) →* S*;
typedef VoidFunction = () →* void;
typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object, self::List<dynamic>*, self::List<self::Object>*, self::Comparable<dynamic>*, (<BottomType>) →* void, () →* self::Comparable<dynamic>*>;
typedef Id<T extends self::Object* = dynamic> = T*;
typedef TestSorting = ({a: self::int, b: self::int, c: self::int}) →* void;
class Object {
}
class Comparable<T extends self::Object* = dynamic> extends self::Object {
}
class num extends self::Object implements self::Comparable<self::num> {
}
class int extends self::num {
}
class double extends self::num {
}
class Iterable<T extends self::Object* = dynamic> extends self::Object {
}
class List<T extends self::Object* = dynamic> extends self::Iterable<self::List::T*> {
}
class Future<T extends self::Object* = dynamic> extends self::Object {
}
class FutureOr<T extends self::Object* = dynamic> extends self::Object {
}
class Null extends self::Object {
}
class Function extends self::Object {
}
class String extends self::Object {
}
class bool extends self::Object {
}
class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S*> = self::List<dynamic>*, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>*, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>*, X extends (self::DefaultTypes::W) → void = (<BottomType>) →* void, Y extends () → self::DefaultTypes::W = () →* self::Comparable<dynamic>*> extends self::Object {
}
class Super extends self::Object implements self::Comparable<self::Sub> {
}
class Sub extends self::Super {
}
class FBound<T extends self::FBound<self::FBound::T> = self::FBound<dynamic>*> extends self::Object {
}
class MixinApplication = self::Object with self::FBound<self::MixinApplication> {
}
""";
Component parseSdk(Uri uri, KernelEnvironment environment) {
Library library =
parseLibrary(uri, mockSdk + testSdk, environment: environment);
StringBuffer sb = new StringBuffer();
Printer printer = new Printer(sb);
printer.writeLibraryFile(library);
Expect.stringEquals(expectedSdk, "$sb");
return new Component(libraries: <Library>[library]);
}
main() {
Uri uri = Uri.parse("dart:core");
KernelEnvironment environment = new KernelEnvironment(uri, uri);
Component component = parseSdk(uri, environment);
ClassHierarchy hierarchy = new ClassHierarchy(component);
CoreTypes coreTypes = new CoreTypes(component);
new KernelSubtypeTest(coreTypes, hierarchy, environment).run();
}
class KernelSubtypeTest extends SubtypeTest<DartType, KernelEnvironment> {
final CoreTypes coreTypes;
final ClassHierarchy hierarchy;
final KernelEnvironment environment;
KernelSubtypeTest(this.coreTypes, this.hierarchy, this.environment);
@override
bool get skipFutureOrPromotion => true;
DartType toType(String text, KernelEnvironment environment) {
return environment.kernelFromParsedType(type_parser.parse(text).single);
}
bool isSubtypeImpl(DartType subtype, DartType supertype) {
return new TypeEnvironment(coreTypes, hierarchy)
.isSubtypeOf(subtype, supertype);
}
KernelEnvironment extend(String typeParameters) {
if (typeParameters?.isEmpty ?? true) return environment;
return const KernelFromParsedType()
.computeTypeParameterEnvironment(
type_parser.parseTypeVariables("<$typeParameters>"), environment)
.environment;
}
}