Skip to content

Commit 0687036

Browse files
chloestefantsovaCommit Queue
authored andcommitted
[model] Share greatest and lowest closure of type schema
The algorithms for computing the greatest and lowest closures of a type schema are shared between the Analyzer and the CFE. As a work-around for the discrepancy between the behavior of the tools, the interface of the greatest closure computation accepts the top type to be used as one of its parameters. Part of #54902 Change-Id: I378c562c39078b20c48015cdf44eb652c8d4c000 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/438660 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent b1af1bd commit 0687036

13 files changed

+107
-40
lines changed

pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1939,7 +1939,14 @@ mixin TypeAnalyzer<
19391939
// expressions.
19401940
// - Let `S` be the greatest closure of `K`.
19411941
SharedTypeView? t;
1942-
SharedTypeView s = operations.greatestClosure(schema);
1942+
// Note that the `topType` named parameter below is a work-around for the
1943+
// discrepancy between the Analyzer and the CFE and should be removed when
1944+
// the discrepancy is resolved. For details, see
1945+
// https://github.com/dart-lang/language/issues/4466.
1946+
SharedTypeView s = operations.greatestClosureOfSchema(
1947+
schema,
1948+
topType: operations.dynamicType,
1949+
);
19431950
bool allCasesSatisfyContext = true;
19441951
for (int i = 0; i < numCases; i++) {
19451952
// Stack: (Expression, i * ExpressionCase)

pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer_operations.dart

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,6 @@ abstract interface class TypeAnalyzerOperations<
181181
covariant SharedType type2,
182182
);
183183

184-
/// Returns the greatest closure of [schema] with respect to the unknown type
185-
/// (`_`).
186-
SharedTypeView greatestClosure(SharedTypeSchemaView schema);
187-
188184
/// Computes the greatest closure of a type.
189185
///
190186
/// Computing the greatest closure of a type is described here:
@@ -753,6 +749,26 @@ abstract interface class TypeAnalyzerOperations<
753749
/// * `List<_>`,
754750
/// * `_ Function(_)`.
755751
bool isKnownType(SharedTypeSchemaView typeSchema);
752+
753+
/// Computes the greatest closure of a type schema.
754+
///
755+
/// The greatest closure of a type schema is defined in
756+
/// https://github.com/dart-lang/language/blob/main/accepted/future-releases/0323-null-aware-elements/feature-specification.md
757+
///
758+
/// The [topType] parameter is needed to account for the known discrepancy in
759+
/// the implementations between the CFE and the Analyzer. For details, see
760+
/// https://github.com/dart-lang/language/issues/4466.
761+
//TODO(cstefantsova): Remove [topType] when the discrepancy is resolved.
762+
SharedTypeView greatestClosureOfSchema(
763+
SharedTypeSchemaView schema, {
764+
SharedTypeView? topType,
765+
});
766+
767+
/// Computes the least closure of a type schema.
768+
///
769+
/// The least closure of a type schema is defined in
770+
/// https://github.com/dart-lang/language/blob/main/accepted/future-releases/0323-null-aware-elements/feature-specification.md
771+
SharedTypeView leastClosureOfSchema(SharedTypeSchemaView schema);
756772
}
757773

758774
mixin TypeAnalyzerOperationsMixin<

pkg/_fe_analyzer_shared/test/mini_ast.dart

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3233,16 +3233,6 @@ class MiniAstOperations
32333233
return _glbs[query] ?? fail('Unknown glb query: $query');
32343234
}
32353235

3236-
@override
3237-
SharedTypeView greatestClosure(SharedTypeSchemaView schema) {
3238-
return SharedTypeView(
3239-
schema.unwrapTypeSchemaView<Type>().closureWithRespectToUnknown(
3240-
covariant: true,
3241-
) ??
3242-
schema.unwrapTypeSchemaView(),
3243-
);
3244-
}
3245-
32463236
@override
32473237
Type greatestClosureOfTypeInternal(
32483238
Type type,
@@ -3699,6 +3689,25 @@ class MiniAstOperations
36993689
PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(
37003690
covariant _PropertyElement property,
37013691
) => property.whyNotPromotable;
3692+
3693+
@override
3694+
SharedTypeView greatestClosureOfSchema(
3695+
SharedTypeSchemaView schema, {
3696+
SharedTypeView? topType,
3697+
}) {
3698+
return SharedTypeView(
3699+
schema.unwrapTypeSchemaView<Type>().closureWithRespectToUnknown(
3700+
covariant: true,
3701+
) ??
3702+
schema.unwrapTypeSchemaView(),
3703+
);
3704+
}
3705+
3706+
@override
3707+
SharedTypeView leastClosureOfSchema(SharedTypeSchemaView schema) {
3708+
// TODO(paulberry): Implement leastClosureOfSchema in mini ast.
3709+
throw UnimplementedError();
3710+
}
37023711
}
37033712

37043713
/// Representation of an expression or statement in the pseudo-Dart language

pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,10 @@ class AssignmentExpressionResolver {
328328
var nonNullT1 = _typeSystem.promoteToNonNull(t1);
329329
var t = _typeSystem.leastUpperBound(nonNullT1, t2);
330330
// - Let `S` be the greatest closure of `K`.
331-
var s = _typeSystem.greatestClosureOfSchema(contextType);
331+
var s =
332+
_resolver.operations
333+
.greatestClosureOfSchema(SharedTypeSchemaView(contextType))
334+
.unwrapTypeView<TypeImpl>();
332335
// If `inferenceUpdate3` is not enabled, then the type of `E` is `T`.
333336
if (!_resolver.definingLibrary.featureSet.isEnabled(
334337
Feature.inference_update_3,

pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ class BinaryExpressionResolver {
215215
var t = _typeSystem.leastUpperBound(nonNullT1, t2);
216216

217217
// - Let `S` be the greatest closure of `K`.
218-
var s = _typeSystem.greatestClosureOfSchema(contextType);
218+
var s =
219+
_resolver.operations
220+
.greatestClosureOfSchema(SharedTypeSchemaView(contextType))
221+
.unwrapTypeView<TypeImpl>();
219222

220223
DartType staticType;
221224
// If `inferenceUpdate3` is not enabled, then the type of `E` is `T`.

pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,11 +595,12 @@ class TypeSystemOperations
595595
}
596596

597597
@override
598-
SharedTypeView greatestClosure(SharedTypeSchemaView schema) {
598+
SharedTypeView greatestClosureOfSchema(
599+
SharedTypeSchemaView schema, {
600+
SharedTypeView? topType,
601+
}) {
599602
return SharedTypeView(
600-
typeSystem.greatestClosureOfSchema(
601-
schema.unwrapTypeSchemaView<TypeImpl>(),
602-
),
603+
typeSystem.greatestClosureOfSchema(schema.unwrapTypeSchemaView()),
603604
);
604605
}
605606

@@ -731,6 +732,13 @@ class TypeSystemOperations
731732
);
732733
}
733734

735+
@override
736+
SharedTypeView leastClosureOfSchema(SharedTypeSchemaView schema) {
737+
return SharedTypeView(
738+
typeSystem.leastClosureOfSchema(schema.unwrapTypeSchemaView()),
739+
);
740+
}
741+
734742
@override
735743
TypeImpl leastClosureOfTypeInternal(
736744
TypeImpl type,

pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:_fe_analyzer_shared/src/types/shared_type.dart';
56
import 'package:analyzer/dart/element/element.dart';
67
import 'package:analyzer/dart/element/nullability_suffix.dart';
78
import 'package:analyzer/dart/element/type.dart';
@@ -105,7 +106,10 @@ class FunctionExpressionResolver {
105106
// corresponding parameter in the context type schema with type
106107
// schema `K`, the parameter is given an inferred type `T` where `T`
107108
// is derived from `K` as follows.
108-
inferredType = _typeSystem.greatestClosureOfSchema(inferredType);
109+
inferredType =
110+
_resolver.operations
111+
.greatestClosureOfSchema(SharedTypeSchemaView(inferredType))
112+
.unwrapTypeView<TypeImpl>();
109113

110114
// If the greatest closure of `K` is `S` and `S` is a subtype of
111115
// `Null`, then `T` is `Object?`. Otherwise, `T` is `S`.

pkg/analyzer/lib/src/dart/resolver/record_literal_resolver.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,10 @@ class RecordLiteralResolver {
144144

145145
// Implicit cast from `dynamic`.
146146
if (contextType is! UnknownInferredType && staticType is DynamicType) {
147-
var greatestClosureOfSchema = _resolver.typeSystem
148-
.greatestClosureOfSchema(contextType);
147+
var greatestClosureOfSchema =
148+
_resolver.operations
149+
.greatestClosureOfSchema(SharedTypeSchemaView(contextType))
150+
.unwrapTypeView<TypeImpl>();
149151
if (!_resolver.typeSystem.isSubtypeOf(
150152
staticType,
151153
greatestClosureOfSchema,

pkg/analyzer/lib/src/generated/static_type_analyzer.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ class StaticTypeAnalyzer {
9595
// - Let `T` be `UP(T1, T2)`
9696
var t = _typeSystem.leastUpperBound(t1, t2);
9797
// - Let `S` be the greatest closure of `K`
98-
var s = _typeSystem.greatestClosureOfSchema(contextType);
98+
var s =
99+
_resolver.operations
100+
.greatestClosureOfSchema(SharedTypeSchemaView(contextType))
101+
.unwrapTypeView<TypeImpl>();
99102
DartType staticType;
100103
// If `inferenceUpdate3` is not enabled, then the type of `E` is `T`.
101104
if (!_resolver.definingLibrary.featureSet.isEnabled(

pkg/front_end/lib/src/compute_platform_binaries_location.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ Uri computePlatformBinariesLocation({bool forceBuildDir = false}) {
5555
new Uri.file(resolvedExecutable ?? Platform.resolvedExecutable))
5656
.resolve(".");
5757
if (vmDirectory.path.endsWith("/bin/")) {
58-
// Coverage-ignore-block(suite): Not run.
5958
// Looks like the VM is in a `/bin/` directory, so this is running from a
6059
// built SDK.
6160
return vmDirectory.resolve(forceBuildDir ? "../../" : "../lib/_internal/");

0 commit comments

Comments
 (0)