| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE.md file. |
| |
| // @dart = 2.9 |
| |
| import 'package:kernel/ast.dart' show DartType, Library, NeverType; |
| |
| import 'package:kernel/src/standard_bounds.dart'; |
| |
| import 'type_schema.dart' show UnknownType; |
| |
| import 'type_schema_elimination.dart'; |
| |
| mixin TypeSchemaStandardBounds on StandardBounds { |
| @override |
| DartType getNullabilityAwareStandardLowerBoundInternal( |
| DartType type1, DartType type2, Library clientLibrary) { |
| // - We add the axiom that `DOWN(T, _) == T` and the symmetric version. |
| // - We replace all uses of `T1 <: T2` in the `DOWN` algorithm by `S1 <: |
| // S2` where `Si` is the greatest closure of `Ti` with respect to `_`. |
| if (type1 is UnknownType) return type2; |
| if (type2 is UnknownType) return type1; |
| type1 = greatestClosure( |
| type1, coreTypes.objectNullableRawType, const NeverType.nonNullable()); |
| type2 = greatestClosure( |
| type2, coreTypes.objectNullableRawType, const NeverType.nonNullable()); |
| |
| return super.getNullabilityAwareStandardLowerBoundInternal( |
| type1, type2, clientLibrary); |
| } |
| |
| @override |
| DartType getNullabilityObliviousStandardLowerBoundInternal( |
| type1, type2, clientLibrary) { |
| // For any type T, SLB(?, T) = SLB(T, ?) = T. |
| if (type1 is UnknownType) { |
| return type2; |
| } |
| if (type2 is UnknownType) { |
| return type1; |
| } |
| return super.getNullabilityObliviousStandardLowerBoundInternal( |
| type1, type2, clientLibrary); |
| } |
| |
| @override |
| DartType getNullabilityAwareStandardUpperBoundInternal( |
| DartType type1, DartType type2, Library clientLibrary) { |
| // - We add the axiom that `UP(T, _) == T` and the symmetric version. |
| // - We replace all uses of `T1 <: T2` in the `UP` algorithm by `S1 <: S2` |
| // where `Si` is the least closure of `Ti` with respect to `_`. |
| if (type1 is UnknownType) return type2; |
| if (type2 is UnknownType) return type1; |
| type1 = leastClosure( |
| type1, coreTypes.objectNullableRawType, const NeverType.nonNullable()); |
| type2 = leastClosure( |
| type2, coreTypes.objectNullableRawType, const NeverType.nonNullable()); |
| return super.getNullabilityAwareStandardUpperBoundInternal( |
| type1, type2, clientLibrary); |
| } |
| |
| @override |
| DartType getNullabilityObliviousStandardUpperBoundInternal( |
| DartType type1, DartType type2, Library clientLibrary) { |
| // For any type T, SUB(?, T) = SUB(T, ?) = T. |
| if (type1 is UnknownType) { |
| return type2; |
| } |
| if (type2 is UnknownType) { |
| return type1; |
| } |
| return super.getNullabilityObliviousStandardUpperBoundInternal( |
| type1, type2, clientLibrary); |
| } |
| } |