Skip to content

Commit

Permalink
Unify named and unnamed argument handling logic for invocations.
Browse files Browse the repository at this point in the history
In order to support dart-lang/language#731
(improved inference for fold etc.) I'm going to need to add logic to
_inferInvocation to postpone type analysis of arguments that are
function expressions.  To avoid having to code up this logic twice, it
will be helpful to have both named and unnamed arguments handled by
the same chunk of code.

In particular, this change unifies the computation of
inferredFormalType, the recursive call to inferExpression, the logic
for hoisting, and the update of the local variables identicalInfo,
formalTypes, and actualTypes.  We pay a small price by having to have
multiple `if (isExpression)` checks, but these should be very fast.

Change-Id: I095a7eac84237eeb878cc3dd86e76a6a871f31d5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241041
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
  • Loading branch information
stereotype441 authored and Commit Bot committed Apr 21, 2022
1 parent 28654b9 commit e63cea6
Showing 1 changed file with 56 additions and 74 deletions.
130 changes: 56 additions & 74 deletions pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2408,91 +2408,73 @@ class TypeInferrerImpl implements TypeInferrer {
argument is Expression || argument is NamedExpression,
"Expected the argument to be either an Expression "
"or a NamedExpression, got '${argument.runtimeType}'.");
if (argument is Expression) {
int index = positionalIndex++;
DartType formalType = getPositionalParameterType(calleeType, index);
DartType inferredFormalType = substitution != null
? substitution.substituteType(formalType)
: formalType;
DartType inferredType;
int index;
DartType formalType;
Expression argumentExpression;
bool isExpression = argument is Expression;
if (isExpression) {
index = positionalIndex++;
formalType = getPositionalParameterType(calleeType, index);
argumentExpression = arguments.positional[index];
} else {
index = namedIndex++;
NamedExpression namedArgument = arguments.named[index];
formalType = getNamedParameterType(calleeType, namedArgument.name);
argumentExpression = namedArgument.value;
}
DartType inferredFormalType = substitution != null
? substitution.substituteType(formalType)
: formalType;
if (isExpression) {
if (isImplicitExtensionMember && index == 0) {
assert(
receiverType != null,
"No receiver type provided for implicit extension member "
"invocation.");
continue;
} else {
if (isSpecialCasedBinaryOperator) {
inferredFormalType = typeSchemaEnvironment
.getContextTypeOfSpecialCasedBinaryOperator(
typeContext, receiverType!, inferredFormalType,
isNonNullableByDefault: isNonNullableByDefault);
} else if (isSpecialCasedTernaryOperator) {
inferredFormalType = typeSchemaEnvironment
.getContextTypeOfSpecialCasedTernaryOperator(
typeContext, receiverType!, inferredFormalType,
isNonNullableByDefault: isNonNullableByDefault);
}
ExpressionInferenceResult result = inferExpression(
arguments.positional[index],
isNonNullableByDefault
? inferredFormalType
: legacyErasure(inferredFormalType),
inferenceNeeded ||
isSpecialCasedBinaryOperator ||
isSpecialCasedTernaryOperator ||
typeChecksNeeded);
inferredType = identical(result.inferredType, noInferredType) ||
isNonNullableByDefault
? result.inferredType
: legacyErasure(result.inferredType);
if (localHoistedExpressions != null &&
evaluationOrderIndex >= hoistingEndIndex) {
hoistedExpressions = null;
}
Expression expression =
_hoist(result.expression, inferredType, hoistedExpressions);
identicalInfo
?.add(flowAnalysis.equalityOperand_end(expression, inferredType));
arguments.positional[index] = expression..parent = arguments;
}
if (useFormalAndActualTypes) {
formalTypes!.add(formalType);
actualTypes!.add(inferredType);
if (isSpecialCasedBinaryOperator) {
inferredFormalType =
typeSchemaEnvironment.getContextTypeOfSpecialCasedBinaryOperator(
typeContext, receiverType!, inferredFormalType,
isNonNullableByDefault: isNonNullableByDefault);
} else if (isSpecialCasedTernaryOperator) {
inferredFormalType =
typeSchemaEnvironment.getContextTypeOfSpecialCasedTernaryOperator(
typeContext, receiverType!, inferredFormalType,
isNonNullableByDefault: isNonNullableByDefault);
}
}
ExpressionInferenceResult result = inferExpression(
argumentExpression,
isNonNullableByDefault
? inferredFormalType
: legacyErasure(inferredFormalType),
inferenceNeeded ||
isSpecialCasedBinaryOperator ||
isSpecialCasedTernaryOperator ||
typeChecksNeeded);
DartType inferredType = identical(result.inferredType, noInferredType) ||
isNonNullableByDefault
? result.inferredType
: legacyErasure(result.inferredType);
if (localHoistedExpressions != null &&
evaluationOrderIndex >= hoistingEndIndex) {
hoistedExpressions = null;
}
Expression expression =
_hoist(result.expression, inferredType, hoistedExpressions);
identicalInfo
?.add(flowAnalysis.equalityOperand_end(expression, inferredType));
if (isExpression) {
arguments.positional[index] = expression..parent = arguments;
} else {
assert(argument is NamedExpression);
int index = namedIndex++;
NamedExpression namedArgument = arguments.named[index];
DartType formalType =
getNamedParameterType(calleeType, namedArgument.name);
DartType inferredFormalType = substitution != null
? substitution.substituteType(formalType)
: formalType;
ExpressionInferenceResult result = inferExpression(
namedArgument.value,
isNonNullableByDefault
? inferredFormalType
: legacyErasure(inferredFormalType),
inferenceNeeded ||
isSpecialCasedBinaryOperator ||
typeChecksNeeded);
DartType inferredType =
identical(result.inferredType, noInferredType) ||
isNonNullableByDefault
? result.inferredType
: legacyErasure(result.inferredType);
if (localHoistedExpressions != null &&
evaluationOrderIndex >= hoistingEndIndex) {
hoistedExpressions = null;
}
Expression expression =
_hoist(result.expression, inferredType, hoistedExpressions);
namedArgument.value = expression..parent = namedArgument;
if (useFormalAndActualTypes) {
formalTypes!.add(formalType);
actualTypes!.add(inferredType);
}
}
if (useFormalAndActualTypes) {
formalTypes!.add(formalType);
actualTypes!.add(inferredType);
}
}
if (identicalInfo != null) {
Expand Down

0 comments on commit e63cea6

Please sign in to comment.