OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 import 'dart:math' as math; | 5 import 'dart:math' as math; |
6 | 6 |
7 import 'package:front_end/src/fasta/type_inference/type_constraint_gatherer.dart
'; | 7 import 'package:front_end/src/fasta/type_inference/type_constraint_gatherer.dart
'; |
8 import 'package:front_end/src/fasta/type_inference/type_schema.dart'; | 8 import 'package:front_end/src/fasta/type_inference/type_schema.dart'; |
9 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart'
; | 9 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart'
; |
10 import 'package:kernel/ast.dart'; | 10 import 'package:kernel/ast.dart'; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 /// Modify the given [constraint]'s lower bound to include [lower]. | 42 /// Modify the given [constraint]'s lower bound to include [lower]. |
43 void addLowerBound(TypeConstraint constraint, DartType lower) { | 43 void addLowerBound(TypeConstraint constraint, DartType lower) { |
44 constraint.lower = getLeastUpperBound(constraint.lower, lower); | 44 constraint.lower = getLeastUpperBound(constraint.lower, lower); |
45 } | 45 } |
46 | 46 |
47 /// Modify the given [constraint]'s upper bound to include [upper]. | 47 /// Modify the given [constraint]'s upper bound to include [upper]. |
48 void addUpperBound(TypeConstraint constraint, DartType upper) { | 48 void addUpperBound(TypeConstraint constraint, DartType upper) { |
49 constraint.upper = getGreatestLowerBound(constraint.upper, upper); | 49 constraint.upper = getGreatestLowerBound(constraint.upper, upper); |
50 } | 50 } |
51 | 51 |
| 52 /// Implements the function "flatten" defined in the spec, where T is [type]: |
| 53 /// |
| 54 /// If T = Future<S> then flatten(T) = flatten(S). |
| 55 /// |
| 56 /// Otherwise if T <: Future then let S be a type such that T << Future<S> |
| 57 /// and for all R, if T << Future<R> then S << R. Then flatten(T) = S. |
| 58 /// |
| 59 /// In any other circumstance, flatten(T) = T. |
| 60 DartType flattenFutures(DartType type) { |
| 61 if (type is InterfaceType) { |
| 62 if (identical(type.classNode, coreTypes.futureClass)) { |
| 63 return flattenFutures(type.typeArguments[0]); |
| 64 } |
| 65 InterfaceType futureBase = |
| 66 hierarchy.getTypeAsInstanceOf(type, coreTypes.futureClass); |
| 67 if (futureBase != null) { |
| 68 return futureBase.typeArguments[0]; |
| 69 } |
| 70 } |
| 71 return type; |
| 72 } |
| 73 |
52 /// Computes the greatest lower bound of [type1] and [type2]. | 74 /// Computes the greatest lower bound of [type1] and [type2]. |
53 DartType getGreatestLowerBound(DartType type1, DartType type2) { | 75 DartType getGreatestLowerBound(DartType type1, DartType type2) { |
54 // The greatest lower bound relation is reflexive. Note that we don't test | 76 // The greatest lower bound relation is reflexive. Note that we don't test |
55 // for equality because we don't want to make the algorithm quadratic. This | 77 // for equality because we don't want to make the algorithm quadratic. This |
56 // is ok because the check is not needed for correctness; it's just a speed | 78 // is ok because the check is not needed for correctness; it's just a speed |
57 // optimization. | 79 // optimization. |
58 if (identical(type1, type2)) { | 80 if (identical(type1, type2)) { |
59 return type1; | 81 return type1; |
60 } | 82 } |
61 | 83 |
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 Substitution.fromMap({type2.parameter: objectType}).substituteType( | 732 Substitution.fromMap({type2.parameter: objectType}).substituteType( |
711 type2.parameter.bound)); | 733 type2.parameter.bound)); |
712 } else { | 734 } else { |
713 // We should only be called when at least one of the types is a | 735 // We should only be called when at least one of the types is a |
714 // TypeParameterType | 736 // TypeParameterType |
715 assert(false); | 737 assert(false); |
716 return const DynamicType(); | 738 return const DynamicType(); |
717 } | 739 } |
718 } | 740 } |
719 } | 741 } |
OLD | NEW |