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

Side by Side Diff: pkg/kernel/lib/type_environment.dart

Issue 2900113002: Implement subtyping rules for FutureOr in kernel. (Closed)
Patch Set: Created 3 years, 7 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.type_environment; 4 library kernel.type_environment;
5 5
6 import 'ast.dart'; 6 import 'ast.dart';
7 import 'class_hierarchy.dart'; 7 import 'class_hierarchy.dart';
8 import 'core_types.dart'; 8 import 'core_types.dart';
9 import 'type_algebra.dart'; 9 import 'type_algebra.dart';
10 10
11 typedef void ErrorHandler(TreeNode node, String message); 11 typedef void ErrorHandler(TreeNode node, String message);
12 12
13 class TypeEnvironment extends SubtypeTester { 13 class TypeEnvironment extends SubtypeTester {
14 final CoreTypes coreTypes; 14 final CoreTypes coreTypes;
15 final ClassHierarchy hierarchy; 15 final ClassHierarchy hierarchy;
16 InterfaceType thisType; 16 InterfaceType thisType;
17 17
18 DartType returnType; 18 DartType returnType;
19 DartType yieldType; 19 DartType yieldType;
20 AsyncMarker currentAsyncMarker = AsyncMarker.Sync; 20 AsyncMarker currentAsyncMarker = AsyncMarker.Sync;
21 21
22 /// An error handler for use in debugging, or `null` if type errors should not 22 /// An error handler for use in debugging, or `null` if type errors should not
23 /// be tolerated. See [typeError]. 23 /// be tolerated. See [typeError].
24 ErrorHandler errorHandler; 24 ErrorHandler errorHandler;
25 25
26 TypeEnvironment(this.coreTypes, this.hierarchy); 26 TypeEnvironment(this.coreTypes, this.hierarchy);
27 27
28 @override
29 bool get strongMode => false;
30
28 InterfaceType get objectType => coreTypes.objectClass.rawType; 31 InterfaceType get objectType => coreTypes.objectClass.rawType;
29 InterfaceType get nullType => coreTypes.nullClass.rawType; 32 InterfaceType get nullType => coreTypes.nullClass.rawType;
30 InterfaceType get boolType => coreTypes.boolClass.rawType; 33 InterfaceType get boolType => coreTypes.boolClass.rawType;
31 InterfaceType get intType => coreTypes.intClass.rawType; 34 InterfaceType get intType => coreTypes.intClass.rawType;
32 InterfaceType get numType => coreTypes.numClass.rawType; 35 InterfaceType get numType => coreTypes.numClass.rawType;
33 InterfaceType get doubleType => coreTypes.doubleClass.rawType; 36 InterfaceType get doubleType => coreTypes.doubleClass.rawType;
34 InterfaceType get stringType => coreTypes.stringClass.rawType; 37 InterfaceType get stringType => coreTypes.stringClass.rawType;
35 InterfaceType get symbolType => coreTypes.symbolClass.rawType; 38 InterfaceType get symbolType => coreTypes.symbolClass.rawType;
36 InterfaceType get typeType => coreTypes.typeClass.rawType; 39 InterfaceType get typeType => coreTypes.typeClass.rawType;
37 InterfaceType get rawFunctionType => coreTypes.functionClass.rawType; 40 InterfaceType get rawFunctionType => coreTypes.functionClass.rawType;
38 41
39 Class get intClass => coreTypes.intClass; 42 Class get intClass => coreTypes.intClass;
40 Class get numClass => coreTypes.numClass; 43 Class get numClass => coreTypes.numClass;
44 Class get futureOrClass => coreTypes.futureOrClass;
41 45
42 InterfaceType literalListType(DartType elementType) { 46 InterfaceType literalListType(DartType elementType) {
43 return new InterfaceType(coreTypes.listClass, <DartType>[elementType]); 47 return new InterfaceType(coreTypes.listClass, <DartType>[elementType]);
44 } 48 }
45 49
46 InterfaceType literalMapType(DartType key, DartType value) { 50 InterfaceType literalMapType(DartType key, DartType value) {
47 return new InterfaceType(coreTypes.mapClass, <DartType>[key, value]); 51 return new InterfaceType(coreTypes.mapClass, <DartType>[key, value]);
48 } 52 }
49 53
50 InterfaceType iterableType(DartType type) { 54 InterfaceType iterableType(DartType type) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 139 }
136 } 140 }
137 141
138 /// The part of [TypeEnvironment] that deals with subtype tests. 142 /// The part of [TypeEnvironment] that deals with subtype tests.
139 /// 143 ///
140 /// This lives in a separate class so it can be tested independently of the SDK. 144 /// This lives in a separate class so it can be tested independently of the SDK.
141 abstract class SubtypeTester { 145 abstract class SubtypeTester {
142 InterfaceType get objectType; 146 InterfaceType get objectType;
143 InterfaceType get rawFunctionType; 147 InterfaceType get rawFunctionType;
144 ClassHierarchy get hierarchy; 148 ClassHierarchy get hierarchy;
149 Class get futureOrClass;
150 InterfaceType futureType(DartType type);
151 bool get strongMode;
145 152
146 /// Determines if the given type is at the bottom of the type hierarchy. May 153 /// Determines if the given type is at the bottom of the type hierarchy. May
147 /// be overridden in subclasses. 154 /// be overridden in subclasses.
148 bool isBottom(DartType type) => type is BottomType; 155 bool isBottom(DartType type) => type is BottomType;
149 156
150 /// Determines if the given type is at the top of the type hierarchy. May be 157 /// Determines if the given type is at the top of the type hierarchy. May be
151 /// overridden in subclasses. 158 /// overridden in subclasses.
152 bool isTop(DartType type) => 159 bool isTop(DartType type) =>
153 type is DynamicType || type is VoidType || type == objectType; 160 type is DynamicType || type is VoidType || type == objectType;
154 161
155 /// Returns true if [subtype] is a subtype of [supertype]. 162 /// Returns true if [subtype] is a subtype of [supertype].
156 bool isSubtypeOf(DartType subtype, DartType supertype) { 163 bool isSubtypeOf(DartType subtype, DartType supertype) {
157 subtype = subtype.unalias; 164 subtype = subtype.unalias;
158 supertype = supertype.unalias; 165 supertype = supertype.unalias;
159 if (identical(subtype, supertype)) return true; 166 if (identical(subtype, supertype)) return true;
160 if (isBottom(subtype)) return true; 167 if (isBottom(subtype)) return true;
161 if (isTop(supertype)) return true; 168 if (isTop(supertype)) return true;
169
170 // Handle FutureOr<T> union type.
Paul Berry 2017/05/23 17:36:38 Note: the logic below comes from the analyzer impl
171 if (strongMode &&
172 subtype is InterfaceType &&
173 identical(subtype.classNode, futureOrClass)) {
174 var subtypeArg = subtype.typeArguments[0];
175 if (supertype is InterfaceType &&
176 identical(supertype.classNode, futureOrClass)) {
177 var supertypeArg = supertype.typeArguments[0];
178 // FutureOr<A> <: FutureOr<B> iff A <: B
179 return isSubtypeOf(subtypeArg, supertypeArg);
180 }
181
182 // given t1 is Future<A> | A, then:
183 // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
184 var subtypeFuture = futureType(subtypeArg);
185 return isSubtypeOf(subtypeFuture, supertype) &&
186 isSubtypeOf(subtypeArg, supertype);
187 }
188
189 if (strongMode &&
190 supertype is InterfaceType &&
191 identical(supertype.classNode, futureOrClass)) {
192 // given t2 is Future<A> | A, then:
193 // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
194 var supertypeArg = supertype.typeArguments[0];
195 var supertypeFuture = futureType(supertypeArg);
196 return isSubtypeOf(subtype, supertypeFuture) ||
197 isSubtypeOf(subtype, supertypeArg);
198 }
199
162 if (subtype is InterfaceType && supertype is InterfaceType) { 200 if (subtype is InterfaceType && supertype is InterfaceType) {
163 var upcastType = 201 var upcastType =
164 hierarchy.getTypeAsInstanceOf(subtype, supertype.classNode); 202 hierarchy.getTypeAsInstanceOf(subtype, supertype.classNode);
165 if (upcastType == null) return false; 203 if (upcastType == null) return false;
166 for (int i = 0; i < upcastType.typeArguments.length; ++i) { 204 for (int i = 0; i < upcastType.typeArguments.length; ++i) {
167 // Termination: the 'supertype' parameter decreases in size. 205 // Termination: the 'supertype' parameter decreases in size.
168 if (!isSubtypeOf( 206 if (!isSubtypeOf(
169 upcastType.typeArguments[i], supertype.typeArguments[i])) { 207 upcastType.typeArguments[i], supertype.typeArguments[i])) {
170 return false; 208 return false;
171 } 209 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 if (subtypeNameIndex == subtype.namedParameters.length) return false; 281 if (subtypeNameIndex == subtype.namedParameters.length) return false;
244 NamedType subtypeParameter = subtype.namedParameters[subtypeNameIndex]; 282 NamedType subtypeParameter = subtype.namedParameters[subtypeNameIndex];
245 // Termination: Both types shrink in size. 283 // Termination: Both types shrink in size.
246 if (!isSubtypeOf(supertypeParameter.type, subtypeParameter.type)) { 284 if (!isSubtypeOf(supertypeParameter.type, subtypeParameter.type)) {
247 return false; 285 return false;
248 } 286 }
249 } 287 }
250 return true; 288 return true;
251 } 289 }
252 } 290 }
OLDNEW
« no previous file with comments | « pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart ('k') | pkg/kernel/test/type_subtype_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698