| // 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 IsSubtypeOf, TypeEnvironment; |
| |
| import 'package:kernel/testing/type_parser_environment.dart' |
| show TypeParserEnvironment, parseLibrary; |
| |
| import 'package:kernel/testing/mock_sdk.dart' show mockSdk; |
| |
| import 'shared_type_tests.dart' show SubtypeTest; |
| |
| 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>; |
| class ExtendedClass; |
| class ExtendedGenericClass<X>; |
| extension Extension on ExtendedClass; |
| extension GenericExtension<Y> on ExtendedGenericClass<Y>; |
| extension TopExtension on dynamic; |
| extension GenericTopExtension<Z> on dynamic; |
| class ExtendedSubclass extends ExtendedClass; |
| """; |
| |
| 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>, (Never) → 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, 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 = (Never) → 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> { |
| } |
| class ExtendedClass extends self::Object { |
| } |
| class ExtendedGenericClass<X extends self::Object? = dynamic> extends self::Object { |
| } |
| class ExtendedSubclass extends self::ExtendedClass { |
| } |
| extension Extension on self::ExtendedClass { |
| } |
| extension GenericExtension<Y extends self::Object? = dynamic> on self::ExtendedGenericClass<Y%> { |
| } |
| extension TopExtension on dynamic { |
| } |
| extension GenericTopExtension<Z extends self::Object? = dynamic> on dynamic { |
| } |
| """; |
| |
| Component parseSdk(Uri uri, TypeParserEnvironment 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]); |
| } |
| |
| void main() { |
| Uri uri = Uri.parse("dart:core"); |
| TypeParserEnvironment environment = new TypeParserEnvironment(uri, uri); |
| Component component = parseSdk(uri, environment); |
| CoreTypes coreTypes = new CoreTypes(component); |
| ClassHierarchy hierarchy = new ClassHierarchy(component, coreTypes); |
| new KernelSubtypeTest(coreTypes, hierarchy, environment).run(); |
| } |
| |
| class KernelSubtypeTest extends SubtypeTest<DartType, TypeParserEnvironment> { |
| final CoreTypes coreTypes; |
| |
| final ClassHierarchy hierarchy; |
| |
| final TypeParserEnvironment environment; |
| |
| KernelSubtypeTest(this.coreTypes, this.hierarchy, this.environment); |
| |
| @override |
| bool get skipFutureOrPromotion => true; |
| |
| @override |
| DartType toType(String text, TypeParserEnvironment environment) { |
| return environment.parseType(text); |
| } |
| |
| @override |
| IsSubtypeOf isSubtypeImpl(DartType subtype, DartType supertype) { |
| return new TypeEnvironment(coreTypes, hierarchy) |
| .performNullabilityAwareSubtypeCheck(subtype, supertype); |
| } |
| |
| @override |
| TypeParserEnvironment extend(String? typeParameters) { |
| return environment.extendWithTypeParameters(typeParameters); |
| } |
| } |