[front_end] Add withArguments to Template class.

The CFE `Template` class now exposes a `withArguments` method, which
behaves the same as `withArgumetsOld` method, but accepts named
arguments rather than positional arguments.

In follow-up CLs, I will adjust the names of these positional
parameters to be more descriptive, and update call sites to use
`withArguments` rather than `withArgumentsOld`. This should make the
call sites clearer and easier to understand.

Change-Id: I6a6a6964638e0312003aa622c5e0fef782b8d979
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447963
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
Paul Berry
2025-09-02 11:47:57 -07:00
committed by Commit Queue
parent 8e608e8050
commit dbdfb1eb60
14 changed files with 5603 additions and 3993 deletions
@@ -107,20 +107,23 @@ class MessageCode extends Code implements Message {
}
}
class Template<T> extends Code {
class Template<TOld extends Function, T extends Function> extends Code {
String get messageCode => name;
final String problemMessageTemplate;
final String? correctionMessageTemplate;
final T withArgumentsOld;
final TOld withArgumentsOld;
final T withArguments;
const Template(
super.name, {
this.correctionMessageTemplate,
required this.problemMessageTemplate,
required this.withArgumentsOld,
required this.withArguments,
super.index = -1,
super.analyzerCodes,
super.severity = CfeSeverity.error,
File diff suppressed because it is too large Load Diff
@@ -10,7 +10,7 @@ class BlockKind {
final codes.Message? message;
final codes.Template<codes.Message Function(Token token)>? template;
final codes.Template<codes.Message Function(Token token), Function>? template;
const BlockKind._(this.name, {this.template, this.message});
@@ -289,7 +289,7 @@ abstract class IdentifierContext {
/// expressions are required.
final bool allowedInConstantExpression;
final Template<_MessageWithArgument<Token>> recoveryTemplate;
final Template<_MessageWithArgument<Token>, Function> recoveryTemplate;
const IdentifierContext(
this._name, {
@@ -4609,7 +4609,7 @@ class Parser {
Token ensureBlock(Token token, BlockKind? missingBlockKind) {
Token next = token.next!;
if (next.isA(TokenType.OPEN_CURLY_BRACKET)) return next;
codes.Template<codes.Message Function(Token token)>? template =
codes.Template<codes.Message Function(Token token), Function>? template =
missingBlockKind?.template;
if (template == null) {
codes.Message? message = missingBlockKind?.message;
@@ -10795,7 +10795,7 @@ class Parser {
void reportRecoverableErrorWithToken(
Token token,
codes.Template<_MessageWithArgument<Token>> template,
codes.Template<_MessageWithArgument<Token>, Function> template,
) {
// Find a non-synthetic token on which to report the error.
token = findNonZeroLengthToken(token);
@@ -303,9 +303,8 @@ abstract class NamedTypeBuilderImpl extends NamedTypeBuilder {
if (member is TypeDeclarationBuilder) {
bind(problemReporting, member);
} else {
Template<Message Function(String name)> template = member == null
? codeTypeNotFound
: codeNotAType;
Template<Message Function(String name), Function> template =
member == null ? codeTypeNotFound : codeNotAType;
String nameText = typeName.fullName;
int nameOffset = typeName.fullNameOffset;
int nameLength = typeName.fullNameLength;
@@ -459,7 +458,7 @@ abstract class NamedTypeBuilderImpl extends NamedTypeBuilder {
}
Supertype? _handleInvalidSupertype(LibraryBuilder library) {
Template<Message Function(String name)> template =
Template<Message Function(String name), Function> template =
declaration.isTypeParameter
? codeSupertypeIsTypeParameter
: codeSupertypeIsIllegal;
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -180,7 +180,7 @@ class DillLoader extends Loader {
_logSummary(outlineSummaryTemplate);
}
void _logSummary(Template<SummaryTemplate> template) {
void _logSummary(Template<SummaryTemplate, Function> template) {
ticker.log(
// Coverage-ignore(suite): Not run.
(Duration elapsed, Duration sinceStart) {
@@ -314,7 +314,7 @@ severity: $severity
return formattedMessage;
}
Template<SummaryTemplate> get outlineSummaryTemplate =>
Template<SummaryTemplate, Function> get outlineSummaryTemplate =>
codeDillOutlineSummary;
/// Append compiled libraries from the given [component]. If the [filter] is
@@ -830,7 +830,7 @@ class BodyBuilder extends StackListenerImpl
void wrapVariableInitializerInError(
VariableDeclaration variable,
Template<Message Function(String name)> template,
Template<Message Function(String name), Function> template,
List<LocatedMessage> context,
) {
String name = variable.name!;
@@ -10654,7 +10654,7 @@ class BodyBuilder extends StackListenerImpl
Statement problem;
bool isBreak = keyword.isA(Keyword.BREAK);
if (name != null) {
Template<Message Function(String)> template = isBreak
Template<Message Function(String), Function> template = isBreak
? cfe.codeBreakTargetOutsideFunction
: cfe.codeContinueTargetOutsideFunction;
problem = buildProblemStatement(
@@ -143,7 +143,10 @@ abstract class DelayedGetterSetterCheck implements DelayedCheck {
],
);
} else if (getterIsDeclared) {
Template<Message Function(DartType, String, DartType, String)>
Template<
Message Function(DartType, String, DartType, String),
Function
>
template = codeInvalidGetterSetterTypeSetterInheritedGetter;
if (getterIsField) {
template = codeInvalidGetterSetterTypeSetterInheritedField;
@@ -165,9 +168,12 @@ abstract class DelayedGetterSetterCheck implements DelayedCheck {
],
);
} else if (setterIsDeclared) {
Template<Message Function(DartType, String, DartType, String)>
Template<
Message Function(DartType, String, DartType, String),
Function
>
template = codeInvalidGetterSetterTypeGetterInherited;
Template<Message Function(String)> context =
Template<Message Function(String), Function> context =
codeInvalidGetterSetterTypeGetterContext;
if (getterIsField) {
template = codeInvalidGetterSetterTypeFieldInherited;
@@ -190,9 +196,12 @@ abstract class DelayedGetterSetterCheck implements DelayedCheck {
],
);
} else {
Template<Message Function(DartType, String, DartType, String)>
Template<
Message Function(DartType, String, DartType, String),
Function
>
template = codeInvalidGetterSetterTypeBothInheritedGetter;
Template<Message Function(String)> context =
Template<Message Function(String), Function> context =
codeInvalidGetterSetterTypeGetterContext;
if (getterIsField) {
template = codeInvalidGetterSetterTypeBothInheritedField;
@@ -2453,7 +2453,7 @@ class OutlineBuilder extends StackListenerImpl {
kind = ProcedureKind.Operator;
int requiredArgumentCount = operator.requiredArgumentCount;
if ((formals?.length ?? 0) != requiredArgumentCount) {
Template<Message Function(String name)> template;
Template<Message Function(String name), Function> template;
switch (requiredArgumentCount) {
case 0:
template = codeOperatorParameterMismatch0;
@@ -851,7 +851,7 @@ class SourceLoader extends Loader {
logSummary(codeSourceBodySummary);
}
void logSummary(Template<SummaryTemplate> template) {
void logSummary(Template<SummaryTemplate, Function> template) {
ticker.log(
// Coverage-ignore(suite): Not run.
(Duration elapsed, Duration sinceStart) {
@@ -1052,7 +1052,7 @@ severity: $severity
ClassMembersBuilder get membersBuilder => _membersBuilder!;
Template<SummaryTemplate> get outlineSummaryTemplate =>
Template<SummaryTemplate, Function> get outlineSummaryTemplate =>
codeSourceOutlineSummary;
/// The [SourceCompilationUnit]s for the `dart:` libraries that are not
@@ -2314,7 +2314,7 @@ severity: $severity
return;
}
}
final Template<Message Function(String, String)> template =
final Template<Message Function(String, String), Function> template =
cls.isMixinDeclaration
? codeMixinSubtypeOfFinalIsNotBase
: codeSubtypeOfFinalIsNotBaseFinalOrSealed;
@@ -2328,7 +2328,7 @@ severity: $severity
cls.fileUri,
);
} else if (baseOrFinalSuperClass.isBase) {
final Template<Message Function(String, String)> template =
final Template<Message Function(String, String), Function> template =
cls.isMixinDeclaration
? codeMixinSubtypeOfBaseIsNotBase
: codeSubtypeOfBaseIsNotBaseFinalOrSealed;
@@ -2484,7 +2484,7 @@ severity: $severity
if (checkedClass.isBase && !cls.cls.isAnonymousMixin) {
// Report an error for a class implementing a base class outside
// of its library.
final Template<Message Function(String)> template =
final Template<Message Function(String), Function> template =
checkedClass.isMixinDeclaration
? codeBaseMixinImplementedOutsideOfLibrary
: codeBaseClassImplementedOutsideOfLibrary;
@@ -2502,7 +2502,7 @@ severity: $severity
} else if (checkedClass.isFinal) {
// Report an error for a class implementing a final class
// outside of its library.
final Template<Message Function(String)> template =
final Template<Message Function(String), Function> template =
cls.cls.isAnonymousMixin &&
checkedClass == interfaceDeclaration
? codeFinalClassUsedAsMixinConstraintOutsideOfLibrary
@@ -3577,7 +3577,7 @@ class _CheckSuperAccess extends RecursiveVisitor {
void _checkMember(
Name name, {
required Template<Message Function(String name)> template,
required Template<Message Function(String name), Function> template,
required bool isSetter,
required int accessFileOffset,
}) {
@@ -385,7 +385,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
DartType? runtimeCheckedType,
bool isVoidAllowed = false,
bool coerceExpression = true,
Template<Message Function(DartType, DartType)>? errorTemplate,
Template<Message Function(DartType, DartType), Function>? errorTemplate,
Map<SharedTypeView, NonPromotionReason> Function()? whyNotPromoted,
}) {
return ensureAssignableResult(
@@ -421,8 +421,10 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
DartType initialContextType = runtimeCheckedType ?? contextType;
Template<Message Function(DartType, DartType)>? preciseTypeErrorTemplate =
_getPreciseTypeErrorTemplate(inferenceResult.expression);
Template<Message Function(DartType, DartType), Function>?
preciseTypeErrorTemplate = _getPreciseTypeErrorTemplate(
inferenceResult.expression,
);
AssignabilityResult assignabilityResult = _computeAssignabilityKind(
contextType,
inferenceResult.inferredType,
@@ -505,7 +507,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
DartType? runtimeCheckedType,
bool isVoidAllowed = false,
bool isCoercionAllowed = true,
Template<Message Function(DartType, DartType)>? errorTemplate,
Template<Message Function(DartType, DartType), Function>? errorTemplate,
Map<SharedTypeView, NonPromotionReason> Function()? whyNotPromoted,
}) {
errorTemplate ??= codeInvalidAssignmentError;
@@ -513,8 +515,10 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
fileOffset ??= inferenceResult.expression.fileOffset;
contextType = computeGreatestClosure(contextType);
Template<Message Function(DartType, DartType)>? preciseTypeErrorTemplate =
_getPreciseTypeErrorTemplate(inferenceResult.expression);
Template<Message Function(DartType, DartType), Function>?
preciseTypeErrorTemplate = _getPreciseTypeErrorTemplate(
inferenceResult.expression,
);
AssignabilityResult assignabilityResult = _computeAssignabilityKind(
contextType,
inferenceResult.inferredType,
@@ -653,7 +657,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
DartType? runtimeCheckedType,
bool isVoidAllowed = false,
bool coerceExpression = true,
Template<Message Function(DartType, DartType)>? errorTemplate,
Template<Message Function(DartType, DartType), Function>? errorTemplate,
Map<SharedTypeView, NonPromotionReason> Function()? whyNotPromoted,
}) {
if (coerceExpression) {
@@ -690,7 +694,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
Expression _wrapTearoffErrorExpression(
Expression expression,
DartType contextType,
Template<Message Function(String)> template,
Template<Message Function(String), Function> template,
) {
Expression errorNode =
new AsExpression(
@@ -1511,7 +1515,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
DartType receiverType,
Name name,
int fileOffset,
Template<Message Function(String, DartType)> errorTemplate,
Template<Message Function(String, DartType), Function> errorTemplate,
) {
assert(isKnown(receiverType));
if (target.isMissing) {
@@ -4888,9 +4892,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
///
/// If it is, an error message template is returned, which can be used by the
/// caller to report an invalid cast. Otherwise, `null` is returned.
Template<Message Function(DartType, DartType)>? _getPreciseTypeErrorTemplate(
Expression expression,
) {
Template<Message Function(DartType, DartType), Function>?
_getPreciseTypeErrorTemplate(Expression expression) {
if (expression is ListLiteral) {
return codeInvalidCastLiteralList;
}
@@ -5019,11 +5022,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
Name name,
Expression? wrappedExpression,
List<ExtensionAccessCandidate>? extensionAccessCandidates,
Template<Message Function(String, DartType)> missingTemplate,
Template<Message Function(String, DartType)> ambiguousTemplate,
Template<Message Function(String, DartType), Function> missingTemplate,
Template<Message Function(String, DartType), Function> ambiguousTemplate,
) {
List<LocatedMessage>? context;
Template<Message Function(String, DartType)> template = missingTemplate;
Template<Message Function(String, DartType), Function> template =
missingTemplate;
if (extensionAccessCandidates != null) {
context = extensionAccessCandidates
.map(
@@ -5370,7 +5374,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
Expression? receiver,
List<ExtensionAccessCandidate>? extensionAccessCandidates,
}) {
Template<Message Function(String, DartType)> codeMissing =
Template<Message Function(String, DartType), Function> codeMissing =
codeUndefinedGetter;
return _reportMissingOrAmbiguousMember(
fileOffset,
@@ -5395,7 +5399,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
required bool forEffect,
List<ExtensionAccessCandidate>? extensionAccessCandidates,
}) {
Template<Message Function(String, DartType)> codeMissing =
Template<Message Function(String, DartType), Function> codeMissing =
codeUndefinedSetter;
return _reportMissingOrAmbiguousMember(
fileOffset,
@@ -5416,7 +5420,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
Expression index, {
List<ExtensionAccessCandidate>? extensionAccessCandidates,
}) {
Template<Message Function(String, DartType)> codeMissing =
Template<Message Function(String, DartType), Function> codeMissing =
codeUndefinedOperator;
return _reportMissingOrAmbiguousMember(
@@ -5445,7 +5449,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
required bool forEffect,
List<ExtensionAccessCandidate>? extensionAccessCandidates,
}) {
Template<Message Function(String, DartType)> codeMissing =
Template<Message Function(String, DartType), Function> codeMissing =
codeUndefinedOperator;
return _reportMissingOrAmbiguousMember(
fileOffset,
@@ -5473,7 +5477,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
List<ExtensionAccessCandidate>? extensionAccessCandidates,
}) {
assert(binaryName != equalsName);
Template<Message Function(String, DartType)> codeMissing =
Template<Message Function(String, DartType), Function> codeMissing =
codeUndefinedOperator;
return _reportMissingOrAmbiguousMember(
fileOffset,
@@ -5499,7 +5503,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
Name unaryName, {
List<ExtensionAccessCandidate>? extensionAccessCandidates,
}) {
Template<Message Function(String, DartType)> codeMissing =
Template<Message Function(String, DartType), Function> codeMissing =
codeUndefinedOperator;
return _reportMissingOrAmbiguousMember(
fileOffset,
@@ -5764,7 +5768,7 @@ class _WhyNotPromotedVisitor
member = stubTarget;
}
propertyReference = member;
Template<Message Function(String, String)> template =
Template<Message Function(String, String), Function> template =
switch (reason.whyNotPromotable) {
PropertyNonPromotabilityReason.isNotField =>
codeFieldNotPromotedBecauseNotField,
@@ -488,6 +488,7 @@ const MessageCode code$name =
}
templateArguments.add("withArgumentsOld: _withArgumentsOld$name");
templateArguments.add("withArguments: _withArguments$name");
templateArguments.addAll(codeArguments);
String message = interpolate(problemMessage);
@@ -520,9 +521,10 @@ const MessageCode code$name =
.toList();
return new Template("""
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(${positionalParameters.join(', ')})> code$name =
const Template<Message Function(${positionalParameters.join(', ')})>(
${templateArguments.join(', ')},);
const Template<
Message Function(${positionalParameters.join(', ')}),
Message Function({${namedParameters.join(', ')}})
> code$name = const Template(${templateArguments.join(', ')},);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArguments$name({${namedParameters.join(', ')}}) {