OLD | NEW |
---|---|
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 | 4 |
5 library analyzer.src.generated.type_system; | 5 library analyzer.src.generated.type_system; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
9 | 9 |
10 import 'package:analyzer/dart/ast/token.dart' show TokenType; | 10 import 'package:analyzer/dart/ast/token.dart' show TokenType; |
11 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
12 import 'package:analyzer/dart/element/type.dart'; | 12 import 'package:analyzer/dart/element/type.dart'; |
13 import 'package:analyzer/src/dart/element/element.dart'; | 13 import 'package:analyzer/src/dart/element/element.dart'; |
14 import 'package:analyzer/src/dart/element/type.dart'; | 14 import 'package:analyzer/src/dart/element/type.dart'; |
15 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 15 import 'package:analyzer/src/generated/engine.dart' |
16 show AnalysisContext, AnalysisOptionsImpl; | |
16 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | 17 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; |
17 import 'package:analyzer/src/generated/utilities_dart.dart'; | 18 import 'package:analyzer/src/generated/utilities_dart.dart'; |
18 | 19 |
19 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited); | 20 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited); |
20 | 21 |
21 /** | 22 /** |
22 * Implementation of [TypeSystem] using the strong mode rules. | 23 * Implementation of [TypeSystem] using the strong mode rules. |
23 * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md | 24 * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md |
24 */ | 25 */ |
25 class StrongTypeSystemImpl extends TypeSystem { | 26 class StrongTypeSystemImpl extends TypeSystem { |
27 /** | |
28 * True if implicit casts should be allowed, otherwise false. | |
29 * | |
30 * This affects the behavior of [isAssignableTo]. | |
31 */ | |
32 final bool implicitCasts; | |
33 | |
34 StrongTypeSystemImpl({this.implicitCasts: true}); | |
35 | |
26 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) { | 36 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) { |
27 return ft.parameters.any((p) => predicate(p.type)); | 37 return ft.parameters.any((p) => predicate(p.type)); |
28 } | 38 } |
29 | 39 |
30 @override | 40 @override |
31 bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from); | 41 bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from); |
32 | 42 |
33 @override | 43 @override |
34 FunctionType functionTypeToConcreteType( | 44 FunctionType functionTypeToConcreteType( |
35 TypeProvider typeProvider, FunctionType t) { | 45 TypeProvider typeProvider, FunctionType t) { |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
288 // An actual subtype | 298 // An actual subtype |
289 if (isSubtypeOf(fromType, toType)) { | 299 if (isSubtypeOf(fromType, toType)) { |
290 return true; | 300 return true; |
291 } | 301 } |
292 | 302 |
293 // Don't allow implicit downcasts between function types | 303 // Don't allow implicit downcasts between function types |
294 // and call method objects, as these will almost always fail. | 304 // and call method objects, as these will almost always fail. |
295 if ((fromType is FunctionType && getCallMethodType(toType) != null) || | 305 if ((fromType is FunctionType && getCallMethodType(toType) != null) || |
296 (toType is FunctionType && getCallMethodType(fromType) != null)) { | 306 (toType is FunctionType && getCallMethodType(fromType) != null)) { |
297 return false; | 307 return false; |
298 } | 308 } |
Leaf
2016/06/11 00:24:39
I think this (and the next check) can be moved und
Jennifer Messerly
2016/06/11 00:40:38
Ah yes, great idea!
| |
299 | 309 |
300 // Don't allow a non-generic function where a generic one is expected. The | 310 // Don't allow a non-generic function where a generic one is expected. The |
301 // former wouldn't know how to handle type arguments being passed to it. | 311 // former wouldn't know how to handle type arguments being passed to it. |
302 // TODO(rnystrom): This same check also exists in FunctionTypeImpl.relate() | 312 // TODO(rnystrom): This same check also exists in FunctionTypeImpl.relate() |
303 // but we don't always reliably go through that code path. This should be | 313 // but we don't always reliably go through that code path. This should be |
304 // cleaned up to avoid the redundancy. | 314 // cleaned up to avoid the redundancy. |
305 if (fromType is FunctionType && | 315 if (fromType is FunctionType && |
306 toType is FunctionType && | 316 toType is FunctionType && |
307 fromType.typeFormals.isEmpty && | 317 fromType.typeFormals.isEmpty && |
308 toType.typeFormals.isNotEmpty) { | 318 toType.typeFormals.isNotEmpty) { |
309 return false; | 319 return false; |
310 } | 320 } |
311 | 321 |
312 // If the subtype relation goes the other way, allow the implicit downcast. | 322 if (implicitCasts) { |
313 // TODO(leafp): Emit warnings and hints for these in some way. | 323 // If the subtype relation goes the other way, allow the implicit |
314 // TODO(leafp): Consider adding a flag to disable these? Or just rely on | 324 // downcast. |
315 // --warnings-as-errors? | 325 if (isSubtypeOf(toType, fromType) || toType.isAssignableTo(fromType)) { |
316 if (isSubtypeOf(toType, fromType) || toType.isAssignableTo(fromType)) { | 326 // TODO(leafp,jmesserly): we emit warnings/hints for these in |
317 // TODO(leafp): error if type is known to be exact (literal, | 327 // src/task/strong/checker.dart, which is a bit inconsistent. That |
318 // instance creation). | 328 // code should be handled into places that use isAssignableTo, such as |
319 // TODO(leafp): Warn on composite downcast. | 329 // ErrorVerifier. |
320 // TODO(leafp): hint on object/dynamic downcast. | 330 return true; |
321 // TODO(leafp): Consider allowing assignment casts. | 331 } |
322 return true; | |
323 } | 332 } |
324 | 333 |
325 return false; | 334 return false; |
326 } | 335 } |
327 | 336 |
328 bool isGroundType(DartType t) { | 337 bool isGroundType(DartType t) { |
329 // TODO(leafp): Revisit this. | 338 // TODO(leafp): Revisit this. |
330 if (t is TypeParameterType) { | 339 if (t is TypeParameterType) { |
331 return false; | 340 return false; |
332 } | 341 } |
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1173 * [TypeParameterType], return their least upper bound in a type system | 1182 * [TypeParameterType], return their least upper bound in a type system |
1174 * specific manner. | 1183 * specific manner. |
1175 */ | 1184 */ |
1176 DartType _typeParameterLeastUpperBound( | 1185 DartType _typeParameterLeastUpperBound( |
1177 TypeProvider provider, DartType type1, DartType type2); | 1186 TypeProvider provider, DartType type1, DartType type2); |
1178 | 1187 |
1179 /** | 1188 /** |
1180 * Create either a strong mode or regular type system based on context. | 1189 * Create either a strong mode or regular type system based on context. |
1181 */ | 1190 */ |
1182 static TypeSystem create(AnalysisContext context) { | 1191 static TypeSystem create(AnalysisContext context) { |
1183 return (context.analysisOptions.strongMode) | 1192 var options = context.analysisOptions as AnalysisOptionsImpl; |
1184 ? new StrongTypeSystemImpl() | 1193 return options.strongMode |
1194 ? new StrongTypeSystemImpl(implicitCasts: options.implicitCasts) | |
1185 : new TypeSystemImpl(); | 1195 : new TypeSystemImpl(); |
1186 } | 1196 } |
1187 } | 1197 } |
1188 | 1198 |
1189 /** | 1199 /** |
1190 * Implementation of [TypeSystem] using the rules in the Dart specification. | 1200 * Implementation of [TypeSystem] using the rules in the Dart specification. |
1191 */ | 1201 */ |
1192 class TypeSystemImpl extends TypeSystem { | 1202 class TypeSystemImpl extends TypeSystem { |
1193 TypeSystemImpl(); | 1203 TypeSystemImpl(); |
1194 | 1204 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1478 } else { | 1488 } else { |
1479 passedOut = true; | 1489 passedOut = true; |
1480 } | 1490 } |
1481 } else if (type is FunctionType) { | 1491 } else if (type is FunctionType) { |
1482 _visitFunctionType(typeParam, type, paramIn); | 1492 _visitFunctionType(typeParam, type, paramIn); |
1483 } else if (type is InterfaceType) { | 1493 } else if (type is InterfaceType) { |
1484 _visitInterfaceType(typeParam, type, paramIn); | 1494 _visitInterfaceType(typeParam, type, paramIn); |
1485 } | 1495 } |
1486 } | 1496 } |
1487 } | 1497 } |
OLD | NEW |