[cfe] Use VariableInitialization in ForStatement and similar nodes
This change is similar to https://github.com/dart-lang/sdk/commit/c97e2554ee3b21b0b0146ca41be969dd8531986d, where ExpressionVariable was used in VariableGet and VariableSet. Part of https://github.com/dart-lang/sdk/issues/61572 Change-Id: Id9fa5302adcf8c773cec8478a31948b54c8393b6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/466720 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
committed by
Commit Queue
parent
b976f6c69b
commit
95df731257
@@ -3751,7 +3751,7 @@ class BodyBuilderImpl extends StackListenerImpl
|
||||
}
|
||||
}
|
||||
|
||||
List<VariableDeclaration>? _buildForLoopVariableDeclarations(
|
||||
List<VariableInitialization>? _buildForLoopVariableDeclarations(
|
||||
variableOrExpression,
|
||||
) {
|
||||
// TODO(ahe): This can be simplified now that we have the events
|
||||
@@ -3759,40 +3759,40 @@ class BodyBuilderImpl extends StackListenerImpl
|
||||
if (variableOrExpression is Generator) {
|
||||
variableOrExpression = variableOrExpression.buildForEffect();
|
||||
}
|
||||
if (variableOrExpression is VariableDeclaration) {
|
||||
if (variableOrExpression is VariableInitialization) {
|
||||
// Late for loop variables are not supported. An error has already been
|
||||
// reported by the parser.
|
||||
variableOrExpression.isLate = false;
|
||||
return <VariableDeclaration>[variableOrExpression];
|
||||
return <VariableInitialization>[variableOrExpression];
|
||||
} else if (variableOrExpression is Expression) {
|
||||
VariableDeclaration variable = new VariableDeclarationImpl.forEffect(
|
||||
variableOrExpression,
|
||||
);
|
||||
return <VariableDeclaration>[variable];
|
||||
return <VariableInitialization>[variable];
|
||||
} else if (variableOrExpression is ExpressionStatement) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
VariableDeclaration variable = new VariableDeclarationImpl.forEffect(
|
||||
variableOrExpression.expression,
|
||||
);
|
||||
return <VariableDeclaration>[variable];
|
||||
return <VariableInitialization>[variable];
|
||||
} else if (forest.isVariablesDeclaration(variableOrExpression)) {
|
||||
return forest.variablesDeclarationExtractDeclarations(
|
||||
variableOrExpression,
|
||||
);
|
||||
} else if (variableOrExpression is List<Object>) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
List<VariableDeclaration> variables = <VariableDeclaration>[];
|
||||
List<VariableInitialization> variables = <VariableInitialization>[];
|
||||
for (Object v in variableOrExpression) {
|
||||
variables.addAll(_buildForLoopVariableDeclarations(v)!);
|
||||
}
|
||||
return variables;
|
||||
} else if (variableOrExpression is PatternVariableDeclaration) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
return <VariableDeclaration>[];
|
||||
return <VariableInitialization>[];
|
||||
} else if (variableOrExpression is ParserRecovery) {
|
||||
return <VariableDeclaration>[];
|
||||
return <VariableInitialization>[];
|
||||
} else if (variableOrExpression == null) {
|
||||
return <VariableDeclaration>[];
|
||||
return <VariableInitialization>[];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -3991,7 +3991,7 @@ class BodyBuilderImpl extends StackListenerImpl
|
||||
.popNode();
|
||||
|
||||
Object? variableOrExpression = pop();
|
||||
List<VariableDeclaration>? variables;
|
||||
List<VariableInitialization>? variables;
|
||||
List<VariableDeclaration>? intermediateVariables;
|
||||
if (variableOrExpression is PatternVariableDeclaration) {
|
||||
variables = pop() as List<VariableDeclaration>; // Internal variables.
|
||||
@@ -4015,7 +4015,7 @@ class BodyBuilderImpl extends StackListenerImpl
|
||||
offsetForToken(forToken),
|
||||
patternVariableDeclaration: variableOrExpression,
|
||||
intermediateVariables: intermediateVariables!,
|
||||
variables: variables,
|
||||
variableInitializations: variables,
|
||||
condition: condition,
|
||||
updates: updates,
|
||||
body: entry,
|
||||
@@ -4110,7 +4110,7 @@ class BodyBuilderImpl extends StackListenerImpl
|
||||
.deferNode();
|
||||
|
||||
Object? variableOrExpression = pop();
|
||||
List<VariableDeclaration>? variables;
|
||||
List<VariableInitialization>? variables;
|
||||
List<VariableDeclaration>? intermediateVariables;
|
||||
if (variableOrExpression is PatternVariableDeclaration) {
|
||||
variables = pop() as List<VariableDeclaration>;
|
||||
|
||||
@@ -270,8 +270,13 @@ class IfElement extends ControlFlowElement with ControlFlowElementMixin {
|
||||
class ForElement extends ControlFlowElement
|
||||
with ControlFlowElementMixin
|
||||
implements ForElementBase {
|
||||
// May be empty, but not null.
|
||||
@override
|
||||
final List<VariableDeclaration> variables; // May be empty, but not null.
|
||||
final List<VariableInitialization> variableInitializations;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<VariableDeclaration> get variables => variableInitializations.cast();
|
||||
|
||||
@override
|
||||
Expression? condition; // May be null.
|
||||
@@ -282,8 +287,13 @@ class ForElement extends ControlFlowElement
|
||||
@override
|
||||
Expression body;
|
||||
|
||||
ForElement(this.variables, this.condition, this.updates, this.body) {
|
||||
setParents(variables, this);
|
||||
ForElement(
|
||||
this.variableInitializations,
|
||||
this.condition,
|
||||
this.updates,
|
||||
this.body,
|
||||
) {
|
||||
setParents(variableInitializations, this);
|
||||
condition?.parent = this;
|
||||
setParents(updates, this);
|
||||
body.parent = this;
|
||||
@@ -292,7 +302,7 @@ class ForElement extends ControlFlowElement
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitChildren(Visitor v) {
|
||||
visitList(variables, v);
|
||||
visitList(variableInitializations, v);
|
||||
condition?.accept(v);
|
||||
visitList(updates, v);
|
||||
body.accept(v);
|
||||
@@ -301,7 +311,7 @@ class ForElement extends ControlFlowElement
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void transformChildren(Transformer v) {
|
||||
v.transformList(variables, this);
|
||||
v.transformList(variableInitializations, this);
|
||||
if (condition != null) {
|
||||
condition = v.transform(condition!);
|
||||
condition?.parent = this;
|
||||
@@ -314,7 +324,7 @@ class ForElement extends ControlFlowElement
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void transformOrRemoveChildren(RemovingTransformer v) {
|
||||
v.transformVariableDeclarationList(variables, this);
|
||||
v.transformVariableInitializationList(variableInitializations, this);
|
||||
if (condition != null) {
|
||||
condition = v.transformOrRemoveExpression(condition!);
|
||||
condition?.parent = this;
|
||||
@@ -336,7 +346,7 @@ class ForElement extends ControlFlowElement
|
||||
}
|
||||
if (bodyEntry == null) return null;
|
||||
ForMapEntry result = new ForMapEntry(
|
||||
variables,
|
||||
variableInitializations,
|
||||
condition,
|
||||
updates,
|
||||
bodyEntry,
|
||||
@@ -354,12 +364,12 @@ class ForElement extends ControlFlowElement
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.write('for (');
|
||||
for (int index = 0; index < variables.length; index++) {
|
||||
for (int index = 0; index < variableInitializations.length; index++) {
|
||||
if (index > 0) {
|
||||
printer.write(', ');
|
||||
}
|
||||
printer.writeVariableDeclaration(
|
||||
variables[index],
|
||||
printer.writeVariableInitialization(
|
||||
variableInitializations[index],
|
||||
includeModifiersAndType: index == 0,
|
||||
);
|
||||
}
|
||||
@@ -593,6 +603,8 @@ class IfCaseElement extends ControlFlowElementImpl
|
||||
}
|
||||
|
||||
abstract interface class ForElementBase implements AuxiliaryExpression {
|
||||
List<VariableInitialization> get variableInitializations;
|
||||
|
||||
List<VariableDeclaration> get variables;
|
||||
|
||||
abstract Expression? condition;
|
||||
@@ -608,8 +620,13 @@ class PatternForElement extends ControlFlowElementImpl
|
||||
PatternVariableDeclaration patternVariableDeclaration;
|
||||
List<VariableDeclaration> intermediateVariables;
|
||||
|
||||
// May be empty, but not null.
|
||||
@override
|
||||
final List<VariableDeclaration> variables; // May be empty, but not null.
|
||||
final List<VariableInitialization> variableInitializations;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<VariableDeclaration> get variables => variableInitializations.cast();
|
||||
|
||||
@override
|
||||
Expression? condition; // May be null.
|
||||
@@ -623,11 +640,11 @@ class PatternForElement extends ControlFlowElementImpl
|
||||
PatternForElement({
|
||||
required this.patternVariableDeclaration,
|
||||
required this.intermediateVariables,
|
||||
required this.variables,
|
||||
required List<VariableInitialization> variables,
|
||||
required this.condition,
|
||||
required this.updates,
|
||||
required this.body,
|
||||
});
|
||||
}) : variableInitializations = variables;
|
||||
|
||||
@override
|
||||
ExpressionInferenceResult acceptInference(
|
||||
@@ -642,12 +659,12 @@ class PatternForElement extends ControlFlowElementImpl
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
patternVariableDeclaration.toTextInternal(printer);
|
||||
printer.write('for (');
|
||||
for (int index = 0; index < variables.length; index++) {
|
||||
for (int index = 0; index < variableInitializations.length; index++) {
|
||||
if (index > 0) {
|
||||
printer.write(', ');
|
||||
}
|
||||
printer.writeVariableDeclaration(
|
||||
variables[index],
|
||||
printer.writeVariableInitialization(
|
||||
variableInitializations[index],
|
||||
includeModifiersAndType: index == 0,
|
||||
);
|
||||
}
|
||||
@@ -893,6 +910,8 @@ class IfMapEntry extends TreeNode
|
||||
}
|
||||
|
||||
abstract interface class ForMapEntryBase implements TreeNode, MapLiteralEntry {
|
||||
List<VariableInitialization> get variableInitializations;
|
||||
|
||||
List<VariableDeclaration> get variables;
|
||||
|
||||
abstract Expression? condition;
|
||||
@@ -906,8 +925,13 @@ abstract interface class ForMapEntryBase implements TreeNode, MapLiteralEntry {
|
||||
class ForMapEntry extends TreeNode
|
||||
with ControlFlowMapEntryMixin
|
||||
implements ForMapEntryBase, ControlFlowMapEntry {
|
||||
// May be empty, but not null.
|
||||
@override
|
||||
final List<VariableDeclaration> variables; // May be empty, but not null.
|
||||
final List<VariableInitialization> variableInitializations;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<VariableDeclaration> get variables => variableInitializations.cast();
|
||||
|
||||
@override
|
||||
Expression? condition; // May be null.
|
||||
@@ -918,8 +942,13 @@ class ForMapEntry extends TreeNode
|
||||
@override
|
||||
MapLiteralEntry body;
|
||||
|
||||
ForMapEntry(this.variables, this.condition, this.updates, this.body) {
|
||||
setParents(variables, this);
|
||||
ForMapEntry(
|
||||
this.variableInitializations,
|
||||
this.condition,
|
||||
this.updates,
|
||||
this.body,
|
||||
) {
|
||||
setParents(variableInitializations, this);
|
||||
condition?.parent = this;
|
||||
setParents(updates, this);
|
||||
body.parent = this;
|
||||
@@ -928,7 +957,7 @@ class ForMapEntry extends TreeNode
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void visitChildren(Visitor v) {
|
||||
visitList(variables, v);
|
||||
visitList(variableInitializations, v);
|
||||
condition?.accept(v);
|
||||
visitList(updates, v);
|
||||
body.accept(v);
|
||||
@@ -937,7 +966,7 @@ class ForMapEntry extends TreeNode
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void transformChildren(Transformer v) {
|
||||
v.transformList(variables, this);
|
||||
v.transformList(variableInitializations, this);
|
||||
if (condition != null) {
|
||||
condition = v.transform(condition!);
|
||||
condition?.parent = this;
|
||||
@@ -950,7 +979,7 @@ class ForMapEntry extends TreeNode
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void transformOrRemoveChildren(RemovingTransformer v) {
|
||||
v.transformVariableDeclarationList(variables, this);
|
||||
v.transformVariableInitializationList(variableInitializations, this);
|
||||
if (condition != null) {
|
||||
condition = v.transformOrRemoveExpression(condition!);
|
||||
condition?.parent = this;
|
||||
@@ -969,12 +998,12 @@ class ForMapEntry extends TreeNode
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.write('for (');
|
||||
for (int index = 0; index < variables.length; index++) {
|
||||
for (int index = 0; index < variableInitializations.length; index++) {
|
||||
if (index > 0) {
|
||||
printer.write(', ');
|
||||
}
|
||||
printer.writeVariableDeclaration(
|
||||
variables[index],
|
||||
printer.writeVariableInitialization(
|
||||
variableInitializations[index],
|
||||
includeModifiersAndType: index == 0,
|
||||
);
|
||||
}
|
||||
@@ -996,7 +1025,11 @@ class PatternForMapEntry extends TreeNode
|
||||
List<VariableDeclaration> intermediateVariables;
|
||||
|
||||
@override
|
||||
final List<VariableDeclaration> variables;
|
||||
final List<VariableInitialization> variableInitializations;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
List<VariableDeclaration> get variables => variableInitializations.cast();
|
||||
|
||||
@override
|
||||
Expression? condition;
|
||||
@@ -1010,23 +1043,23 @@ class PatternForMapEntry extends TreeNode
|
||||
PatternForMapEntry({
|
||||
required this.patternVariableDeclaration,
|
||||
required this.intermediateVariables,
|
||||
required this.variables,
|
||||
required List<VariableInitialization> variables,
|
||||
required this.condition,
|
||||
required this.updates,
|
||||
required this.body,
|
||||
});
|
||||
}) : variableInitializations = variables;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
patternVariableDeclaration.toTextInternal(printer);
|
||||
printer.write('for (');
|
||||
for (int index = 0; index < variables.length; index++) {
|
||||
for (int index = 0; index < variableInitializations.length; index++) {
|
||||
if (index > 0) {
|
||||
printer.write(', ');
|
||||
}
|
||||
printer.writeVariableDeclaration(
|
||||
variables[index],
|
||||
printer.writeVariableInitialization(
|
||||
variableInitializations[index],
|
||||
includeModifiersAndType: index == 0,
|
||||
);
|
||||
}
|
||||
@@ -1313,7 +1346,7 @@ MapLiteralEntry convertToMapEntry(
|
||||
PatternForMapEntry result = new PatternForMapEntry(
|
||||
patternVariableDeclaration: element.patternVariableDeclaration,
|
||||
intermediateVariables: element.intermediateVariables,
|
||||
variables: element.variables,
|
||||
variables: element.variableInitializations,
|
||||
condition: element.condition,
|
||||
updates: element.updates,
|
||||
body: convertToMapEntry(
|
||||
@@ -1329,7 +1362,7 @@ MapLiteralEntry convertToMapEntry(
|
||||
|
||||
case ForElement():
|
||||
ForMapEntry result = new ForMapEntry(
|
||||
element.variables,
|
||||
element.variableInitializations,
|
||||
element.condition,
|
||||
element.updates,
|
||||
convertToMapEntry(
|
||||
|
||||
@@ -6052,7 +6052,7 @@ class StatementConstantEvaluator
|
||||
|
||||
@override
|
||||
ExecutionStatus visitForStatement(ForStatement node) {
|
||||
for (VariableDeclaration variable in node.variables) {
|
||||
for (VariableInitialization variable in node.variableInitializations) {
|
||||
final ExecutionStatus status = variable.accept(this);
|
||||
if (status is! ProceedStatus) return status;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ class Forest {
|
||||
|
||||
ForElement createForElement(
|
||||
int fileOffset,
|
||||
List<VariableDeclaration> variables,
|
||||
List<VariableInitialization> variables,
|
||||
Expression? condition,
|
||||
List<Expression> updates,
|
||||
Expression body,
|
||||
@@ -295,7 +295,7 @@ class Forest {
|
||||
int fileOffset, {
|
||||
required PatternVariableDeclaration patternVariableDeclaration,
|
||||
required List<VariableDeclaration> intermediateVariables,
|
||||
required List<VariableDeclaration> variables,
|
||||
required List<VariableInitialization> variables,
|
||||
required Expression? condition,
|
||||
required List<Expression> updates,
|
||||
required Expression body,
|
||||
@@ -312,7 +312,7 @@ class Forest {
|
||||
|
||||
ForMapEntry createForMapEntry(
|
||||
int fileOffset,
|
||||
List<VariableDeclaration> variables,
|
||||
List<VariableInitialization> variables,
|
||||
Expression? condition,
|
||||
List<Expression> updates,
|
||||
MapLiteralEntry body,
|
||||
@@ -325,7 +325,7 @@ class Forest {
|
||||
int fileOffset, {
|
||||
required PatternVariableDeclaration patternVariableDeclaration,
|
||||
required List<VariableDeclaration> intermediateVariables,
|
||||
required List<VariableDeclaration> variables,
|
||||
required List<VariableInitialization> variableInitializations,
|
||||
required Expression? condition,
|
||||
required List<Expression> updates,
|
||||
required MapLiteralEntry body,
|
||||
@@ -333,7 +333,7 @@ class Forest {
|
||||
return new PatternForMapEntry(
|
||||
patternVariableDeclaration: patternVariableDeclaration,
|
||||
intermediateVariables: intermediateVariables,
|
||||
variables: variables,
|
||||
variables: variableInitializations,
|
||||
condition: condition,
|
||||
updates: updates,
|
||||
body: body,
|
||||
@@ -505,7 +505,7 @@ class Forest {
|
||||
/// Return a representation of a for statement.
|
||||
Statement createForStatement(
|
||||
int fileOffset,
|
||||
List<VariableDeclaration>? variables,
|
||||
List<VariableInitialization>? variables,
|
||||
Expression? condition,
|
||||
List<Expression> updaters,
|
||||
Statement body,
|
||||
@@ -1219,7 +1219,7 @@ class _VariablesDeclaration extends AuxiliaryStatement {
|
||||
if (index > 0) {
|
||||
printer.write(', ');
|
||||
}
|
||||
printer.writeVariableDeclaration(
|
||||
printer.writeVariableInitialization(
|
||||
declarations[index],
|
||||
includeModifiersAndType: index == 0,
|
||||
);
|
||||
|
||||
@@ -385,7 +385,7 @@ class Cascade extends InternalExpression {
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.write('let ');
|
||||
printer.writeVariableDeclaration(variable);
|
||||
printer.writeVariableInitialization(variable);
|
||||
printer.write(' in cascade {');
|
||||
printer.incIndentation();
|
||||
for (Expression expression in expressions) {
|
||||
@@ -431,7 +431,7 @@ class DeferredCheck extends InternalExpression {
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.write('let ');
|
||||
printer.writeVariableDeclaration(variable);
|
||||
printer.writeVariableInitialization(variable);
|
||||
printer.write(' in ');
|
||||
printer.writeExpression(expression);
|
||||
}
|
||||
@@ -888,7 +888,7 @@ class VariableDeclarationImpl extends VariableStatement
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.writeVariableDeclaration(
|
||||
printer.writeVariableInitialization(
|
||||
this,
|
||||
isLate: isLate || lateGetter != null,
|
||||
type: lateType ?? type,
|
||||
@@ -1050,7 +1050,6 @@ mixin DelegatingVariableMixin on InternalExpressionVariableMixin
|
||||
bool get isLate => astVariable.isLate;
|
||||
|
||||
@override
|
||||
// Coverage-ignore(suite): Not run.
|
||||
void set isLate(bool value) {
|
||||
astVariable.isLate = value;
|
||||
}
|
||||
|
||||
@@ -3477,9 +3477,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
@override
|
||||
StatementInferenceResult visitForStatement(ForStatement node) {
|
||||
_contextAllocationStrategy.enterScopeProvider(node);
|
||||
List<VariableDeclaration>? variables;
|
||||
for (int index = 0; index < node.variables.length; index++) {
|
||||
VariableDeclaration variable = node.variables[index];
|
||||
List<VariableInitialization>? variables;
|
||||
for (int index = 0; index < node.variableInitializations.length; index++) {
|
||||
VariableInitialization variable = node.variableInitializations[index];
|
||||
if (variable.name == null) {
|
||||
if (variable.initializer != null) {
|
||||
ExpressionInferenceResult result = inferExpression(
|
||||
@@ -3495,8 +3495,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
if (variableResult.hasChanged) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
if (variables == null) {
|
||||
variables = <VariableDeclaration>[];
|
||||
variables.addAll(node.variables.sublist(0, index));
|
||||
variables = <VariableInitialization>[];
|
||||
variables.addAll(node.variableInitializations.sublist(0, index));
|
||||
}
|
||||
if (variableResult.statementCount == 1) {
|
||||
variables.add(variableResult.statement as VariableDeclaration);
|
||||
@@ -3514,8 +3514,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
}
|
||||
if (variables != null) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
node.variables.clear();
|
||||
node.variables.addAll(variables);
|
||||
node.variableInitializations.clear();
|
||||
node.variableInitializations.addAll(variables);
|
||||
setParents(variables, node);
|
||||
}
|
||||
flowAnalysis.for_conditionBegin(node);
|
||||
@@ -4278,11 +4278,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
List<VariableDeclaration> declaredVariables =
|
||||
patternVariableDeclaration.pattern.declaredVariables;
|
||||
assert(declaredVariables.length == element.intermediateVariables.length);
|
||||
assert(declaredVariables.length == element.variables.length);
|
||||
assert(declaredVariables.length == element.variableInitializations.length);
|
||||
for (int i = 0; i < declaredVariables.length; i++) {
|
||||
DartType type = declaredVariables[i].type;
|
||||
element.intermediateVariables[i].type = type;
|
||||
element.variables[i].type = type;
|
||||
element.variableInitializations[i].type = type;
|
||||
}
|
||||
|
||||
return _inferForElementBase(
|
||||
@@ -4314,9 +4314,13 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
Map<Expression, DartType> inferredConditionTypes,
|
||||
) {
|
||||
// TODO(johnniwinther): Use _visitStatements instead.
|
||||
List<VariableDeclaration>? variables;
|
||||
for (int index = 0; index < element.variables.length; index++) {
|
||||
VariableDeclaration variable = element.variables[index];
|
||||
List<VariableInitialization>? variables;
|
||||
for (
|
||||
int index = 0;
|
||||
index < element.variableInitializations.length;
|
||||
index++
|
||||
) {
|
||||
VariableInitialization variable = element.variableInitializations[index];
|
||||
if (variable.name == null) {
|
||||
if (variable.initializer != null) {
|
||||
ExpressionInferenceResult initializerResult = inferExpression(
|
||||
@@ -4334,7 +4338,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
if (variables == null) {
|
||||
variables = <VariableDeclaration>[];
|
||||
variables.addAll(element.variables.sublist(0, index));
|
||||
variables.addAll(element.variableInitializations.sublist(0, index));
|
||||
}
|
||||
if (variableResult.statementCount == 1) {
|
||||
variables.add(variableResult.statement as VariableDeclaration);
|
||||
@@ -4352,8 +4356,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
}
|
||||
if (variables != null) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
element.variables.clear();
|
||||
element.variables.addAll(variables);
|
||||
element.variableInitializations.clear();
|
||||
element.variableInitializations.addAll(variables);
|
||||
setParents(variables, element);
|
||||
}
|
||||
|
||||
@@ -5172,7 +5176,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
: _createBlock(statements);
|
||||
ForStatement loop = _createForStatement(
|
||||
element.fileOffset,
|
||||
element.variables,
|
||||
element.variableInitializations,
|
||||
element.condition,
|
||||
element.updates,
|
||||
loopBody,
|
||||
@@ -5207,7 +5211,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
_createBlock(statements);
|
||||
ForStatement loop = _createForStatement(
|
||||
element.fileOffset,
|
||||
element.variables,
|
||||
element.variableInitializations,
|
||||
element.condition,
|
||||
element.updates,
|
||||
loopBody,
|
||||
@@ -5774,7 +5778,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
: _createBlock(statements);
|
||||
ForStatement loop = _createForStatement(
|
||||
entry.fileOffset,
|
||||
entry.variables,
|
||||
entry.variableInitializations,
|
||||
entry.condition,
|
||||
entry.updates,
|
||||
loopBody,
|
||||
@@ -5807,7 +5811,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
: _createBlock(statements);
|
||||
ForStatement loop = _createForStatement(
|
||||
entry.fileOffset,
|
||||
entry.variables,
|
||||
entry.variableInitializations,
|
||||
entry.condition,
|
||||
entry.updates,
|
||||
loopBody,
|
||||
@@ -6771,7 +6775,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
|
||||
ForStatement _createForStatement(
|
||||
int fileOffset,
|
||||
List<VariableDeclaration> variables,
|
||||
List<VariableInitialization> variables,
|
||||
Expression? condition,
|
||||
List<Expression> updates,
|
||||
Statement body,
|
||||
@@ -7367,11 +7371,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
List<VariableDeclaration> declaredVariables =
|
||||
patternVariableDeclaration.pattern.declaredVariables;
|
||||
assert(declaredVariables.length == entry.intermediateVariables.length);
|
||||
assert(declaredVariables.length == entry.variables.length);
|
||||
assert(declaredVariables.length == entry.variableInitializations.length);
|
||||
for (int i = 0; i < declaredVariables.length; i++) {
|
||||
DartType type = declaredVariables[i].type;
|
||||
entry.intermediateVariables[i].type = type;
|
||||
entry.variables[i].type = type;
|
||||
entry.variableInitializations[i].type = type;
|
||||
}
|
||||
|
||||
return _inferForMapEntryBase(
|
||||
@@ -7427,9 +7431,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
_MapLiteralEntryOffsets offsets,
|
||||
) {
|
||||
// TODO(johnniwinther): Use _visitStatements instead.
|
||||
List<VariableDeclaration>? variables;
|
||||
for (int index = 0; index < entry.variables.length; index++) {
|
||||
VariableDeclaration variable = entry.variables[index];
|
||||
List<VariableInitialization>? variables;
|
||||
for (int index = 0; index < entry.variableInitializations.length; index++) {
|
||||
VariableInitialization variable = entry.variableInitializations[index];
|
||||
if (variable.name == null) {
|
||||
if (variable.initializer != null) {
|
||||
ExpressionInferenceResult result = inferExpression(
|
||||
@@ -7446,7 +7450,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
if (variables == null) {
|
||||
variables = <VariableDeclaration>[];
|
||||
variables.addAll(entry.variables.sublist(0, index));
|
||||
variables.addAll(entry.variableInitializations.sublist(0, index));
|
||||
}
|
||||
if (variableResult.statementCount == 1) {
|
||||
variables.add(variableResult.statement as VariableDeclaration);
|
||||
@@ -7464,8 +7468,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
}
|
||||
if (variables != null) {
|
||||
// Coverage-ignore-block(suite): Not run.
|
||||
entry.variables.clear();
|
||||
entry.variables.addAll(variables);
|
||||
entry.variableInitializations.clear();
|
||||
entry.variableInitializations.addAll(variables);
|
||||
setParents(variables, entry);
|
||||
}
|
||||
|
||||
@@ -8211,7 +8215,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
PatternForElement result = new PatternForElement(
|
||||
patternVariableDeclaration: entry.patternVariableDeclaration,
|
||||
intermediateVariables: entry.intermediateVariables,
|
||||
variables: entry.variables,
|
||||
variables: entry.variableInitializations,
|
||||
condition: entry.condition,
|
||||
updates: entry.updates,
|
||||
body: convertToElement(entry.body, onConvertMapEntry),
|
||||
@@ -8220,7 +8224,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
return result;
|
||||
case ForMapEntry():
|
||||
ForElement result = new ForElement(
|
||||
entry.variables,
|
||||
entry.variableInitializations,
|
||||
entry.condition,
|
||||
entry.updates,
|
||||
convertToElement(entry.body, onConvertMapEntry),
|
||||
|
||||
@@ -69,6 +69,8 @@ class TypeArgumentsVisitor extends VerifyingAnalysis {
|
||||
'VariableDeclaration',
|
||||
uri: astUri,
|
||||
);
|
||||
InterfaceType variableInitializationType = interface
|
||||
.createInterfaceType('VariableInitialization', uri: astUri);
|
||||
DartType typeArgument = receiver.arguments.types.single;
|
||||
if (interface.isSubtypeOf(typeArgument, expressionType) &&
|
||||
typeArgument != expressionType) {
|
||||
@@ -102,6 +104,19 @@ class TypeArgumentsVisitor extends VerifyingAnalysis {
|
||||
"${typeArgument} instead of ${variableDeclarationType}",
|
||||
);
|
||||
}
|
||||
} else if (interface.isSubtypeOf(
|
||||
typeArgument,
|
||||
variableInitializationType,
|
||||
)) {
|
||||
// [VariableInitialization] is used as an exclusive member of, for
|
||||
// instance, `ForStatement.variableInitializations`.
|
||||
if (typeArgument != variableInitializationType) {
|
||||
registerError(
|
||||
node,
|
||||
"map().toList() with type argument "
|
||||
"${typeArgument} instead of ${variableInitializationType}",
|
||||
);
|
||||
}
|
||||
} else if (typeArgument != statementType) {
|
||||
registerError(
|
||||
node,
|
||||
|
||||
@@ -11,3 +11,19 @@ testCaptured() {
|
||||
int a = 0;
|
||||
return () => a;
|
||||
}
|
||||
|
||||
testForCounterNotCaptured() {
|
||||
int a = 0;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
a += i;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
testForCounterCaptured() {
|
||||
List<Function> closures = [];
|
||||
for (int i = 0; i < 10; i++) {
|
||||
closures.add(() => i);
|
||||
}
|
||||
return closures;
|
||||
}
|
||||
|
||||
@@ -18,3 +18,33 @@ static method testCaptured() → dynamic /* scope=[
|
||||
a := 0;
|
||||
return () → core::int => a;
|
||||
}
|
||||
static method testForCounterNotCaptured() → dynamic /* scope=[
|
||||
not-captured VariableContext([
|
||||
local-variable a;
|
||||
]),
|
||||
] */ {
|
||||
a := 0;
|
||||
for /* scope=[
|
||||
not-captured VariableContext([
|
||||
local-variable i;
|
||||
]),
|
||||
] */ (i := 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
|
||||
a = a.{core::num::+}(i){(core::num) → core::int};
|
||||
}
|
||||
return a;
|
||||
}
|
||||
static method testForCounterCaptured() → dynamic /* scope=[
|
||||
not-captured VariableContext([
|
||||
local-variable closures;
|
||||
]),
|
||||
] */ {
|
||||
closures := <core::Function>[];
|
||||
for /* scope=[
|
||||
captured VariableContext([
|
||||
local-variable i;
|
||||
]),
|
||||
] */ (i := 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
|
||||
closures.{core::List::add}(() → core::int => i){(core::Function) → void};
|
||||
}
|
||||
return closures;
|
||||
}
|
||||
|
||||
+30
@@ -18,3 +18,33 @@ static method testCaptured() → dynamic /* scope=[
|
||||
a := 0;
|
||||
return () → core::int => a;
|
||||
}
|
||||
static method testForCounterNotCaptured() → dynamic /* scope=[
|
||||
not-captured VariableContext([
|
||||
local-variable a;
|
||||
]),
|
||||
] */ {
|
||||
a := 0;
|
||||
for /* scope=[
|
||||
not-captured VariableContext([
|
||||
local-variable i;
|
||||
]),
|
||||
] */ (i := 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
|
||||
a = a.{core::num::+}(i){(core::num) → core::int};
|
||||
}
|
||||
return a;
|
||||
}
|
||||
static method testForCounterCaptured() → dynamic /* scope=[
|
||||
not-captured VariableContext([
|
||||
local-variable closures;
|
||||
]),
|
||||
] */ {
|
||||
closures := <core::Function>[];
|
||||
for /* scope=[
|
||||
captured VariableContext([
|
||||
local-variable i;
|
||||
]),
|
||||
] */ (i := 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
|
||||
closures.{core::List::add}(() → core::int => i){(core::Function) → void};
|
||||
}
|
||||
return closures;
|
||||
}
|
||||
|
||||
+4
@@ -5,3 +5,7 @@ static method testNotCaptured() → dynamic
|
||||
;
|
||||
static method testCaptured() → dynamic
|
||||
;
|
||||
static method testForCounterNotCaptured() → dynamic
|
||||
;
|
||||
static method testForCounterCaptured() → dynamic
|
||||
;
|
||||
|
||||
+4
@@ -1,3 +1,7 @@
|
||||
testNotCaptured() {}
|
||||
|
||||
testCaptured() {}
|
||||
|
||||
testForCounterNotCaptured() {}
|
||||
|
||||
testForCounterCaptured() {}
|
||||
|
||||
+4
@@ -1,3 +1,7 @@
|
||||
testCaptured() {}
|
||||
|
||||
testForCounterCaptured() {}
|
||||
|
||||
testForCounterNotCaptured() {}
|
||||
|
||||
testNotCaptured() {}
|
||||
|
||||
@@ -129,7 +129,7 @@ const Map<String?, Map<String, FieldRule?>> _fieldRuleMap = {
|
||||
'LocalFunctionInvocation': {'variable': FieldRule(isDeclaration: false)},
|
||||
'LocalVariable': {'variableInitialization': FieldRule(isDeclaration: false)},
|
||||
'BreakStatement': {'target': FieldRule(isDeclaration: false)},
|
||||
'ForStatement': {'variables': FieldRule(isDeclaration: true)},
|
||||
'ForStatement': {'variableInitializations': FieldRule(isDeclaration: true)},
|
||||
'ForInStatement': {'variable': FieldRule(isDeclaration: true)},
|
||||
'SwitchStatement': {'cases': FieldRule(isDeclaration: true)},
|
||||
'ContinueSwitchStatement': {'target': FieldRule(isDeclaration: false)},
|
||||
|
||||
@@ -534,7 +534,8 @@ class CloneVisitorNotMembers
|
||||
|
||||
@override
|
||||
TreeNode visitForStatement(ForStatement node) {
|
||||
List<VariableDeclaration> variables = node.variables.map(clone).toList();
|
||||
List<VariableInitialization> variables =
|
||||
node.variableInitializations.map(clone).toList();
|
||||
return new ForStatement(variables, cloneOptional(node.condition),
|
||||
node.updates.map(clone).toList(), clone(node.body));
|
||||
}
|
||||
|
||||
@@ -4845,7 +4845,7 @@ class Let extends Expression {
|
||||
@override
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.write('let ');
|
||||
printer.writeVariableDeclaration(variable);
|
||||
printer.writeVariableInitialization(variable);
|
||||
printer.write(' in ');
|
||||
printer.writeExpression(body);
|
||||
}
|
||||
|
||||
@@ -530,7 +530,10 @@ class DoStatement extends Statement implements LoopStatement {
|
||||
}
|
||||
|
||||
class ForStatement extends Statement implements LoopStatement, ScopeProvider {
|
||||
final List<VariableDeclaration> variables; // May be empty, but not null.
|
||||
// May be empty, but not null.
|
||||
final List<VariableInitialization> variableInitializations;
|
||||
List<VariableDeclaration> get variables => variableInitializations.cast();
|
||||
|
||||
Expression? condition; // May be null.
|
||||
final List<Expression> updates; // May be empty, but not null.
|
||||
|
||||
@@ -540,8 +543,9 @@ class ForStatement extends Statement implements LoopStatement, ScopeProvider {
|
||||
@override
|
||||
Scope? scope;
|
||||
|
||||
ForStatement(this.variables, this.condition, this.updates, this.body) {
|
||||
setParents(variables, this);
|
||||
ForStatement(
|
||||
this.variableInitializations, this.condition, this.updates, this.body) {
|
||||
setParents(variableInitializations, this);
|
||||
condition?.parent = this;
|
||||
setParents(updates, this);
|
||||
body.parent = this;
|
||||
@@ -556,7 +560,7 @@ class ForStatement extends Statement implements LoopStatement, ScopeProvider {
|
||||
|
||||
@override
|
||||
void visitChildren(Visitor v) {
|
||||
visitList(variables, v);
|
||||
visitList(variableInitializations, v);
|
||||
condition?.accept(v);
|
||||
visitList(updates, v);
|
||||
body.accept(v);
|
||||
@@ -564,7 +568,7 @@ class ForStatement extends Statement implements LoopStatement, ScopeProvider {
|
||||
|
||||
@override
|
||||
void transformChildren(Transformer v) {
|
||||
v.transformList(variables, this);
|
||||
v.transformList(variableInitializations, this);
|
||||
if (condition != null) {
|
||||
condition = v.transform(condition!);
|
||||
condition?.parent = this;
|
||||
@@ -576,7 +580,7 @@ class ForStatement extends Statement implements LoopStatement, ScopeProvider {
|
||||
|
||||
@override
|
||||
void transformOrRemoveChildren(RemovingTransformer v) {
|
||||
v.transformVariableDeclarationList(variables, this);
|
||||
v.transformVariableInitializationList(variableInitializations, this);
|
||||
if (condition != null) {
|
||||
condition = v.transformOrRemoveExpression(condition!);
|
||||
condition?.parent = this;
|
||||
@@ -594,11 +598,11 @@ class ForStatement extends Statement implements LoopStatement, ScopeProvider {
|
||||
@override
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.write('for (');
|
||||
for (int index = 0; index < variables.length; index++) {
|
||||
for (int index = 0; index < variableInitializations.length; index++) {
|
||||
if (index > 0) {
|
||||
printer.write(', ');
|
||||
}
|
||||
printer.writeVariableDeclaration(variables[index],
|
||||
printer.writeVariableInitialization(variableInitializations[index],
|
||||
includeModifiersAndType: index == 0);
|
||||
}
|
||||
printer.write('; ');
|
||||
@@ -761,7 +765,7 @@ class ForInStatement extends Statement implements LoopStatement, ScopeProvider {
|
||||
@override
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.write('for (');
|
||||
printer.writeVariableDeclaration(variable);
|
||||
printer.writeVariableInitialization(variable);
|
||||
|
||||
printer.write(' in ');
|
||||
printer.writeExpression(iterable);
|
||||
@@ -1274,11 +1278,11 @@ class Catch extends TreeNode implements ScopeProvider {
|
||||
printer.write(' ');
|
||||
}
|
||||
printer.write('catch (');
|
||||
printer.writeVariableDeclaration(exception!,
|
||||
printer.writeVariableInitialization(exception!,
|
||||
includeModifiersAndType: false);
|
||||
if (stackTrace != null) {
|
||||
printer.write(', ');
|
||||
printer.writeVariableDeclaration(stackTrace!,
|
||||
printer.writeVariableInitialization(stackTrace!,
|
||||
includeModifiersAndType: false);
|
||||
}
|
||||
printer.write(') ');
|
||||
@@ -1898,13 +1902,13 @@ class VariableStatement extends Statement implements VariableDeclaration {
|
||||
@override
|
||||
String toStringInternal() {
|
||||
AstPrinter printer = new AstPrinter(defaultAstTextStrategy);
|
||||
printer.writeVariableDeclaration(this, includeInitializer: false);
|
||||
printer.writeVariableInitialization(this, includeInitializer: false);
|
||||
return printer.getText();
|
||||
}
|
||||
|
||||
@override
|
||||
void toTextInternal(AstPrinter printer) {
|
||||
printer.writeVariableDeclaration(this);
|
||||
printer.writeVariableInitialization(this);
|
||||
printer.write(';');
|
||||
}
|
||||
|
||||
|
||||
@@ -5131,7 +5131,7 @@ class EquivalenceStrategy {
|
||||
if (other is! ForStatement) return false;
|
||||
visitor.pushNodeState(node, other);
|
||||
bool result = true;
|
||||
if (!checkForStatement_variables(visitor, node, other)) {
|
||||
if (!checkForStatement_variableInitializations(visitor, node, other)) {
|
||||
result = visitor.resultOnInequivalence;
|
||||
}
|
||||
if (!checkForStatement_condition(visitor, node, other)) {
|
||||
@@ -9542,10 +9542,13 @@ class EquivalenceStrategy {
|
||||
return checkStatement_fileOffset(visitor, node, other);
|
||||
}
|
||||
|
||||
bool checkForStatement_variables(
|
||||
bool checkForStatement_variableInitializations(
|
||||
EquivalenceVisitor visitor, ForStatement node, ForStatement other) {
|
||||
return visitor.checkLists(
|
||||
node.variables, other.variables, visitor.checkNodes, 'variables');
|
||||
node.variableInitializations,
|
||||
other.variableInitializations,
|
||||
visitor.checkNodes,
|
||||
'variableInitializations');
|
||||
}
|
||||
|
||||
bool checkForStatement_condition(
|
||||
|
||||
@@ -467,7 +467,7 @@ class AstPrinter {
|
||||
node.toTextInternal(this, includeTypeArguments: includeTypeArguments);
|
||||
}
|
||||
|
||||
/// Writes the variable declaration [node] to the printer buffer.
|
||||
/// Writes the [VariableInitialization] [node] to the printer buffer.
|
||||
///
|
||||
/// If [includeModifiersAndType] is `true`, the declaration is prefixed by
|
||||
/// the modifiers and declared type of the variable. Otherwise only the
|
||||
@@ -475,7 +475,7 @@ class AstPrinter {
|
||||
///
|
||||
/// If [isLate] and [type] are provided, these values are used instead of
|
||||
/// the corresponding properties on [node].
|
||||
void writeVariableDeclaration(VariableDeclaration node,
|
||||
void writeVariableInitialization(VariableInitialization node,
|
||||
{bool includeModifiersAndType = true,
|
||||
bool? isLate,
|
||||
DartType? type,
|
||||
@@ -496,7 +496,7 @@ class AstPrinter {
|
||||
writeType(type ?? node.type);
|
||||
_sb.write(' ');
|
||||
}
|
||||
_sb.write(getVariableName(node));
|
||||
_sb.write(getVariableName(node.variable));
|
||||
if (includeInitializer && node.initializer != null && !node.isRequired) {
|
||||
_sb.write(' = ');
|
||||
writeExpression(node.initializer!);
|
||||
@@ -556,7 +556,7 @@ class AstPrinter {
|
||||
if (index == node.requiredParameterCount) {
|
||||
_sb.write('[');
|
||||
}
|
||||
writeVariableDeclaration(node.positionalParameters[index]);
|
||||
writeVariableInitialization(node.positionalParameters[index]);
|
||||
}
|
||||
if (node.requiredParameterCount < node.positionalParameters.length) {
|
||||
_sb.write(']');
|
||||
@@ -570,7 +570,7 @@ class AstPrinter {
|
||||
if (index > 0) {
|
||||
_sb.write(', ');
|
||||
}
|
||||
writeVariableDeclaration(node.namedParameters[index]);
|
||||
writeVariableInitialization(node.namedParameters[index]);
|
||||
}
|
||||
_sb.write('}');
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ class NameSystem {
|
||||
}
|
||||
|
||||
abstract class Annotator {
|
||||
String annotateVariable(Printer printer, VariableDeclaration node);
|
||||
String annotateVariable(Printer printer, VariableInitialization node);
|
||||
String annotateReturn(Printer printer, FunctionNode node);
|
||||
String annotateField(Printer printer, Field node);
|
||||
}
|
||||
@@ -1103,6 +1103,7 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
|
||||
writeVariableContext(context, separator: separator);
|
||||
}
|
||||
--indentation;
|
||||
writeIndentation();
|
||||
writeWord('] */');
|
||||
}
|
||||
|
||||
@@ -2422,8 +2423,12 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
|
||||
void visitForStatement(ForStatement node) {
|
||||
writeIndentation();
|
||||
writeSpaced('for');
|
||||
if (node.scope case Scope scope?) {
|
||||
writeScope(scope);
|
||||
ensureSpace();
|
||||
}
|
||||
writeSymbol('(');
|
||||
writeList(node.variables, writeVariableDeclaration);
|
||||
writeList(node.variableInitializations, writeVariableInitialization);
|
||||
writeComma(';');
|
||||
Expression? condition = node.condition;
|
||||
if (condition != null) {
|
||||
@@ -2647,26 +2652,32 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
|
||||
void writeVariableInitialization(
|
||||
VariableInitialization node,
|
||||
) {
|
||||
if (showOffsets) writeWord("[${node.fileOffset}]");
|
||||
if (showMetadata) writeMetadata(node);
|
||||
writeAnnotationList(node.annotations, separateLines: false);
|
||||
writeModifier(node.isErroneouslyInitialized, 'erroneously-initialized');
|
||||
bool hasImplicitInitializer = node.initializer is NullLiteral ||
|
||||
(node.initializer is ConstantExpression &&
|
||||
(node.initializer as ConstantExpression).constant is NullConstant);
|
||||
if ((node.initializer == null || hasImplicitInitializer) &&
|
||||
node.hasDeclaredInitializer) {
|
||||
writeModifier(node.hasDeclaredInitializer, 'has-declared-initializer');
|
||||
} else if (node.initializer != null &&
|
||||
!hasImplicitInitializer &&
|
||||
!node.hasDeclaredInitializer) {
|
||||
writeModifier(node.hasDeclaredInitializer, 'has-no-declared-initializer');
|
||||
}
|
||||
writeWord(getVariableName(node.variable));
|
||||
Expression? initializer = node.initializer;
|
||||
if (initializer != null) {
|
||||
writeSpaced(':=');
|
||||
writeExpression(initializer);
|
||||
if (node is VariableDeclaration) {
|
||||
writeVariableDeclaration(node);
|
||||
} else {
|
||||
if (showOffsets) writeWord("[${node.fileOffset}]");
|
||||
if (showMetadata) writeMetadata(node);
|
||||
writeAnnotationList(node.annotations, separateLines: false);
|
||||
writeModifier(node.isErroneouslyInitialized, 'erroneously-initialized');
|
||||
bool hasImplicitInitializer = node.initializer is NullLiteral ||
|
||||
(node.initializer is ConstantExpression &&
|
||||
(node.initializer as ConstantExpression).constant
|
||||
is NullConstant);
|
||||
if ((node.initializer == null || hasImplicitInitializer) &&
|
||||
node.hasDeclaredInitializer) {
|
||||
writeModifier(node.hasDeclaredInitializer, 'has-declared-initializer');
|
||||
} else if (node.initializer != null &&
|
||||
!hasImplicitInitializer &&
|
||||
!node.hasDeclaredInitializer) {
|
||||
writeModifier(
|
||||
node.hasDeclaredInitializer, 'has-no-declared-initializer');
|
||||
}
|
||||
writeWord(getVariableName(node.variable));
|
||||
Expression? initializer = node.initializer;
|
||||
if (initializer != null) {
|
||||
writeSpaced(':=');
|
||||
writeExpression(initializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1023,7 +1023,7 @@ class TypeCheckingVisitor
|
||||
|
||||
@override
|
||||
void visitForStatement(ForStatement node) {
|
||||
node.variables.forEach(visitVariableDeclaration);
|
||||
node.variableInitializations.forEach(visitVariableInitialization);
|
||||
if (node.condition != null) {
|
||||
node.condition = checkExpressionAndAssignability(
|
||||
node.condition!, environment.coreTypes.boolNonNullableRawType);
|
||||
@@ -1093,6 +1093,11 @@ class TypeCheckingVisitor
|
||||
|
||||
@override
|
||||
void visitVariableDeclaration(VariableDeclaration node) {
|
||||
visitVariableInitialization(node);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitVariableInitialization(VariableInitialization node) {
|
||||
if (node.initializer != null) {
|
||||
node.initializer =
|
||||
checkExpressionAndAssignability(node.initializer!, node.type);
|
||||
@@ -1347,13 +1352,6 @@ class TypeCheckingVisitor
|
||||
// TODO(johnniwinther): Implement this.
|
||||
}
|
||||
|
||||
@override
|
||||
void visitVariableInitialization(VariableInitialization node) {
|
||||
// TODO(cstefantsova): Implement visitVariableInitialization.
|
||||
throw new UnimplementedError(
|
||||
"Unimplemented support for $node (${node.runtimeType}).");
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitVariableRead(VariableRead node) {
|
||||
// TODO(cstefantsova): Implement visitVariableRead.
|
||||
|
||||
@@ -2474,6 +2474,16 @@ class RemovingTransformer extends TreeVisitor1Default<TreeNode, TreeNode?> {
|
||||
transformList(nodes, parent, dummyVariableDeclaration);
|
||||
}
|
||||
|
||||
/// Transforms or removes [VariableInitialization] nodes in [nodes] as
|
||||
/// children of [parent].
|
||||
///
|
||||
/// This is convenience method for calling [transformList] with removal
|
||||
/// sentinel for [VariableInitialization] nodes.
|
||||
void transformVariableInitializationList(
|
||||
List<VariableInitialization> nodes, TreeNode parent) {
|
||||
transformList(nodes, parent, dummyVariableDeclaration);
|
||||
}
|
||||
|
||||
/// Transforms or removes [T] nodes in [nodes] as children of [parent] by
|
||||
/// calling [transformOrRemove] using [removalSentinel] as the removal
|
||||
/// sentinel.
|
||||
|
||||
Reference in New Issue
Block a user