Skip to content

Commit

Permalink
[analyzer][cfe] Share the constraint collecting procedures
Browse files Browse the repository at this point in the history
Part of #54902

Change-Id: I98dae68a61536cc3292f2a4f05cab22a8014486d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/392581
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
  • Loading branch information
chloestefantsova authored and Commit Queue committed Nov 1, 2024
1 parent ff3d7a1 commit 297c90b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,16 @@ abstract class TypeConstraintGenerator<

TypeConstraintGenerator({required this.inferenceUsingBoundsIsEnabled});

/// Add constraint: [lower] <: [typeParameter] <: TOP.
void addLowerConstraintForParameter(
TypeParameterStructure typeParameter, TypeStructure lower,
{required AstNode? nodeForTesting});

/// Add constraint: BOTTOM <: [typeParameter] <: [upper].
void addUpperConstraintForParameter(
TypeParameterStructure typeParameter, TypeStructure upper,
{required AstNode? nodeForTesting});

/// Returns the type arguments of the supertype of [type] that is an
/// instantiation of [typeDeclaration]. If none of the supertypes of [type]
/// are instantiations of [typeDeclaration], returns null.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ class _TypeConstraintGatherer extends TypeConstraintGenerator<Type,
case var typeVar?
when p.nullabilitySuffix == NullabilitySuffix.none &&
_typeVariablesBeingConstrained.contains(typeVar)) {
_constraints.add('$typeVar <: $q');
addUpperConstraintForParameter(typeVar, q, nodeForTesting: null);
return true;
}

Expand All @@ -609,7 +609,7 @@ class _TypeConstraintGatherer extends TypeConstraintGenerator<Type,
case var typeVar?
when q.nullabilitySuffix == NullabilitySuffix.none &&
_typeVariablesBeingConstrained.contains(typeVar)) {
_constraints.add('$p <: $typeVar');
addLowerConstraintForParameter(typeVar, p, nodeForTesting: null);
return true;
}

Expand All @@ -635,4 +635,16 @@ class _TypeConstraintGatherer extends TypeConstraintGenerator<Type,
void restoreState(TypeConstraintGeneratorState state) {
_constraints.length = state.count;
}

@override
void addUpperConstraintForParameter(TypeParameter typeParameter, Type upper,
{required Node? nodeForTesting}) {
_constraints.add('$typeParameter <: $upper');
}

@override
void addLowerConstraintForParameter(TypeParameter typeParameter, Type lower,
{required Node? nodeForTesting}) {
_constraints.add('$lower <: $typeParameter');
}
}
66 changes: 36 additions & 30 deletions pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,38 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
@override
TypeSystemOperations get typeAnalyzerOperations => _typeSystemOperations;

@override
void addLowerConstraintForParameter(
TypeParameterElement element, DartType lower,
{required AstNode? nodeForTesting}) {
GeneratedTypeConstraint<DartType, TypeParameterElement, PromotableElement>
generatedTypeConstraint = GeneratedTypeConstraint<
DartType,
TypeParameterElement,
PromotableElement>.lower(element, SharedTypeSchemaView(lower));
_constraints.add(generatedTypeConstraint);
if (dataForTesting != null && nodeForTesting != null) {
(dataForTesting!.generatedTypeConstraints[nodeForTesting] ??= [])
.add(generatedTypeConstraint);
}
}

@override
void addUpperConstraintForParameter(
TypeParameterElement element, DartType upper,
{required AstNode? nodeForTesting}) {
GeneratedTypeConstraint<DartType, TypeParameterElement, PromotableElement>
generatedTypeConstraint = GeneratedTypeConstraint<
DartType,
TypeParameterElement,
PromotableElement>.upper(element, SharedTypeSchemaView(upper));
_constraints.add(generatedTypeConstraint);
if (dataForTesting != null && nodeForTesting != null) {
(dataForTesting!.generatedTypeConstraints[nodeForTesting] ??= [])
.add(generatedTypeConstraint);
}
}

/// Returns the set of type constraints that was gathered.
Map<
TypeParameterElement,
Expand Down Expand Up @@ -148,7 +180,8 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
case var P_element?
when P_nullability == NullabilitySuffix.none &&
_typeParameters.contains(P_element)) {
_addUpper(P_element, Q, nodeForTesting: nodeForTesting);
addUpperConstraintForParameter(P_element, Q,
nodeForTesting: nodeForTesting);
return true;
}

Expand All @@ -165,7 +198,8 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
P,
_typeSystemOperations.greatestClosureOfTypeInternal(
Q_element.bound!, [..._typeParameters]))))) {
_addLower(Q_element, P, nodeForTesting: nodeForTesting);
addLowerConstraintForParameter(Q_element, P,
nodeForTesting: nodeForTesting);
return true;
}

Expand Down Expand Up @@ -343,34 +377,6 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
return false;
}

