| 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/ast.dart' show AstNode; | 10 import 'package:analyzer/dart/ast/ast.dart' show AstNode; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 * A list of non-nullable type names (e.g., 'int', 'bool', etc.). | 51 * A list of non-nullable type names (e.g., 'int', 'bool', etc.). |
| 52 */ | 52 */ |
| 53 final List<String> nonnullableTypes; | 53 final List<String> nonnullableTypes; |
| 54 | 54 |
| 55 final TypeProvider typeProvider; | 55 final TypeProvider typeProvider; |
| 56 | 56 |
| 57 StrongTypeSystemImpl(this.typeProvider, | 57 StrongTypeSystemImpl(this.typeProvider, |
| 58 {this.implicitCasts: true, | 58 {this.implicitCasts: true, |
| 59 this.nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES}); | 59 this.nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES}); |
| 60 | 60 |
| 61 @override |
| 62 bool get isStrong => true; |
| 63 |
| 61 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) { | 64 bool anyParameterType(FunctionType ft, bool predicate(DartType t)) { |
| 62 return ft.parameters.any((p) => predicate(p.type)); | 65 return ft.parameters.any((p) => predicate(p.type)); |
| 63 } | 66 } |
| 64 | 67 |
| 65 @override | 68 @override |
| 66 bool get isStrong => true; | |
| 67 | |
| 68 @override | |
| 69 FunctionType functionTypeToConcreteType(FunctionType t) { | 69 FunctionType functionTypeToConcreteType(FunctionType t) { |
| 70 // TODO(jmesserly): should we use a real "fuzzyArrow" bit on the function | 70 // TODO(jmesserly): should we use a real "fuzzyArrow" bit on the function |
| 71 // type? That would allow us to implement this in the subtype relation. | 71 // type? That would allow us to implement this in the subtype relation. |
| 72 // TODO(jmesserly): we'll need to factor this differently if we want to | 72 // TODO(jmesserly): we'll need to factor this differently if we want to |
| 73 // move CodeChecker's functionality into existing analyzer. Likely we can | 73 // move CodeChecker's functionality into existing analyzer. Likely we can |
| 74 // let the Expression have a strict arrow, then in places were we do | 74 // let the Expression have a strict arrow, then in places were we do |
| 75 // inference, convert back to a fuzzy arrow. | 75 // inference, convert back to a fuzzy arrow. |
| 76 | 76 |
| 77 if (!t.parameters.any((p) => p.type.isDynamic)) { | 77 if (!t.parameters.any((p) => p.type.isDynamic)) { |
| 78 return t; | 78 return t; |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 defaults[parameter] = value.substitute2( | 364 defaults[parameter] = value.substitute2( |
| 365 defaults.values.toList(), defaults.keys.toList()); | 365 defaults.values.toList(), defaults.keys.toList()); |
| 366 partials.remove(parameter); | 366 partials.remove(parameter); |
| 367 hasProgress = true; | 367 hasProgress = true; |
| 368 break; | 368 break; |
| 369 } | 369 } |
| 370 } | 370 } |
| 371 } | 371 } |
| 372 | 372 |
| 373 // If we stopped making progress, and not all types are ground, | 373 // If we stopped making progress, and not all types are ground, |
| 374 // then the whole type is malbounded and an error should be reported. | 374 // then the whole type is malbounded and an error should be reported |
| 375 // if errors are requested, and a partially completed type should |
| 376 // be returned. |
| 375 if (partials.isNotEmpty) { | 377 if (partials.isNotEmpty) { |
| 376 if (hasError != null) { | 378 if (hasError != null) { |
| 377 hasError[0] = true; | 379 hasError[0] = true; |
| 378 } | 380 } |
| 379 return instantiateType( | 381 var domain = defaults.keys.toList(); |
| 380 type, new List<DartType>.filled(count, DynamicTypeImpl.instance)); | 382 var range = defaults.values.toList(); |
| 383 // Build a substitution Phi mapping each uncompleted type variable to |
| 384 // dynamic, and each completed type variable to its default. |
| 385 for (TypeParameterType parameter in partials.keys) { |
| 386 domain.add(parameter); |
| 387 range.add(DynamicTypeImpl.instance); |
| 388 } |
| 389 // Set the default for an uncompleted type variable (T extends B) |
| 390 // to be Phi(B) |
| 391 for (TypeParameterType parameter in partials.keys) { |
| 392 defaults[parameter] = partials[parameter].substitute2(range, domain); |
| 393 } |
| 381 } | 394 } |
| 382 | 395 |
| 383 List<DartType> orderedArguments = | 396 List<DartType> orderedArguments = |
| 384 typeFormals.map((p) => defaults[p.type]).toList(); | 397 typeFormals.map((p) => defaults[p.type]).toList(); |
| 385 return instantiateType(type, orderedArguments); | 398 return instantiateType(type, orderedArguments); |
| 386 } | 399 } |
| 387 | 400 |
| 388 @override | 401 @override |
| 389 bool isAssignableTo(DartType fromType, DartType toType) { | 402 bool isAssignableTo(DartType fromType, DartType toType) { |
| 390 // TODO(leafp): Document the rules in play here | 403 // TODO(leafp): Document the rules in play here |
| (...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1701 } else { | 1714 } else { |
| 1702 passedOut = true; | 1715 passedOut = true; |
| 1703 } | 1716 } |
| 1704 } else if (type is FunctionType) { | 1717 } else if (type is FunctionType) { |
| 1705 _visitFunctionType(typeParam, type, paramIn); | 1718 _visitFunctionType(typeParam, type, paramIn); |
| 1706 } else if (type is InterfaceType) { | 1719 } else if (type is InterfaceType) { |
| 1707 _visitInterfaceType(typeParam, type, paramIn); | 1720 _visitInterfaceType(typeParam, type, paramIn); |
| 1708 } | 1721 } |
| 1709 } | 1722 } |
| 1710 } | 1723 } |
| OLD | NEW |