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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 bool isNonNullableType(DartType type) { | 490 bool isNonNullableType(DartType type) { |
491 return !isNullableType(type); | 491 return !isNullableType(type); |
492 } | 492 } |
493 | 493 |
494 /// Opposite of [isNonNullableType]. | 494 /// Opposite of [isNonNullableType]. |
495 bool isNullableType(DartType type) { | 495 bool isNullableType(DartType type) { |
496 return type is FunctionType || | 496 return type is FunctionType || |
497 !nonnullableTypes.contains(_getTypeFullyQualifiedName(type)); | 497 !nonnullableTypes.contains(_getTypeFullyQualifiedName(type)); |
498 } | 498 } |
499 | 499 |
500 /// Check that [f1] is a subtype of [f2] for an override. | 500 /// Check that [f1] is a subtype of [f2] for a member override. |
501 /// | 501 /// |
502 /// This is different from the normal function subtyping in two ways: | 502 /// This is different from the normal function subtyping in two ways: |
503 /// - we know the function types are strict arrows, | 503 /// - we know the function types are strict arrows, |
504 /// - it allows opt-in covariant parameters. | 504 /// - it allows opt-in covariant parameters. |
505 bool isOverrideSubtypeOf(FunctionType f1, FunctionType f2) { | 505 bool isOverrideSubtypeOf(FunctionType f1, FunctionType f2) { |
506 return FunctionTypeImpl.relate( | 506 return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds, |
507 f1, | 507 parameterRelation: isOverrideSubtypeOfParameter); |
508 f2, | 508 } |
509 (t1, t2, t1Covariant, _) => | 509 |
510 isSubtypeOf(t2, t1) || t1Covariant && isSubtypeOf(t1, t2), | 510 /// Check that parameter [p2] is a subtype of [p1], given that we are |
511 instantiateToBounds, | 511 /// checking `f1 <: f2` where `p1` is a parameter of `f1` and `p2` is a |
512 returnRelation: isSubtypeOf); | 512 /// parameter of `f2`. |
| 513 /// |
| 514 /// Parameters are contravariant, so we must check `p2 <: p1` to |
| 515 /// determine if `f1 <: f2`. This is used by [isOverrideSubtypeOf]. |
| 516 bool isOverrideSubtypeOfParameter(ParameterElement p1, ParameterElement p2) { |
| 517 return isSubtypeOf(p2.type, p1.type) || |
| 518 p1.isCovariant && isSubtypeOf(p1.type, p2.type); |
513 } | 519 } |
514 | 520 |
515 @override | 521 @override |
516 bool isSubtypeOf(DartType leftType, DartType rightType) { | 522 bool isSubtypeOf(DartType leftType, DartType rightType) { |
517 return _isSubtypeOf(leftType, rightType, null); | 523 return _isSubtypeOf(leftType, rightType, null); |
518 } | 524 } |
519 | 525 |
520 /// Given a [type] T that may have an unknown type `?`, returns a type | 526 /// Given a [type] T that may have an unknown type `?`, returns a type |
521 /// R such that R <: T for any type substituted for `?`. | 527 /// R such that R <: T for any type substituted for `?`. |
522 /// | 528 /// |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 return InterfaceTypeImpl.computeLeastUpperBound(type1, type2) ?? | 788 return InterfaceTypeImpl.computeLeastUpperBound(type1, type2) ?? |
783 typeProvider.dynamicType; | 789 typeProvider.dynamicType; |
784 } | 790 } |
785 | 791 |
786 /// Check that [f1] is a subtype of [f2]. | 792 /// Check that [f1] is a subtype of [f2]. |
787 /// | 793 /// |
788 /// This will always assume function types use fuzzy arrows, in other words | 794 /// This will always assume function types use fuzzy arrows, in other words |
789 /// that dynamic parameters of f1 and f2 are treated as bottom. | 795 /// that dynamic parameters of f1 and f2 are treated as bottom. |
790 bool _isFunctionSubtypeOf( | 796 bool _isFunctionSubtypeOf( |
791 FunctionType f1, FunctionType f2, Set<TypeImpl> visitedTypes) { | 797 FunctionType f1, FunctionType f2, Set<TypeImpl> visitedTypes) { |
792 return FunctionTypeImpl.relate( | 798 return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds, |
793 f1, | 799 parameterRelation: (p1, p2) => _isSubtypeOf( |
794 f2, | 800 p2.type, p1.type, visitedTypes, |
795 (t1, t2, _, __) => | 801 dynamicIsBottom: true)); |
796 _isSubtypeOf(t2, t1, visitedTypes, dynamicIsBottom: true), | |
797 instantiateToBounds, | |
798 returnRelation: isSubtypeOf); | |
799 } | 802 } |
800 | 803 |
801 bool _isInterfaceSubtypeOf( | 804 bool _isInterfaceSubtypeOf( |
802 InterfaceType i1, InterfaceType i2, Set<TypeImpl> visitedTypes) { | 805 InterfaceType i1, InterfaceType i2, Set<TypeImpl> visitedTypes) { |
803 if (identical(i1, i2)) { | 806 if (identical(i1, i2)) { |
804 return true; | 807 return true; |
805 } | 808 } |
806 | 809 |
807 // Guard recursive calls | 810 // Guard recursive calls |
808 _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype = _guard( | 811 _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype = _guard( |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2169 // which is a super type of the function type. | 2172 // which is a super type of the function type. |
2170 if (t1 is InterfaceType) { | 2173 if (t1 is InterfaceType) { |
2171 t1 = _typeSystem.getCallMethodDefiniteType(t1); | 2174 t1 = _typeSystem.getCallMethodDefiniteType(t1); |
2172 if (t1 == null) return; | 2175 if (t1 == null) return; |
2173 } | 2176 } |
2174 | 2177 |
2175 if (t1 is FunctionType && t2 is FunctionType) { | 2178 if (t1 is FunctionType && t2 is FunctionType) { |
2176 FunctionTypeImpl.relate( | 2179 FunctionTypeImpl.relate( |
2177 t1, | 2180 t1, |
2178 t2, | 2181 t2, |
2179 (t1, t2, _, __) { | 2182 (t1, t2) { |
2180 _matchSubtypeOf(t2, t1, null, origin, | 2183 // TODO(jmesserly): should we flip covariance when we're relating |
2181 covariant: !covariant, dynamicIsBottom: true); | 2184 // type formal bounds? They're more like parameters. |
| 2185 matchSubtype(t1, t2); |
2182 return true; | 2186 return true; |
2183 }, | 2187 }, |
2184 _typeSystem.instantiateToBounds, | 2188 _typeSystem.instantiateToBounds, |
2185 returnRelation: (t1, t2) { | 2189 parameterRelation: (p1, p2) { |
2186 matchSubtype(t1, t2); | 2190 _matchSubtypeOf(p2.type, p1.type, null, origin, |
| 2191 covariant: !covariant, dynamicIsBottom: true); |
2187 return true; | 2192 return true; |
2188 }); | 2193 }); |
2189 } | 2194 } |
2190 } | 2195 } |
2191 | 2196 |
2192 static String _formatConstraints(Iterable<_TypeConstraint> constraints) { | 2197 static String _formatConstraints(Iterable<_TypeConstraint> constraints) { |
2193 List<List<String>> lineParts = | 2198 List<List<String>> lineParts = |
2194 new Set<_TypeConstraintOrigin>.from(constraints.map((c) => c.origin)) | 2199 new Set<_TypeConstraintOrigin>.from(constraints.map((c) => c.origin)) |
2195 .map((o) => o.formatError()) | 2200 .map((o) => o.formatError()) |
2196 .toList(); | 2201 .toList(); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2374 /// Combining these constraints results in a lower bound of `num`. | 2379 /// Combining these constraints results in a lower bound of `num`. |
2375 /// | 2380 /// |
2376 /// In general, we choose the lower bound as our inferred type, so we can | 2381 /// In general, we choose the lower bound as our inferred type, so we can |
2377 /// offer the most constrained (strongest) result type. | 2382 /// offer the most constrained (strongest) result type. |
2378 final DartType lowerBound; | 2383 final DartType lowerBound; |
2379 | 2384 |
2380 _TypeRange({DartType lower, DartType upper}) | 2385 _TypeRange({DartType lower, DartType upper}) |
2381 : lowerBound = lower ?? UnknownInferredType.instance, | 2386 : lowerBound = lower ?? UnknownInferredType.instance, |
2382 upperBound = upper ?? UnknownInferredType.instance; | 2387 upperBound = upper ?? UnknownInferredType.instance; |
2383 } | 2388 } |
OLD | NEW |