void _addLower(TypeParameterElement element, DartType lower,
{required AstNode? nodeForTesting}) {
GeneratedTypeConstraint<DartType, TypeParameterElement, PromotableElement>
generatedTypeConstraint = GeneratedTypeConstraint<
DartType,
TypeParameterElement,
PromotableElement>.lower(element, SharedTypeSchemaView(lower));
_constraints.add(generatedTypeConstraint);
if (dataForTesting != null && nodeForTesting != null) {
(dataForTesting!.generatedTypeConstraints[nodeForTesting] ??= [])
.add(generatedTypeConstraint);
}
}

void _addUpper(TypeParameterElement element, DartType upper,
{required AstNode? nodeForTesting}) {
GeneratedTypeConstraint<DartType, TypeParameterElement, PromotableElement>
generatedTypeConstraint = GeneratedTypeConstraint<
DartType,
TypeParameterElement,
PromotableElement>.upper(element, SharedTypeSchemaView(upper));
_constraints.add(generatedTypeConstraint);
if (dataForTesting != null && nodeForTesting != null) {
(dataForTesting!.generatedTypeConstraints[nodeForTesting] ??= [])
.add(generatedTypeConstraint);
}
}

/// Matches [P] against [Q], where [P] and [Q] are both function types.
///
/// If [P] is a subtype of [Q] under some constraints, the constraints making
Expand Down
42 changes: 22 additions & 20 deletions pkg/front_end/lib/src/type_inference/type_constraint_gatherer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -135,31 +135,33 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
constrainSupertype: false, treeNodeForTesting: treeNodeForTesting);
}

/// Add constraint: [lower] <: [parameter] <: TOP.
void _constrainParameterLower(StructuralParameter parameter, DartType lower,
{required TreeNode? treeNodeForTesting}) {
@override
void addLowerConstraintForParameter(
StructuralParameter parameter, DartType lower,
{required TreeNode? nodeForTesting}) {
GeneratedTypeConstraint generatedTypeConstraint =
new GeneratedTypeConstraint.lower(
parameter, new SharedTypeSchemaView(lower));
if (treeNodeForTesting != null && _inferenceResultForTesting != null) {
if (nodeForTesting != null && _inferenceResultForTesting != null) {
// Coverage-ignore-block(suite): Not run.
(_inferenceResultForTesting
.generatedTypeConstraints[treeNodeForTesting] ??= [])
(_inferenceResultForTesting.generatedTypeConstraints[nodeForTesting] ??=
[])
.add(generatedTypeConstraint);
}
_protoConstraints.add(generatedTypeConstraint);
}

/// Add constraint: BOTTOM <: [parameter] <: [upper].
void _constrainParameterUpper(StructuralParameter parameter, DartType upper,
{required TreeNode? treeNodeForTesting}) {
@override
void addUpperConstraintForParameter(
StructuralParameter parameter, DartType upper,
{required TreeNode? nodeForTesting}) {
GeneratedTypeConstraint generatedTypeConstraint =
new GeneratedTypeConstraint.upper(
parameter, new SharedTypeSchemaView(upper));
if (treeNodeForTesting != null && _inferenceResultForTesting != null) {
if (nodeForTesting != null && _inferenceResultForTesting != null) {
// Coverage-ignore-block(suite): Not run.
(_inferenceResultForTesting
.generatedTypeConstraints[treeNodeForTesting] ??= [])
(_inferenceResultForTesting.generatedTypeConstraints[nodeForTesting] ??=
[])
.add(generatedTypeConstraint);
}
_protoConstraints.add(generatedTypeConstraint);
Expand Down Expand Up @@ -255,8 +257,8 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
case StructuralParameter pParameter?
when pNullability == NullabilitySuffix.none &&
_parametersToConstrain.contains(pParameter)) {
_constrainParameterUpper(pParameter, q,
treeNodeForTesting: treeNodeForTesting);
addUpperConstraintForParameter(pParameter, q,
nodeForTesting: treeNodeForTesting);
return true;
}

Expand All @@ -273,8 +275,8 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
p,
typeOperations.greatestClosureOfTypeInternal(
qParameter.bound, _parametersToConstrain)))) {
_constrainParameterLower(qParameter, p,
treeNodeForTesting: treeNodeForTesting);
addLowerConstraintForParameter(qParameter, p,
nodeForTesting: treeNodeForTesting);
return true;
}

Expand Down Expand Up @@ -526,17 +528,17 @@ class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
"Unsupported type '${type.runtimeType}'."));
for (GeneratedTypeConstraint constraint in constraints) {
if (constraint.isUpper) {
_constrainParameterUpper(
addUpperConstraintForParameter(
constraint.typeParameter,
eliminator.eliminateToLeast(
constraint.constraint.unwrapTypeSchemaView()),
treeNodeForTesting: treeNodeForTesting);
nodeForTesting: treeNodeForTesting);
} else {
_constrainParameterLower(
addLowerConstraintForParameter(
constraint.typeParameter,
eliminator.eliminateToGreatest(
constraint.constraint.unwrapTypeSchemaView()),
treeNodeForTesting: treeNodeForTesting);
nodeForTesting: treeNodeForTesting);
}
}
return true;
Expand Down

0 comments on commit 297c90b

Please sign in to comment.