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

Side by Side Diff: pkg/analyzer/lib/src/generated/type_system.dart

Issue 2954523002: fix #27259, implement covariance checking for strong mode and DDC (Closed)
Patch Set: merged and fix an analysis error Created 3 years, 5 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) 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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/resolver.dart ('k') | pkg/analyzer/lib/src/task/strong/ast_properties.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698