Chromium Code Reviews| 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 |