[cfe][Contexts] Split VariableDeclaration and VariableStatement

This separates VariableDeclaration from Statement. VariableDeclaration no longer implements Statement and variable declared in a block or in a for-statement are now wrapped by a VariableStatement.

Currently there are two VariableStatement implementations; LegacyVariableStatement for variables in the current model, called LegacyVariable, and VariableInitialization for variables used in the new, still experimental, encoding that supports scope computation.

This CL is a step towards realigning the AST nodes to the new model in which each kind of variable has its own distinct subclass. (LocalVariable, PositionalParameter, NamedParameter, SyntheticVariable, etc.)

Note that it is not the intent to use VariableStatement in ForStatement going forward but that will be handled in a follow-up.

TEST=existing.

Change-Id: I5b309cd62c9b138f95b74fb054686edffa49a393
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/502681
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther
2026-05-18 05:49:28 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 046d473d5e
commit e30cd0322c
78 changed files with 1341 additions and 1132 deletions
@@ -371,7 +371,9 @@ class SharedInteropTransformer extends Transformer {
type: dartType,
isSynthesized: true,
)..fileOffset = invocation.fileOffset;
block.add(dartInstance);
block.add(
VariableStatement(dartInstance)..fileOffset = invocation.fileOffset,
);
var jsExporter = VariableDeclaration(
'#jsExporter',
@@ -379,7 +381,9 @@ class SharedInteropTransformer extends Transformer {
type: ExtensionType(_jsObject, Nullability.nonNullable),
isSynthesized: true,
)..fileOffset = invocation.fileOffset;
block.add(jsExporter);
block.add(
VariableStatement(jsExporter)..fileOffset = invocation.fileOffset,
);
for (var MapEntry(key: exportName, value: exports) in exportMap.entries) {
ExpressionStatement setProperty(
@@ -460,7 +464,9 @@ class SharedInteropTransformer extends Transformer {
type: ExtensionType(_jsObject, Nullability.nonNullable),
isSynthesized: true,
)..fileOffset = invocation.fileOffset;
block.add(getSetMap);
block.add(
VariableStatement(getSetMap)..fileOffset = invocation.fileOffset,
);
var (:getter, :setter) = _exportChecker.getGetterSetter(exports);
if (getter != null) {
final resultType = _staticInteropMockValidator.typeParameterResolver
+7 -2
View File
@@ -898,7 +898,7 @@ class AstToIr extends ast.RecursiveVisitor {
}
@override
void visitVariableDeclaration(ast.VariableDeclaration node) {
void defaultVariableDeclaration(ast.VariableDeclaration node) {
final variable = node.variable;
if (node.isConst) return;
if (node.isLate) {
@@ -921,9 +921,14 @@ class AstToIr extends ast.RecursiveVisitor {
}
}
@override
void visitLegacyVariableStatement(ast.LegacyVariableStatement node) {
defaultVariableDeclaration(node.variable);
}
@override
void visitVariableInitialization(ast.VariableInitialization node) {
visitVariableDeclaration(node);
defaultVariableDeclaration(node.variable);
}
@override
+6 -1
View File
@@ -305,7 +305,12 @@ class _ScopeBuilder extends ast.RecursiveVisitor {
}
@override
void visitVariableDeclaration(ast.VariableDeclaration node) {
void visitLegacyVariableStatement(ast.LegacyVariableStatement node) {
node.visitChildren(this);
}
@override
void defaultVariableDeclaration(ast.VariableDeclaration node) {
_declareVariable(node.variable);
node.visitChildren(this);
}
@@ -578,7 +578,7 @@ class ConstantCollector extends ir.RecursiveVisitor {
}
@override
void visitVariableDeclaration(ir.VariableDeclaration node) {
void defaultVariableDeclaration(ir.VariableDeclaration node) {
// We avoid visiting metadata on the parameter declaration by only visiting
// the initializer. The type cannot hold constants so can kan skip that
// as well.
+9 -2
View File
@@ -939,7 +939,14 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
}
@override
TypeInformation? visitVariableDeclaration(ir.VariableDeclaration node) {
TypeInformation? visitLegacyVariableStatement(
ir.LegacyVariableStatement node,
) {
return defaultVariableDeclaration(node.variable);
}
@override
TypeInformation? defaultVariableDeclaration(ir.VariableDeclaration node) {
assert(
node.parent is! ir.FunctionNode,
"Unexpected parameter declaration.",
@@ -2457,7 +2464,7 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
@override
Null visitForStatement(ir.ForStatement node) {
for (ir.VariableDeclaration variable in node.variables) {
for (ir.VariableStatement variable in node.variables) {
visit(variable);
}
return handleLoop(node, _localsMap.getJumpTargetForFor(node), () {
+1 -1
View File
@@ -284,7 +284,7 @@ class ImpactBuilder extends ir.RecursiveVisitor implements ImpactRegistry {
}
@override
void visitVariableDeclaration(ir.VariableDeclaration node) {
void defaultVariableDeclaration(ir.VariableDeclaration node) {
if (node.initializer == null) {
registerLocalWithoutInitializer();
}
+16 -9
View File
@@ -322,8 +322,15 @@ class ScopeModelBuilder extends ir.VisitorDefault<EvaluationComplexity>
}
@override
EvaluationComplexity visitVariableDeclaration(ir.VariableDeclaration node) {
_handleVariableDeclaration(node, SimpleVariableUse.localType);
EvaluationComplexity visitLegacyVariableStatement(
ir.LegacyVariableStatement node,
) {
return defaultVariableDeclaration(node.variable);
}
@override
EvaluationComplexity defaultVariableDeclaration(ir.VariableDeclaration node) {
_handleVariableDeclaration(node.variable, SimpleVariableUse.localType);
return const EvaluationComplexity.lazy();
}
@@ -505,9 +512,9 @@ class ScopeModelBuilder extends ir.VisitorDefault<EvaluationComplexity>
// Loop variables that have not been captured yet can safely be flagged as
// non-mutated, because no nested function can observe the mutation.
for (ir.VariableDeclaration variable in node.variables) {
if (!_capturedVariables.contains(variable)) {
_mutatedVariables.remove(variable);
for (ir.VariableStatement variableDeclaration in node.variables) {
if (!_capturedVariables.contains(variableDeclaration.variable)) {
_mutatedVariables.remove(variableDeclaration.variable);
}
}
@@ -522,12 +529,12 @@ class ScopeModelBuilder extends ir.VisitorDefault<EvaluationComplexity>
});
// See if we have declared loop variables that need to be boxed.
for (ir.VariableDeclaration variable in node.variables) {
for (ir.VariableStatement variableDeclaration in node.variables) {
// Non-mutated variables should not be boxed. The _mutatedVariables set
// gets cleared when `enterNewScope` returns, so check it here.
if (_capturedVariables.contains(variable) &&
_mutatedVariables.contains(variable)) {
boxedLoopVariables.add(variable);
if (_capturedVariables.contains(variableDeclaration.variable) &&
_mutatedVariables.contains(variableDeclaration.variable)) {
boxedLoopVariables.add(variableDeclaration.variable);
}
}
});
@@ -312,8 +312,8 @@ class LateLowering {
if (!_shouldLowerVariable(variable)) return variable;
// A [VariableDeclaration] being used as a statement must be a direct child
// of a [Block].
if (variable.parent is! Block) return variable;
// of a [VariableStatement].
if (variable.parent is! VariableStatement) return variable;
return _variableCell(variable);
}
@@ -604,11 +604,11 @@ class LateLowering {
VariableGet resultRead() =>
VariableGet(result)..fileOffset = fileOffset;
return Block([
value,
VariableStatement(value),
IfStatement(
_callIsSentinel(valueRead(), fileOffset),
Block([
result,
VariableStatement(result),
ExpressionStatement(
StaticInvocation(
_coreTypes.lateInitializeOnceCheck,
@@ -653,7 +653,7 @@ class LateLowering {
)..fileOffset = fileOffset;
VariableGet valueRead() => VariableGet(value)..fileOffset = fileOffset;
return Block([
value,
VariableStatement(value),
IfStatement(
_callIsSentinel(valueRead(), fileOffset),
ExpressionStatement(
@@ -137,7 +137,7 @@ class ListFactorySpecializer extends BaseSpecializer {
final loop = ForStatement(
// initializers: _i = 0
[indexVariable],
[VariableStatement(indexVariable)],
// condition: _i < _length
InstanceInvocation(
InstanceAccessKind.Instance,
@@ -170,7 +170,11 @@ class ListFactorySpecializer extends BaseSpecializer {
)..fileOffset = node.fileOffset;
return BlockExpression(
Block([?lengthVariable, listVariable, loop]),
Block([
if (lengthVariable != null) VariableStatement(lengthVariable!),
VariableStatement(listVariable),
loop,
]),
VariableGet(listVariable)..fileOffset = node.fileOffset,
);
}
@@ -316,7 +320,7 @@ class ListGenerateLoopBodyInliner extends CloneVisitorNotMembers {
Statement run() {
Statement body = cloneInContext(function.body!);
return Block([parameter, body]);
return Block([VariableStatement(parameter), body]);
}
@override
@@ -77,7 +77,7 @@ class _ModularTransformer extends Transformer {
}
@override
TreeNode visitVariableDeclaration(VariableDeclaration node) {
TreeNode defaultVariableDeclaration(VariableDeclaration node) {
node.transformChildren(this);
return _lateLowering.transformVariableDeclaration(node, _currentMember);
}
@@ -44,11 +44,11 @@ class TreeNodeIndexerVisitor extends ir.VisitorDefault<void>
}
@override
void visitVariableDeclaration(ir.VariableDeclaration node) {
void defaultVariableDeclaration(ir.VariableDeclaration node) {
if (node.parent is! ir.FunctionDeclaration) {
registerNode(node);
}
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
}
@override
+8 -3
View File
@@ -2565,7 +2565,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
void visitForStatement(ir.ForStatement node) {
assert(_isReachable);
void buildInitializer() {
for (ir.VariableDeclaration declaration in node.variables) {
for (ir.VariableStatement declaration in node.variables) {
declaration.accept(this);
}
}
@@ -4752,7 +4752,12 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
}
@override
void visitVariableDeclaration(ir.VariableDeclaration node) {
void visitLegacyVariableStatement(ir.LegacyVariableStatement node) {
defaultVariableDeclaration(node.variable);
}
@override
void defaultVariableDeclaration(ir.VariableDeclaration node) {
Local local = _localsMap.getLocalVariable(node);
if (node.initializer == null) {
HInstruction initialValue = graph.addConstantNull(closedWorld);
@@ -9693,7 +9698,7 @@ class InlineWeeder extends ir.VisitorDefault<void> with ir.VisitorVoidMixin {
}
@override
void visitVariableDeclaration(ir.VariableDeclaration node) {
void defaultVariableDeclaration(ir.VariableDeclaration node) {
registerRegularNode();
skipReductiveNodes(() {
visitList(node.annotations);
@@ -120,7 +120,7 @@ class SwitchContinueAnalysis extends ir.VisitorDefault<bool>
node is ir.ReturnStatement ||
node is ir.AssertStatement ||
node is ir.YieldStatement ||
node is ir.VariableDeclaration) {
node is ir.VariableStatement) {
return false;
}
throw 'Statement type ${node.runtimeType} not handled in '
@@ -4832,13 +4832,18 @@ class BytecodeGenerator extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
_handleVariableInitialization(node);
}
@override
void visitLegacyVariableStatement(LegacyVariableStatement node) {
_handleVariableInitialization(node.variable);
}
@override
void visitVariableInitialization(VariableInitialization node) {
_handleVariableInitialization(node);
_handleVariableInitialization(node.variable);
}
void _handleVariableInitialization(VariableDeclaration node) {
+2 -41
View File
@@ -527,41 +527,11 @@ class _ScopeBuilder extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
_handleVariableInitialization(node);
}
@override
void visitVariableInitialization(VariableInitialization node) {
_handleVariableInitialization(node);
}
void _handleVariableInitialization(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
_declareVariable(node.variable);
node.visitChildren(this);
}
@override
void visitPositionalParameter(PositionalParameter node) {
_handleFunctionParameter(node);
}
@override
void visitNamedParameter(NamedParameter node) {
_handleFunctionParameter(node);
}
void _handleFunctionParameter(FunctionParameter node) {
_declareVariable(node);
node.visitChildren(this);
}
@override
void visitCatchVariable(CatchVariable node) {
_declareVariable(node);
node.visitChildren(this);
}
@override
void visitVariableGet(VariableGet node) {
_useVariable(node.variable);
@@ -1063,16 +1033,7 @@ class _Allocator extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
_handleVariableInitialization(node);
}
@override
void visitVariableInitialization(VariableInitialization node) {
_handleVariableInitialization(node);
}
void _handleVariableInitialization(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
_allocateVariable(node.variable);
node.visitChildren(this);
}
+34 -20
View File
@@ -91,7 +91,8 @@ class _AwaitTransformer extends Transformer {
Statement newBody = transformer.transform(body);
final List<Statement> newStatements = [
...transformer.expressionTransformer.variables,
for (final variable in transformer.expressionTransformer.variables)
VariableStatement(variable),
...transformer.statements,
];
@@ -248,13 +249,13 @@ class _AwaitTransformer extends Transformer {
List<List<Statement>> initEffects = List<List<Statement>>.generate(length, (
int i,
) {
VariableDeclaration decl = stmt.variables[i];
VariableStatement decl = stmt.variables[i];
List<Statement> statements = <Statement>[];
if (decl.initializer != null) {
decl.initializer = expressionTransformer.rewrite(
decl.initializer!,
if (decl.variable.initializer != null) {
decl.variable.initializer = expressionTransformer.rewrite(
decl.variable.initializer!,
statements,
)..parent = decl;
)..parent = decl.variable;
}
isSimple = isSimple && statements.isEmpty;
return statements;
@@ -345,23 +346,31 @@ class _AwaitTransformer extends Transformer {
List<Statement> updates = <Statement>[];
List<Statement> newBody = <Statement>[body];
for (int i = 0; i < stmt.variables.length; ++i) {
VariableDeclaration decl = stmt.variables[i];
VariableStatement decl = stmt.variables[i];
temps.add(
VariableDeclaration(null, type: decl.type, isSynthesized: true),
VariableDeclaration(
null,
type: decl.variable.type,
isSynthesized: true,
),
);
loopBody.add(decl);
if (decl.initializer != null) {
initializers.addAll(initEffects[i]);
initializers.add(
ExpressionStatement(VariableSet(decl, decl.initializer!)),
ExpressionStatement(VariableSet(decl.variable, decl.initializer!)),
);
decl.initializer = null;
}
updates.add(
ExpressionStatement(VariableSet(decl, VariableGet(temps.last))),
ExpressionStatement(
VariableSet(decl.variable, VariableGet(temps.last)),
),
);
newBody.add(
ExpressionStatement(VariableSet(temps.last, VariableGet(decl))),
ExpressionStatement(
VariableSet(temps.last, VariableGet(decl.variable)),
),
);
}
// Add the updates to their guarded list of statements.
@@ -387,7 +396,10 @@ class _AwaitTransformer extends Transformer {
loopBody.add(IfStatement(cond, Block(newBody), BreakStatement(labeled)));
labeled.body = WhileStatement(BoolLiteral(true), Block(loopBody))
..parent = labeled;
return Block(<Statement>[...temps, labeled]);
return Block(<Statement>[
for (VariableDeclaration temp in temps) VariableStatement(temp),
labeled,
]);
}
@override
@@ -537,19 +549,21 @@ class _AwaitTransformer extends Transformer {
}
return Block([
continuationVar,
exceptionVar,
stackTraceVar,
VariableStatement(continuationVar),
VariableStatement(exceptionVar),
VariableStatement(stackTraceVar),
TryFinally(body, finalizer),
]);
}
@override
TreeNode visitVariableDeclaration(VariableDeclaration stmt) {
final initializer = stmt.initializer;
TreeNode visitLegacyVariableStatement(LegacyVariableStatement stmt) {
final initializer = stmt.variable.initializer;
if (initializer != null) {
stmt.initializer = expressionTransformer.rewrite(initializer, statements)
..parent = stmt;
stmt.variable.initializer = expressionTransformer.rewrite(
initializer,
statements,
)..parent = stmt.variable;
}
return stmt;
}
@@ -1256,7 +1270,7 @@ class _ExpressionTransformer extends Transformer {
// <body's statements>
//
// and return the body's value.
statements.add(variable);
statements.add(VariableStatement(variable));
var index = nameIndex;
seenAwait = false;
variable.initializer = transform(variable.initializer!)
+4 -4
View File
@@ -1626,11 +1626,11 @@ class _CaptureFinder extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
if (depth > 0) {
variableDepth[node] = depth;
}
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
}
@override
@@ -1863,7 +1863,7 @@ class _ContextCollector extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
Capture? capture = closures.captures[node];
if (capture != null) {
if (isInInitializer == capture.isInInitializer) {
@@ -1871,7 +1871,7 @@ class _ContextCollector extends RecursiveVisitor {
capture.context = currentContext!;
}
}
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
}
@override
+17 -5
View File
@@ -672,6 +672,18 @@ abstract class AstCodeGenerator
}
}
void translateVariableDeclaration(VariableDeclaration node) {
final oldFileOffset = setSourceMapFileOffset(node.fileOffset);
try {
visitVariableDeclaration(node);
} catch (_) {
_printLocation(node);
rethrow;
} finally {
setSourceMapFileOffset(oldFileOffset);
}
}
void translateStatement(Statement node) {
final oldFileOffset = setSourceMapFileOffset(node.fileOffset);
try {
@@ -1266,7 +1278,7 @@ abstract class AstCodeGenerator
@override
void visitForStatement(ForStatement node) {
allocateContext(node);
for (VariableDeclaration variable in node.variables) {
for (VariableStatement variable in node.variables) {
translateStatement(variable);
}
w.Label block = b.block();
@@ -1290,8 +1302,8 @@ abstract class AstCodeGenerator
w.Local newContext = context.currentLocal;
// Copy the values of captured loop variables to the new context.
for (VariableDeclaration variable in node.variables) {
Capture? capture = closures.captures[variable];
for (VariableStatement variableDeclaration in node.variables) {
Capture? capture = closures.captures[variableDeclaration.variable];
if (capture != null) {
assert(capture.context == context);
b.local_get(newContext);
@@ -1559,7 +1571,7 @@ abstract class AstCodeGenerator
@override
w.ValueType visitLet(Let node, w.ValueType expectedType) {
translateStatement(node.variable);
translateVariableDeclaration(node.variable);
return translateExpression(node.body, expectedType);
}
@@ -4440,7 +4452,7 @@ class ConstructorInitializerCodeGenerator extends ConstructorCodeGeneratorBase {
@override
void visitLocalInitializer(LocalInitializer node) {
translateStatement(node.variable);
translateVariableDeclaration(node.variable);
}
@override
@@ -732,12 +732,15 @@ class _ReferenceDependenciesCollector extends RecursiveVisitor {
@override
void visitEmptyStatement(EmptyStatement node) => node.visitChildren(this);
@override
void visitVariableDeclaration(VariableDeclaration node) =>
void defaultVariableDeclaration(VariableDeclaration node) =>
node.visitChildren(this);
@override
void visitReturnStatement(ReturnStatement node) => node.visitChildren(this);
@override
void visitYieldStatement(YieldStatement node) => node.visitChildren(this);
@override
void visitLegacyVariableStatement(LegacyVariableStatement node) =>
node.visitChildren(this);
@override
void visitLet(Let node) => node.visitChildren(this);
@@ -151,7 +151,7 @@ class CallbackSpecializer {
),
);
body.add(argumentsLength);
body.add(VariableStatement(argumentsLength));
if (castClosureArguments.isNotEmpty) {
// Call the cast closure, but only if the arity is okay. In the case where
+4 -4
View File
@@ -495,11 +495,11 @@ class Finalizer extends _ExceptionHandler {
Finalizer._(this.codeGen, TryFinally node, this.parentFinalizer, super.target)
: _continuationVar =
(node.parent as Block).statements[0] as VariableDeclaration,
((node.parent as Block).statements[0] as VariableStatement).variable,
_exceptionVar =
(node.parent as Block).statements[1] as VariableDeclaration,
((node.parent as Block).statements[1] as VariableStatement).variable,
_stackTraceVar =
(node.parent as Block).statements[2] as VariableDeclaration;
((node.parent as Block).statements[2] as VariableStatement).variable;
@override
bool get canHandleJSExceptions => true;
@@ -869,7 +869,7 @@ abstract class StateMachineCodeGenerator extends AstCodeGenerator {
StateTarget after = afterTargets[node]!;
allocateContext(node);
for (VariableDeclaration variable in node.variables) {
for (VariableStatement variable in node.variables) {
translateStatement(variable);
}
emitTargetLabel(inner);
+15 -14
View File
@@ -278,11 +278,11 @@ class _WasmTransformer extends Transformer {
}
@override
visitVariableDeclaration(VariableDeclaration node) {
defaultVariableDeclaration(VariableDeclaration node) {
if (!node.isFinal) {
_implicitFinalVariables.add(node);
}
return super.visitVariableDeclaration(node);
return super.defaultVariableDeclaration(node);
}
@override
@@ -440,7 +440,8 @@ class _WasmTransformer extends Transformer {
resultType: elementType,
)..fileOffset = stmt.bodyOffset);
Block body = Block([variable, stmt.body])..fileOffset = stmt.fileOffset;
Block body = Block([VariableStatement(variable), stmt.body])
..fileOffset = stmt.fileOffset;
Statement forStatement = ForStatement(
const [],
@@ -479,8 +480,8 @@ class _WasmTransformer extends Transformer {
}
return Block([
iterator,
if (isAsync) jumpSentinel,
VariableStatement(iterator),
if (isAsync) VariableStatement(jumpSentinel),
forStatement,
]).accept<TreeNode>(this);
}
@@ -883,17 +884,17 @@ class _WasmTransformer extends Transformer {
return FunctionNode(
Block([
pausedVar,
cancelCompleterVar,
isDoneVar,
onCancelCallbackVar,
onResumeCallbackVar,
VariableStatement(pausedVar),
VariableStatement(cancelCompleterVar),
VariableStatement(isDoneVar),
VariableStatement(onCancelCallbackVar),
VariableStatement(onResumeCallbackVar),
// var controller = StreamController<T>(sync: true, onCancel: onCancelCallback, onResume: onResumeCallback);
controllerVar,
VariableStatement(controllerVar),
// var #body = ...;
bodyVar,
VariableStatement(bodyVar),
// controller.onListen = ...;
ExpressionStatement(setControllerOnListen),
@@ -1346,7 +1347,7 @@ class PushPopWasmArrayTransformer {
}
final List<Statement> arrayGrowStatements = [
newArrayVariable,
VariableStatement(newArrayVariable),
ExpressionStatement(newArrayCopy),
arrayFieldUpdate,
];
@@ -1475,7 +1476,7 @@ class PushPopWasmArrayTransformer {
isFinal: true,
type: elementType,
);
blockStatements.add(arrayGetVariable);
blockStatements.add(VariableStatement(arrayGetVariable));
// array[length] = null
if (elementIsNullable) {
+27 -20
View File
@@ -4861,10 +4861,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
@override
js_ast.Statement visitForStatement(ForStatement node) {
return _translateLoop(node, () {
js_ast.VariableInitialization emitForInitializer(VariableDeclaration v) =>
js_ast.VariableInitialization emitForInitializer(VariableStatement s) =>
js_ast.VariableInitialization(
_emitVariableDef(v),
_visitInitializer(v.initializer, v.annotations),
_emitVariableDef(s.variable),
_visitInitializer(s.variable.initializer, s.variable.annotations),
);
if (node.variables.any(containsFunctionExpression)) {
@@ -4934,30 +4934,34 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
js_ast.Statement _rewriteAsWhile(ForStatement node) {
var initFlagTempId = _emitScopedId('t#_init');
var loopVariableIds = {
for (var variable in node.variables) variable: _emitVariableDef(variable),
for (var stmt in node.variables)
stmt.variable: _emitVariableDef(stmt.variable),
};
var prevVariableTempIds = {
for (var variable in node.variables)
variable: _emitScopedId('t#_prev_${variable.name!}'),
for (var stmt in node.variables)
stmt.variable: _emitScopedId('t#_prev_${stmt.variable.name!}'),
};
var inits = js_ast.Block([
// Set init flag to false so the initialization only happens on the first
// iteration of the while loop.
js.statement('# = false;', [initFlagTempId]),
// Initialize fresh loop variables to initial values.
for (var variable in node.variables)
for (var stmt in node.variables)
js.statement('# = #;', [
loopVariableIds[variable]!,
_visitInitializer(variable.initializer, variable.annotations),
loopVariableIds[stmt.variable]!,
_visitInitializer(
stmt.variable.initializer,
stmt.variable.annotations,
),
]),
]);
var prevInits = js_ast.Block([
// Initialize fresh loop variables with the value from the previous
// iteration.
for (var variable in node.variables)
for (var stmt in node.variables)
js.statement('# = #;', [
loopVariableIds[variable],
prevVariableTempIds[variable],
loopVariableIds[stmt.variable],
prevVariableTempIds[stmt.variable],
]),
// Original update expressions.
for (var update in node.updates) _visitExpression(update).toStatement(),
@@ -4970,8 +4974,11 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
initFlagTempId,
js_ast.LiteralBool(true),
),
for (var variable in node.variables)
js_ast.VariableInitialization(prevVariableTempIds[variable]!, null),
for (var stmt in node.variables)
js_ast.VariableInitialization(
prevVariableTempIds[stmt.variable]!,
null,
),
]).toStatement(),
// The for loop transformed into a while loop.
js_ast.While(
@@ -4980,9 +4987,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
// Create fresh loop variables every iteration.
if (node.variables.isNotEmpty)
js_ast.VariableDeclarationList('let', [
for (var variable in node.variables)
for (var stmt in node.variables)
js_ast.VariableInitialization(
loopVariableIds[variable]!,
loopVariableIds[stmt.variable]!,
null,
),
]).toStatement(),
@@ -4995,15 +5002,15 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
// Original loop body.
_visitScope(_effectiveBodyOf(node, node.body)),
// Save previous loop variables
for (var variable in node.variables)
for (var stmt in node.variables)
js.statement('# = #;', [
prevVariableTempIds[variable]!,
_emitVariableRef(variable),
prevVariableTempIds[stmt.variable]!,
_emitVariableRef(stmt.variable),
])
// Map these locations to the variable declaration so stepping
// in the Dart debugger doesn't jump to the previous line when
// stepping.
..sourceInformation = _nodeStart(variable),
..sourceInformation = _nodeStart(stmt.variable),
]),
)
// The while loop gets mapped to the original for loop location.
@@ -5475,10 +5475,10 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
@override
js_ast.Statement visitForStatement(ForStatement node) {
return _translateLoop(node, () {
js_ast.VariableInitialization emitForInitializer(VariableDeclaration v) =>
js_ast.VariableInitialization emitForInitializer(VariableStatement s) =>
js_ast.VariableInitialization(
_emitVariableDef(v),
_visitInitializer(v.initializer, v.annotations),
_emitVariableDef(s.variable),
_visitInitializer(s.variable.initializer, s.variable.annotations),
);
if (node.variables.any(containsFunctionExpression)) {
@@ -5548,30 +5548,34 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
js_ast.Statement _rewriteAsWhile(ForStatement node) {
var initFlagTempId = _emitScopedId('t#_init');
var loopVariableIds = {
for (var variable in node.variables) variable: _emitVariableDef(variable),
for (var stmt in node.variables)
stmt.variable: _emitVariableDef(stmt.variable),
};
var prevVariableTempIds = {
for (var variable in node.variables)
variable: _emitScopedId('t#_prev_${variable.name!}'),
for (var stmt in node.variables)
stmt.variable: _emitScopedId('t#_prev_${stmt.variable.name!}'),
};
var inits = js_ast.Block([
// Set init flag to false so the initialization only happens on the first
// iteration of the while loop.
js.statement('# = false;', [initFlagTempId]),
// Initialize fresh loop variables to initial values.
for (var variable in node.variables)
for (var stmt in node.variables)
js.statement('# = #;', [
loopVariableIds[variable]!,
_visitInitializer(variable.initializer, variable.annotations),
loopVariableIds[stmt.variable]!,
_visitInitializer(
stmt.variable.initializer,
stmt.variable.annotations,
),
]),
]);
var prevInits = js_ast.Block([
// Intialize fresh loop variables with the value from the previous
// iteration.
for (var variable in node.variables)
for (var stmt in node.variables)
js.statement('# = #;', [
loopVariableIds[variable],
prevVariableTempIds[variable],
loopVariableIds[stmt.variable],
prevVariableTempIds[stmt.variable],
]),
// Original update expressions.
for (var update in node.updates) _visitExpression(update).toStatement(),
@@ -5584,8 +5588,11 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
initFlagTempId,
js_ast.LiteralBool(true),
),
for (var variable in node.variables)
js_ast.VariableInitialization(prevVariableTempIds[variable]!, null),
for (var stmt in node.variables)
js_ast.VariableInitialization(
prevVariableTempIds[stmt.variable]!,
null,
),
]).toStatement(),
// The for loop transformed into a while loop.
js_ast.While(
@@ -5594,9 +5601,9 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
// Create fresh loop variables every iteration.
if (node.variables.isNotEmpty)
js_ast.VariableDeclarationList('let', [
for (var variable in node.variables)
for (var stmt in node.variables)
js_ast.VariableInitialization(
loopVariableIds[variable]!,
loopVariableIds[stmt.variable]!,
null,
),
]).toStatement(),
@@ -5609,15 +5616,15 @@ class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
// Original loop body.
_visitScope(_effectiveBodyOf(node, node.body)),
// Save previous loop variables
for (var variable in node.variables)
for (var stmt in node.variables)
js.statement('# = #;', [
prevVariableTempIds[variable]!,
_emitVariableRef(variable),
prevVariableTempIds[stmt.variable]!,
_emitVariableRef(stmt.variable),
])
// Map these locations to the variable declaration so stepping
// in the Dart debugger doesn't jump to the previous line when
// stepping.
..sourceInformation = _nodeStart(variable),
..sourceInformation = _nodeStart(stmt.variable),
]),
)
// The while loop gets mapped to the original for loop location.
@@ -187,7 +187,7 @@ class ModuleSymbolsCollector extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
var kind = node.isInitializingFormal
? VariableSymbolKind.formal
: VariableSymbolKind.local;
@@ -417,7 +417,7 @@ class _NullableVariableInference extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
if (_nullInference.allowNotNullDeclarations) {
var annotations = node.annotations;
if (annotations.isNotEmpty &&
@@ -339,7 +339,7 @@ Expression? getLateFieldInitializer(Member node) {
return staticSet.value;
}
} else if (block.statements.isNotEmpty &&
block.statements.first is VariableDeclaration) {
block.statements.first is VariableStatement) {
// We have
//
// get field {
@@ -353,9 +353,9 @@ Expression? getLateFieldInitializer(Member node) {
// }
//
// in case `<init>` is the initializer.
VariableDeclaration variableDeclaration =
block.statements.first as VariableDeclaration;
return variableDeclaration.initializer;
VariableStatement variableStatement =
block.statements.first as VariableStatement;
return variableStatement.variable.initializer;
}
}
return null;
@@ -778,11 +778,14 @@ mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
}
if (!_isExternal) {
VariableDeclaration thisVariable = this.thisVariable!;
List<Statement> statements = [thisVariable];
VariableStatement thisVariableStatement = extern.createVariableStatement(
thisVariable,
);
List<Statement> statements = [thisVariableStatement];
_ExtensionTypeInitializerToStatementConverter visitor =
new _ExtensionTypeInitializerToStatementConverter(
statements,
thisVariable,
thisVariableStatement,
);
for (Initializer initializer in _initializers) {
initializer.accept(visitor);
@@ -847,12 +850,12 @@ mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
class _ExtensionTypeInitializerToStatementConverter
implements InitializerVisitor<void> {
VariableDeclaration thisVariable;
VariableStatement thisVariableStatement;
final List<Statement> statements;
_ExtensionTypeInitializerToStatementConverter(
this.statements,
this.thisVariable,
this.thisVariableStatement,
);
@override
@@ -866,7 +869,7 @@ class _ExtensionTypeInitializerToStatementConverter
statements.add(
extern.createExpressionStatement(
extern.createVariableSet(
thisVariable,
thisVariableStatement.variable,
extern.createStaticInvocation(
node.target,
node.arguments.toArguments(
@@ -884,9 +887,10 @@ class _ExtensionTypeInitializerToStatementConverter
);
return;
} else if (node is ExtensionTypeRepresentationFieldInitializer) {
thisVariable
..initializer = (node.value..parent = thisVariable)
thisVariableStatement.variable
..initializer = (node.value..parent = thisVariableStatement.variable)
..fileOffset = node.fileOffset;
thisVariableStatement.fileOffset = node.fileOffset;
return;
}
// Coverage-ignore-block(suite): Not run.
@@ -898,9 +902,10 @@ class _ExtensionTypeInitializerToStatementConverter
@override
// Coverage-ignore(suite): Not run.
void visitFieldInitializer(FieldInitializer node) {
thisVariable
..initializer = (node.value..parent = thisVariable)
thisVariableStatement.variable
..initializer = (node.value..parent = thisVariableStatement.variable)
..fileOffset = node.fileOffset;
thisVariableStatement.fileOffset = node.fileOffset;
}
@override
@@ -917,7 +922,7 @@ class _ExtensionTypeInitializerToStatementConverter
@override
void visitLocalInitializer(LocalInitializer node) {
statements.add(node.variable);
statements.add(extern.createVariableStatement(node.variable));
}
@override
@@ -18,7 +18,6 @@ import '../../builder/metadata_builder.dart';
import '../../builder/property_builder.dart';
import '../../builder/type_builder.dart';
import '../../kernel/body_builder_context.dart';
import '../../kernel/external_ast_helper.dart';
import '../../kernel/external_ast_helper.dart' as extern;
import '../../kernel/hierarchy/class_member.dart';
import '../../kernel/hierarchy/members_builder.dart';
@@ -332,13 +331,13 @@ class RegularSetterDeclaration
// Add them as local variable to put them in scope of the body.
List<Statement> statements = <Statement>[];
for (FormalParameterBuilder parameter in declaredFormals) {
statements.add(parameter.variable);
statements.add(extern.createVariableStatement(parameter.variable));
}
statements.add(body);
body = createBlock(statements, fileOffset: fileOffset);
body = extern.createBlock(statements, fileOffset: fileOffset);
}
body = createBlock([
createExpressionStatement(
body = extern.createBlock([
extern.createExpressionStatement(
problemReporting.buildProblem(
compilerContext: compilerContext,
message: diag.setterWithWrongNumberOfFormals,
+75 -61
View File
@@ -3345,14 +3345,14 @@ class BodyBuilderImpl extends StackListenerImpl
}
pushNewLocalVariable(initializer, equalsToken: assignmentOperator);
if (isLate) {
VariableDeclaration node = peek() as VariableDeclaration;
VariableStatement node = peek() as VariableStatement;
// This is matched by the call to [beginNode] in
// [beginVariableInitializer].
// TODO(62401): Remove the cast when the flow analysis uses
// [InternalExpressionVariable]s.
assignedVariables.storeInfo(
(node.variable as InternalVariable).astVariable,
(node.variable.variable as InternalVariable).astVariable,
assignedVariablesInfo!,
);
}
@@ -3404,7 +3404,7 @@ class BodyBuilderImpl extends StackListenerImpl
name = createWildcardVariableName(wildcardVariableIndex);
wildcardVariableIndex++;
}
VariableDeclaration variableInitialization;
Statement variableInitialization;
InternalVariable internalVariable;
if (isClosureContextLoweringEnabled) {
internalVariable = new InternalLocalVariable(
@@ -3428,20 +3428,22 @@ class BodyBuilderImpl extends StackListenerImpl
fileOffset: offsetForToken(equalsToken),
);
} else {
variableInitialization = internalVariable = new VariableDeclarationImpl(
name,
forSyntheticToken: identifier.token.isSynthetic,
initializer: initializer,
type: currentLocalVariableType,
isFinal: isFinal,
isConst: isConst,
isLate: isLate,
isRequired: isRequired,
hasDeclaredInitializer: initializer != null,
isStaticLate: isFinal && initializer == null,
isWildcard: isWildcard,
fileOffset: identifier.nameOffset,
fileEqualsOffset: offsetForToken(equalsToken),
variableInitialization = intern.createVariableStatement(
internalVariable = new VariableDeclarationImpl(
name,
forSyntheticToken: identifier.token.isSynthetic,
initializer: initializer,
type: currentLocalVariableType,
isFinal: isFinal,
isConst: isConst,
isLate: isLate,
isRequired: isRequired,
hasDeclaredInitializer: initializer != null,
isStaticLate: isFinal && initializer == null,
isWildcard: isWildcard,
fileOffset: identifier.nameOffset,
fileEqualsOffset: offsetForToken(equalsToken),
),
);
}
assignedVariables.declare(internalVariable.astVariable);
@@ -3530,15 +3532,16 @@ class BodyBuilderImpl extends StackListenerImpl
push(node);
return;
}
VariableDeclaration variableInitialization = node as VariableDeclaration;
variableInitialization.fileOffset = nameToken.charOffset;
VariableStatement variableInitialization = node as VariableStatement;
variableInitialization.variable.fileOffset =
variableInitialization.fileOffset = nameToken.charOffset;
push(variableInitialization);
// Avoid adding the local identifier to scope if it's a wildcard.
// TODO(kallentu): Emit better error on lookup, rather than not adding it to
// the scope.
if (!(libraryFeatures.wildcardVariables.isEnabled &&
variableInitialization.isWildcard)) {
variableInitialization.variable.isWildcard)) {
declareVariable(variableInitialization.variable, _localScope);
}
}
@@ -3586,23 +3589,20 @@ class BodyBuilderImpl extends StackListenerImpl
push(node);
return;
}
VariableDeclaration variableInitialization = node as VariableDeclaration;
VariableStatement variableInitialization = node as VariableStatement;
if (annotations != null) {
for (int i = 0; i < annotations.length; i++) {
variableInitialization.addAnnotation(annotations[i]);
variableInitialization.variable.addAnnotation(annotations[i]);
}
_registerSingleTargetAnnotations(variableInitialization);
// (variablesWithMetadata ??= <VariableDeclaration>[]).add(
// variableInitialization,
// );
_registerSingleTargetAnnotations(variableInitialization.variable);
}
push(variableInitialization);
} else {
List<VariableDeclaration>? variables =
const FixedNullableList<VariableDeclaration>().popNonNullable(
List<VariableStatement>? variables =
const FixedNullableList<VariableStatement>().popNonNullable(
stack,
count,
dummyVariableDeclaration,
dummyVariableStatement,
);
constantContext = pop() as ConstantContext;
currentLocalVariableType = pop(NullValues.Type) as DartType?;
@@ -3613,11 +3613,13 @@ class BodyBuilderImpl extends StackListenerImpl
return;
}
if (annotations != null) {
VariableDeclaration first = variables.first;
VariableStatement first = variables.first;
for (int i = 0; i < annotations.length; i++) {
first.addAnnotation(annotations[i]);
first.variable.addAnnotation(annotations[i]);
}
_registerMultiTargetAnnotations(variables);
_registerMultiTargetAnnotations(
variables.map((v) => v.variable).toList(),
);
}
push(intern.variablesDeclaration(variables, uri));
}
@@ -3722,7 +3724,7 @@ class BodyBuilderImpl extends StackListenerImpl
}
}
List<VariableDeclaration>? _buildForLoopVariableDeclarations(
List<VariableStatement>? _buildForLoopVariableDeclarations(
variableOrExpression,
) {
// TODO(ahe): This can be simplified now that we have the events
@@ -3730,40 +3732,40 @@ class BodyBuilderImpl extends StackListenerImpl
if (variableOrExpression is Generator) {
variableOrExpression = variableOrExpression.buildForEffect();
}
if (variableOrExpression is VariableDeclaration) {
if (variableOrExpression is VariableStatement) {
// Late for loop variables are not supported. An error has already been
// reported by the parser.
variableOrExpression.isLate = false;
return <VariableDeclaration>[variableOrExpression];
variableOrExpression.variable.isLate = false;
return [variableOrExpression];
} else if (variableOrExpression is Expression) {
VariableDeclaration variable = new VariableDeclarationImpl.forEffect(
variableOrExpression,
);
return <VariableDeclaration>[variable];
return [intern.createVariableStatement(variable)];
} else if (variableOrExpression is ExpressionStatement) {
// Coverage-ignore-block(suite): Not run.
VariableDeclaration variable = new VariableDeclarationImpl.forEffect(
variableOrExpression.expression,
);
return <VariableDeclaration>[variable];
return [intern.createVariableStatement(variable)];
} else if (intern.isVariablesDeclaration(variableOrExpression)) {
return intern.variablesDeclarationExtractDeclarations(
variableOrExpression,
);
} else if (variableOrExpression is List<Object>) {
// Coverage-ignore-block(suite): Not run.
List<VariableDeclaration> variables = <VariableDeclaration>[];
List<VariableStatement> variables = [];
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 [];
} else if (variableOrExpression is ParserRecovery) {
return <VariableDeclaration>[];
return [];
} else if (variableOrExpression == null) {
return <VariableDeclaration>[];
return [];
}
return null;
}
@@ -3794,8 +3796,10 @@ class BodyBuilderImpl extends StackListenerImpl
// If the declaration is of the form `for (final x in ...)`, then we may
// have erroneously set the `isStaticLate` flag, so un-set it.
Object? declaration = peek();
if (declaration is VariableDeclarationImpl) {
declaration.isStaticLate = false;
if (declaration case VariableStatement(
:VariableDeclarationImpl variable,
)) {
variable.isStaticLate = false;
}
} else {
// This is matched by the call to [deferNode] in [endForStatement] or
@@ -3967,10 +3971,12 @@ class BodyBuilderImpl extends StackListenerImpl
.popNode();
Object? variableOrExpression = pop();
List<VariableDeclaration>? variables;
List<VariableStatement>? variables;
List<VariableDeclaration>? intermediateVariables;
if (variableOrExpression is PatternVariableDeclaration) {
variables = pop() as List<VariableDeclaration>; // Internal variables.
variables = (pop() as List<VariableDeclaration>)
.map(intern.createVariableStatement)
.toList(); // Internal variables.
intermediateVariables = pop() as List<VariableDeclaration>;
} else {
variables = _buildForLoopVariableDeclarations(variableOrExpression)!;
@@ -4086,10 +4092,12 @@ class BodyBuilderImpl extends StackListenerImpl
.deferNode();
Object? variableOrExpression = pop();
List<VariableDeclaration>? variables;
List<VariableStatement>? variables;
List<VariableDeclaration>? intermediateVariables;
if (variableOrExpression is PatternVariableDeclaration) {
variables = pop() as List<VariableDeclaration>;
variables = (pop() as List<VariableDeclaration>)
.map(intern.createVariableStatement)
.toList(); // Internal variables.
intermediateVariables = pop() as List<VariableDeclaration>;
} else {
variables = _buildForLoopVariableDeclarations(variableOrExpression);
@@ -4132,7 +4140,13 @@ class BodyBuilderImpl extends StackListenerImpl
result = intern.createBlock(
fileOffset: result.fileOffset,
fileEndOffset: result.fileOffset,
<Statement>[variableOrExpression, ...intermediateVariables!, result],
[
variableOrExpression,
for (VariableDeclaration intermediateVariable
in intermediateVariables!)
intern.createVariableStatement(intermediateVariable),
result,
],
);
}
if (variableOrExpression is ParserRecovery) {
@@ -8358,46 +8372,46 @@ class BodyBuilderImpl extends StackListenerImpl
lvalue.hasDeclaredInitializer = false;
// Late for-in variables are not supported. An error has already been
// reported by the parser.
lvalue.isLate = false;
lvalue.variable.isLate = false;
InvalidExpression? error;
if (lvalue.isConst) {
if (lvalue.variable.isConst) {
// Coverage-ignore-block(suite): Not run.
error = buildProblem(
message: diag.forInLoopWithConstVariable,
fileUri: uri,
fileOffset: lvalue.fileOffset,
length: lvalue.cosmeticName!.length,
length: lvalue.variable.cosmeticName!.length,
);
// As a recovery step, remove the const flag, to not confuse the
// constant evaluator further in the pipeline.
lvalue.isConst = false;
lvalue.variable.isConst = false;
}
return new VariableInitializationForInElement(
variableInitialization: lvalue,
error: error,
);
} else if (lvalue is VariableDeclaration) {
} else if (lvalue is LegacyVariableStatement) {
// Variable initializers are not supported. An error has already been
// reported by the parser.
lvalue.initializer = null;
lvalue.hasDeclaredInitializer = false;
lvalue.variable.initializer = null;
lvalue.variable.hasDeclaredInitializer = false;
// Late for-in variables are not supported. An error has already been
// reported by the parser.
lvalue.isLate = false;
lvalue.variable.isLate = false;
InvalidExpression? error;
if (lvalue.isConst) {
if (lvalue.variable.isConst) {
error = buildProblem(
message: diag.forInLoopWithConstVariable,
fileUri: uri,
fileOffset: lvalue.fileOffset,
length: lvalue.cosmeticName!.length,
length: lvalue.variable.cosmeticName!.length,
);
// As a recovery step, remove the const flag, to not confuse the
// constant evaluator further in the pipeline.
lvalue.isConst = false;
lvalue.variable.isConst = false;
}
return new SingleVariableDeclarationForInElement(
variableDeclaration: lvalue,
variableStatement: lvalue,
error: error,
);
} else if (lvalue is Generator) {
+14 -14
View File
@@ -222,10 +222,10 @@ class ForElement extends ControlFlowElement
implements ForElementBase {
// May be empty, but not null.
@override
final List<VariableDeclaration> variableInitializations;
final List<VariableStatement> variableInitializations;
@override
List<VariableDeclaration> get variables => variableInitializations.cast();
List<VariableStatement> get variables => variableInitializations;
@override
Expression? condition; // May be null.
@@ -283,7 +283,7 @@ class ForElement extends ControlFlowElement
printer.write(', ');
}
printer.writeVariableInitialization(
variableInitializations[index],
variableInitializations[index].variable,
includeModifiersAndType: index == 0,
);
}
@@ -462,9 +462,9 @@ class IfCaseElement extends ControlFlowElementImpl
}
abstract interface class ForElementBase implements AuxiliaryExpression {
List<VariableDeclaration> get variableInitializations;
List<VariableStatement> get variableInitializations;
List<VariableDeclaration> get variables;
List<VariableStatement> get variables;
abstract Expression? condition;
@@ -481,10 +481,10 @@ class PatternForElement extends ControlFlowElementImpl
// May be empty, but not null.
@override
final List<VariableDeclaration> variableInitializations;
final List<VariableStatement> variableInitializations;
@override
List<VariableDeclaration> get variables => variableInitializations.cast();
List<VariableStatement> get variables => variableInitializations;
@override
Expression? condition; // May be null.
@@ -498,7 +498,7 @@ class PatternForElement extends ControlFlowElementImpl
PatternForElement({
required this.patternVariableDeclaration,
required this.intermediateVariables,
required List<VariableDeclaration> variables,
required List<VariableStatement> variables,
required this.condition,
required this.updates,
required this.body,
@@ -522,7 +522,7 @@ class PatternForElement extends ControlFlowElementImpl
printer.write(', ');
}
printer.writeVariableInitialization(
variableInitializations[index],
variableInitializations[index].variable,
includeModifiersAndType: index == 0,
);
}
@@ -689,7 +689,7 @@ class IfMapEntry extends TreeNode
}
abstract interface class ForMapEntryBase implements TreeNode, MapLiteralEntry {
List<VariableDeclaration> get variables;
List<VariableStatement> get variables;
abstract Expression? condition;
@@ -704,7 +704,7 @@ class ForMapEntry extends TreeNode
implements ForMapEntryBase, ControlFlowMapEntry {
// May be empty, but not null.
@override
final List<VariableDeclaration> variables;
final List<VariableStatement> variables;
@override
Expression? condition; // May be null.
@@ -736,7 +736,7 @@ class ForMapEntry extends TreeNode
printer.write(', ');
}
printer.writeVariableInitialization(
variables[index],
variables[index].variable,
includeModifiersAndType: index == 0,
);
}
@@ -758,7 +758,7 @@ class PatternForMapEntry extends TreeNode
List<VariableDeclaration> intermediateVariables;
@override
final List<VariableDeclaration> variables;
final List<VariableStatement> variables;
@override
Expression? condition;
@@ -788,7 +788,7 @@ class PatternForMapEntry extends TreeNode
printer.write(', ');
}
printer.writeVariableInitialization(
variables[index],
variables[index].variable,
includeModifiersAndType: index == 0,
);
}
@@ -447,7 +447,28 @@ class ConstantsTransformer extends RemovingTransformer {
}
@override
TreeNode visitVariableDeclaration(
TreeNode visitLegacyVariableStatement(
LegacyVariableStatement node,
TreeNode? removalSentinel,
) {
if (removalSentinel != null) {
VariableDeclaration? variable = transformOrRemoveVariableDeclaration(
node.variable,
);
if (variable == null) {
return removalSentinel;
}
node.variable = variable..parent = node;
return node;
} else {
// Coverage-ignore-block(suite): Not run.
node.variable = transform(node.variable)..parent = node;
return node;
}
}
@override
TreeNode defaultVariableDeclaration(
VariableDeclaration node,
TreeNode? removalSentinel,
) {
@@ -1107,7 +1128,12 @@ class ConstantsTransformer extends RemovingTransformer {
if (isContinueTarget) {
// TODO(johnniwinther): In this case it should be an error to have
// any variables. This is not currently reported.
replacementStatements.addAll(pattern.declaredVariables);
for (VariableDeclaration declaredVariable
in pattern.declaredVariables) {
replacementStatements.add(
extern.createVariableStatement(declaredVariable),
);
}
for (VariableDeclaration variable in pattern.declaredVariables) {
(declaredVariablesByName[variable.name!] ??= []).add(variable);
@@ -1247,7 +1273,9 @@ class ConstantsTransformer extends RemovingTransformer {
],
[node.fileOffset],
extern.createBlock([
...switchCase.jointVariables,
for (VariableDeclaration jointVariable
in switchCase.jointVariables)
extern.createVariableStatement(jointVariable),
if (body is! Block || body.statements.isNotEmpty) body,
], fileOffset: node.fileOffset),
isDefault: switchCase.isDefault,
@@ -1269,7 +1297,8 @@ class ConstantsTransformer extends RemovingTransformer {
replacementCases.add(replacementCase);
} else {
caseBlock = extern.createBlock([
...switchCase.jointVariables,
for (VariableDeclaration jointVariable in switchCase.jointVariables)
extern.createVariableStatement(jointVariable),
if (body is! Block || body.statements.isNotEmpty) body,
], fileOffset: switchCase.fileOffset);
}
@@ -1302,7 +1331,8 @@ class ConstantsTransformer extends RemovingTransformer {
}
cases.add(
extern.createBlock([
...caseVariables,
for (VariableDeclaration caseVariable in caseVariables)
extern.createVariableStatement(caseVariable),
caseBlock,
if (breakStatement != null)
// Coverage-ignore(suite): Not run.
@@ -1355,10 +1385,13 @@ class ConstantsTransformer extends RemovingTransformer {
);
innerLabeledStatement.body = casesBlock..parent = innerLabeledStatement;
replacementStatements = [
matchResultVariable,
extern.createVariableStatement(matchResultVariable),
...replacementStatements,
...matchingCache.declarations,
...declaredVariableHelpers,
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
for (VariableDeclaration declaredVariableHelper
in declaredVariableHelpers)
extern.createVariableStatement(declaredVariableHelper),
innerLabeledStatement,
extern.createSwitchStatement(
extern.createVariableGet(matchResultVariable),
@@ -1371,8 +1404,11 @@ class ConstantsTransformer extends RemovingTransformer {
} else {
replacementStatements = [
...replacementStatements,
...matchingCache.declarations,
...declaredVariableHelpers,
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
for (VariableDeclaration declaredVariableHelper
in declaredVariableHelpers)
extern.createVariableStatement(declaredVariableHelper),
...cases,
];
}
@@ -1609,15 +1645,19 @@ class ConstantsTransformer extends RemovingTransformer {
}
}
List<Statement> cacheVariables = [...matchingCache.declarations];
Iterable<Statement> declarations =
List<Statement> cacheVariables = [
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
];
Iterable<VariableDeclaration> declarations =
node.patternGuard.pattern.declaredVariables;
Statement ifStatement;
if (declarations.isNotEmpty) {
// If we need local declarations, create a new block to avoid naming
// collision with declarations in the same parent block.
ifStatement = extern.createBlock([
...declarations,
for (VariableDeclaration declaration in declarations)
extern.createVariableStatement(declaration),
extern.createIfStatement(
condition,
then,
@@ -1680,7 +1720,8 @@ class ConstantsTransformer extends RemovingTransformer {
replacementStatements,
);
replacementStatements = [
...matchingCache.declarations,
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
...replacementStatements,
];
} else {
@@ -1689,7 +1730,8 @@ class ConstantsTransformer extends RemovingTransformer {
inCacheInitializer: false,
);
replacementStatements = [
...matchingCache.declarations,
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
// TODO(cstefantsova): Provide a better diagnostic message.
extern.createIfStatement(
extern.createNot(readMatchingExpression),
@@ -1720,7 +1762,9 @@ class ConstantsTransformer extends RemovingTransformer {
];
}
replacementStatements = [
...node.pattern.declaredVariables,
for (VariableDeclaration declaredVariable
in node.pattern.declaredVariables)
extern.createVariableStatement(declaredVariable),
...replacementStatements,
];
@@ -1770,8 +1814,12 @@ class ConstantsTransformer extends RemovingTransformer {
effects: effects,
);
replacementStatements = [
...matchingCache.declarations,
...node.pattern.declaredVariables,
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
for (VariableDeclaration declaredVariable
in node.pattern.declaredVariables)
extern // Coverage-ignore(suite): Not run.
.createVariableStatement(declaredVariable),
...replacementStatements,
...effects,
];
@@ -1784,8 +1832,12 @@ class ConstantsTransformer extends RemovingTransformer {
);
replacementStatements = [
...matchingCache.declarations,
...node.pattern.declaredVariables,
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
for (VariableDeclaration declaredVariable
in node.pattern.declaredVariables)
extern // Coverage-ignore(suite): Not run.
.createVariableStatement(declaredVariable),
// TODO(cstefantsova): Provide a better diagnostic message.
extern.createIfStatement(
extern.createNot(readMatchingExpression),
@@ -2005,7 +2057,7 @@ class ConstantsTransformer extends RemovingTransformer {
)..parent = labeledStatement;
replacement = extern.createBlockExpression(
extern.createBlock([
valueVariable,
extern.createVariableStatement(valueVariable),
labeledStatement,
], fileOffset: node.fileOffset),
extern.createVariableGet(valueVariable),
@@ -2110,7 +2162,9 @@ class ConstantsTransformer extends RemovingTransformer {
cases.add(
extern.createBlock([
...pattern.declaredVariables,
for (VariableDeclaration declaredVariable
in pattern.declaredVariables)
extern.createVariableStatement(declaredVariable),
extern.createIfStatement(
caseCondition,
extern.createBlock([
@@ -2173,8 +2227,9 @@ class ConstantsTransformer extends RemovingTransformer {
)..parent = labeledStatement;
replacement = extern.createBlockExpression(
extern.createBlock([
valueVariable,
...matchingCache.declarations,
extern.createVariableStatement(valueVariable),
for (VariableDeclaration declaration in matchingCache.declarations)
extern.createVariableStatement(declaration),
labeledStatement,
], fileOffset: node.fileOffset),
extern.createVariableGet(valueVariable),
@@ -6048,8 +6103,12 @@ class ConstantEvaluator
}
class StatementConstantEvaluator
with StatementVisitorExperimentExclusionMixin<ExecutionStatus>
implements StatementVisitor<ExecutionStatus> {
with
StatementVisitorExperimentExclusionMixin<ExecutionStatus>,
VariableVisitorExperimentExclusionMixin<ExecutionStatus>
implements
StatementVisitor<ExecutionStatus>,
VariableVisitor<ExecutionStatus> {
ConstantEvaluator exprEvaluator;
StatementConstantEvaluator(this.exprEvaluator);
@@ -6145,7 +6204,7 @@ class StatementConstantEvaluator
@override
ExecutionStatus visitForStatement(ForStatement node) {
for (VariableDeclaration variable in node.variables) {
for (VariableStatement variable in node.variables) {
final ExecutionStatus status = variable.accept(this);
if (status is! ProceedStatus) return status;
}
@@ -376,9 +376,9 @@ class DartScopeBuilder2 extends VisitorDefault<void> with VisitorVoidMixin {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
if (node.isHoisted) hoistedUnwritten.add(node);
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
// Declare it after.
scopes.last.add(node);
}
@@ -916,3 +916,7 @@ Expression createVariableSet(
return new VariableSet(variable, value)..fileOffset = fileOffset;
}
}
VariableStatement createVariableStatement(VariableDeclaration variable) {
return new VariableStatement(variable)..fileOffset = variable.fileOffset;
}
+33 -34
View File
@@ -969,7 +969,7 @@ class ReturnStatementImpl extends ReturnStatement {
}
/// Front end specific implementation of [VariableDeclaration].
class VariableDeclarationImpl extends VariableStatement
class VariableDeclarationImpl extends LegacyVariable
with InternalVariableMixin
implements InternalVariable {
@override
@@ -1059,7 +1059,6 @@ class VariableDeclarationImpl extends VariableStatement
isLate: isLate || lateGetter != null,
type: lateType ?? type,
);
printer.write(';');
}
@override
@@ -1095,11 +1094,11 @@ class InternalLocalVariable extends TreeNode
@override
// Coverage-ignore(suite): Not run.
R accept<R>(StatementVisitor<R> v) => v.visitLocalVariable(astVariable);
R accept<R>(VariableVisitor<R> v) => v.visitLocalVariable(astVariable);
@override
// Coverage-ignore(suite): Not run.
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitLocalVariable(astVariable, arg);
@override
@@ -1125,13 +1124,12 @@ class InternalLocalVariable extends TreeNode
int binaryOffsetNoTag = -1;
@override
List<VariableContext>? get capturedContexts {
throw new UnsupportedError("${this.runtimeType}.capturedContexts");
}
List<VariableContext>? get capturedContexts =>
variableInitialization?.capturedContexts;
@override
void set capturedContexts(List<VariableContext>? value) {
throw new UnsupportedError("${this.runtimeType}.capturedContexts=");
variableInitialization!.capturedContexts = value;
}
@override
@@ -1190,11 +1188,11 @@ class InternalPositionalParameter extends TreeNode
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitPositionalParameter(astVariable);
R accept<R>(VariableVisitor<R> v) => v.visitPositionalParameter(astVariable);
@override
// Coverage-ignore(suite): Not run.
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitPositionalParameter(astVariable, arg);
@override
@@ -1296,11 +1294,11 @@ class InternalNamedParameter extends TreeNode
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitNamedParameter(astVariable);
R accept<R>(VariableVisitor<R> v) => v.visitNamedParameter(astVariable);
@override
// Coverage-ignore(suite): Not run.
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitNamedParameter(astVariable, arg);
@override
@@ -1524,7 +1522,6 @@ mixin DelegatingVariableMixin on InternalVariableMixin
Expression? get initializer => astVariable.initializer;
@override
// Coverage-ignore(suite): Not run.
void set initializer(Expression? value) {
astVariable.initializer = value;
}
@@ -1658,12 +1655,11 @@ mixin DelegatingVariableMixin on InternalVariableMixin
}
@override
// Coverage-ignore(suite): Not run.
VariableDeclaration? get variableInitialization =>
VariableInitialization? get variableInitialization =>
astVariable.variableInitialization;
@override
void set variableInitialization(VariableDeclaration? value) {
void set variableInitialization(VariableInitialization? value) {
astVariable.variableInitialization = value;
}
@@ -1735,13 +1731,13 @@ mixin DelegatingVariableMixin on InternalVariableMixin
@override
// Coverage-ignore(suite): Not run.
R accept<R>(StatementVisitor<R> v) {
R accept<R>(VariableVisitor<R> v) {
return astVariable.accept(v);
}
@override
// Coverage-ignore(suite): Not run.
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) {
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) {
return astVariable.accept1(v, arg);
}
@@ -5835,7 +5831,9 @@ sealed class _VariableForInElement extends _BaseForInElement {
}) {
return new ForInEncoding(
preLoopError: error,
bodyPrologue: _variableForSideEffect,
bodyPrologue: _variableForSideEffect != null
? extern.createVariableStatement(_variableForSideEffect!)
: null,
);
}
}
@@ -5858,7 +5856,7 @@ class VariableInitializationForInElement extends _VariableForInElement {
// Coverage-ignore(suite): Not run.
void toTextInternal(AstPrinter printer) {
printer.writeVariableInitialization(
variableInitialization,
variableInitialization.variable,
includeInitializer: false,
isImplicitlyTyped:
(variableInitialization.variable is InternalVariable) &&
@@ -5881,36 +5879,36 @@ class VariableInitializationForInElement extends _VariableForInElement {
/// For-in element for a single declared variable.
class SingleVariableDeclarationForInElement extends _VariableForInElement {
/// The declared variable.
final VariableDeclaration variableDeclaration;
final LegacyVariableStatement variableStatement;
SingleVariableDeclarationForInElement({
required this.variableDeclaration,
required this.variableStatement,
required super.error,
});
@override
VariableDeclaration get _variableDeclaration => variableDeclaration;
VariableDeclaration get _variableDeclaration => variableStatement.variable;
@override
// Coverage-ignore(suite): Not run.
void toTextInternal(AstPrinter printer) {
printer.writeVariableInitialization(
variableDeclaration,
variableStatement.variable,
includeInitializer: false,
isImplicitlyTyped:
variableDeclaration.variable is InternalVariable &&
(variableDeclaration.variable as InternalVariable).isImplicitlyTyped,
variableStatement.variable is InternalVariable &&
(variableStatement.variable as InternalVariable).isImplicitlyTyped,
);
}
@override
DartType _computeElementTypeContext(InferenceVisitorBase visitor) {
if (variableDeclaration case InternalVariable variable) {
if (variableStatement.variable case InternalVariable variable) {
if (variable.isImplicitlyTyped) {
return const UnknownType();
}
}
return variableDeclaration.type;
return variableStatement.variable.type;
}
}
@@ -5918,7 +5916,7 @@ class SingleVariableDeclarationForInElement extends _VariableForInElement {
/// `for (var a, b in [])`. This is an error case.
class MultiVariableDeclarationForInElement extends _BaseForInElement {
/// The declared variables.
final List<VariableDeclaration> variableDeclarations;
final List<VariableStatement> variableDeclarations;
/// The error that should be emitted prior to the for-in statement.
final InvalidExpression error;
@@ -5932,20 +5930,21 @@ class MultiVariableDeclarationForInElement extends _BaseForInElement {
// Coverage-ignore(suite): Not run.
void toTextInternal(AstPrinter printer) {
for (int i = 0; i < variableDeclarations.length; i++) {
VariableDeclaration variableDeclaration = variableDeclarations[i];
VariableStatement variableDeclaration = variableDeclarations[i];
if (i == 0) {
printer.writeVariableInitialization(
variableDeclaration,
variableDeclaration.variable,
includeModifiersAndType: true,
includeInitializer: false,
isImplicitlyTyped:
variableDeclaration is InternalVariable &&
(variableDeclaration as InternalVariable).isImplicitlyTyped,
variableDeclaration.variable is InternalVariable &&
(variableDeclaration.variable as InternalVariable)
.isImplicitlyTyped,
);
} else {
printer.write(', ');
printer.writeVariableInitialization(
variableDeclaration,
variableDeclaration.variable,
includeModifiersAndType: false,
includeInitializer: false,
);
@@ -302,7 +302,7 @@ Statement createExpressionStatement(
ForElement createForElement(
int fileOffset,
List<VariableDeclaration> variables,
List<VariableStatement> variables,
Expression? condition,
List<Expression> updates,
Expression body,
@@ -363,7 +363,7 @@ ForInStatement createForInStatement(
ForMapEntry createForMapEntry(
int fileOffset,
List<VariableDeclaration> variables,
List<VariableStatement> variables,
Expression? condition,
List<Expression> updates,
MapLiteralEntry body,
@@ -375,7 +375,7 @@ ForMapEntry createForMapEntry(
/// Return a representation of a for statement.
Statement createForStatement(
int fileOffset,
List<VariableDeclaration>? variables,
List<VariableStatement>? variables,
Expression? condition,
List<Expression> updaters,
Statement body,
@@ -810,7 +810,7 @@ PatternForElement createPatternForElement(
int fileOffset, {
required PatternVariableDeclaration patternVariableDeclaration,
required List<VariableDeclaration> intermediateVariables,
required List<VariableDeclaration> variables,
required List<VariableStatement> variables,
required Expression? condition,
required List<Expression> updates,
required Expression body,
@@ -829,7 +829,7 @@ PatternForMapEntry createPatternForMapEntry(
int fileOffset, {
required PatternVariableDeclaration patternVariableDeclaration,
required List<VariableDeclaration> intermediateVariables,
required List<VariableDeclaration> variableInitializations,
required List<VariableStatement> variableInitializations,
required Expression? condition,
required List<Expression> updates,
required MapLiteralEntry body,
@@ -1240,6 +1240,10 @@ InternalVariableSet createVariableSet(
..fileOffset = fileOffset;
}
VariableStatement createVariableStatement(VariableDeclaration variable) {
return new VariableStatement(variable)..fileOffset = variable.fileOffset;
}
/// Return a representation of a while statement at the given [fileOffset]
/// consisting of the given [condition] and [body].
Statement createWhileStatement(
@@ -1291,13 +1295,13 @@ bool isThisExpression(Object node) =>
bool isVariablesDeclaration(Object? node) => node is _VariablesDeclaration;
_VariablesDeclaration variablesDeclaration(
List<VariableDeclaration> declarations,
List<VariableStatement> declarations,
Uri uri,
) {
return new _VariablesDeclaration(declarations, uri);
}
List<VariableDeclaration> variablesDeclarationExtractDeclarations(
List<VariableStatement> variablesDeclarationExtractDeclarations(
Object? variablesDeclaration,
) {
return (variablesDeclaration as _VariablesDeclaration).declarations;
@@ -1306,9 +1310,13 @@ List<VariableDeclaration> variablesDeclarationExtractDeclarations(
Statement wrapVariables(Statement statement) {
if (statement is _VariablesDeclaration) {
return new Block(
new List<Statement>.of(statement.declarations, growable: true),
new List<Statement>.generate(
statement.declarations.length,
(int index) => statement.declarations[index],
growable: true,
),
)..fileOffset = statement.fileOffset;
} else if (statement is VariableDeclaration) {
} else if (statement is VariableStatement) {
return new Block(<Statement>[statement])..fileOffset = statement.fileOffset;
} else {
return statement;
@@ -1316,7 +1324,7 @@ Statement wrapVariables(Statement statement) {
}
class _VariablesDeclaration extends AuxiliaryStatement {
final List<VariableDeclaration> declarations;
final List<VariableStatement> declarations;
final Uri uri;
_VariablesDeclaration(this.declarations, this.uri) {
@@ -1348,7 +1356,7 @@ class _VariablesDeclaration extends AuxiliaryStatement {
printer.write(', ');
}
printer.writeVariableInitialization(
declarations[index],
declarations[index].variable,
includeModifiersAndType: index == 0,
);
}
@@ -158,7 +158,7 @@ Statement createGetterWithInitializerWithRecheck(
new Not(createIsSetRead()..fileOffset = fileOffset)
..fileOffset = fileOffset,
new Block(<Statement>[
temp,
new VariableStatement(temp)..fileOffset = temp.fileOffset,
new IfStatement(
createIsSetRead()..fileOffset = fileOffset,
new ExpressionStatement(exception)..fileOffset = fileOffset,
@@ -334,7 +334,7 @@ abstract class DataExtractor<T> extends VisitorDefault<void>
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
if (node.name != null && node.parent is! FunctionDeclaration) {
// Skip synthetic variables and function declaration variables.
computeForNode(
@@ -3441,9 +3441,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
scopeProviderInfoKind: ScopeProviderInfoKind.Loop,
);
}
List<VariableDeclaration>? variables;
List<VariableStatement>? variables;
for (int index = 0; index < node.variables.length; index++) {
VariableDeclaration variable = node.variables[index];
VariableStatement variableStatement = node.variables[index];
VariableDeclaration variable = variableStatement.variable;
if (variable.name == null) {
if (variable.initializer != null) {
ExpressionInferenceResult result = inferExpression(
@@ -3455,24 +3456,26 @@ class InferenceVisitorImpl extends InferenceVisitorBase
variable.type = result.inferredType;
}
} else {
StatementInferenceResult variableResult = inferStatement(variable);
StatementInferenceResult variableResult = inferStatement(
variableStatement,
);
if (variableResult.hasChanged) {
// Coverage-ignore-block(suite): Not run.
if (variables == null) {
variables = <VariableDeclaration>[];
variables = [];
variables.addAll(node.variables.sublist(0, index));
}
if (variableResult.statementCount == 1) {
variables.add(variableResult.statement as VariableDeclaration);
variables.add(variableResult.statement as VariableStatement);
} else {
for (Statement variable in variableResult.statements) {
variables.add(variable as VariableDeclaration);
variables.add(variable as VariableStatement);
}
}
}
// Coverage-ignore(suite): Not run.
else if (variables != null) {
variables.add(variable);
variables.add(variableStatement);
}
}
}
@@ -4368,7 +4371,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
).expression..parent = intermediateVariable;
intermediateVariable.type = type;
element.variableInitializations[i].type = type;
element.variableInitializations[i].variable.type = type;
}
return _inferForElementBase(
@@ -4400,13 +4403,15 @@ class InferenceVisitorImpl extends InferenceVisitorBase
Map<Expression, DartType> inferredConditionTypes,
) {
// TODO(johnniwinther): Use _visitStatements instead.
List<VariableDeclaration>? variables;
List<VariableStatement>? variables;
for (
int index = 0;
index < element.variableInitializations.length;
index++
) {
VariableDeclaration variable = element.variableInitializations[index];
VariableStatement variableStatement =
element.variableInitializations[index];
VariableDeclaration variable = variableStatement.variable;
if (variable.name == null) {
if (variable.initializer != null) {
ExpressionInferenceResult initializerResult = inferExpression(
@@ -4419,24 +4424,26 @@ class InferenceVisitorImpl extends InferenceVisitorBase
variable.type = initializerResult.inferredType;
}
} else {
StatementInferenceResult variableResult = inferStatement(variable);
StatementInferenceResult variableResult = inferStatement(
variableStatement,
);
if (variableResult.hasChanged) {
// Coverage-ignore-block(suite): Not run.
if (variables == null) {
variables = <VariableDeclaration>[];
variables = [];
variables.addAll(element.variableInitializations.sublist(0, index));
}
if (variableResult.statementCount == 1) {
variables.add(variableResult.statement as VariableDeclaration);
variables.add(variableResult.statement as VariableStatement);
} else {
for (Statement variable in variableResult.statements) {
variables.add(variable as VariableDeclaration);
variables.add(variable as VariableStatement);
}
}
}
// Coverage-ignore(suite): Not run.
else if (variables != null) {
variables.add(variable);
variables.add(variableStatement);
}
}
}
@@ -4999,7 +5006,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
)..fileOffset = node.fileOffset,
receiverType,
);
body = [result];
body = [extern.createVariableStatement(result)];
// Add the elements up to the first non-expression.
for (int j = 0; j < index; ++j) {
_addExpressionElement(
@@ -5024,7 +5031,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
);
}
}
body ??= [result];
body ??= [extern.createVariableStatement(result)];
// Translate the elements starting with the first non-expression.
for (; index < elements.length; ++index) {
_translateElement(
@@ -5317,7 +5324,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
// Coverage-ignore(suite): Not run.
?.registerAlias(element, loop);
body.add(element.patternVariableDeclaration);
body.addAll(element.intermediateVariables);
for (VariableDeclaration intermediateVariable
in element.intermediateVariables) {
body.add(extern.createVariableStatement(intermediateVariable));
}
body.add(loop);
}
@@ -5394,7 +5404,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
value,
typeSchemaEnvironment.iterableType(elementType, Nullability.nullable),
);
body.add(temp);
body.add(extern.createVariableStatement(temp));
value = _createNullCheckedVariableGet(temp);
}
@@ -5428,7 +5438,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
Nullability.nullable,
),
);
body.add(temp);
body.add(extern.createVariableStatement(temp));
value = _createNullCheckedVariableGet(temp);
}
@@ -5445,7 +5455,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
elementType,
);
Statement loopBody = _createBlock(<Statement>[
castedVar,
extern.createVariableStatement(castedVar),
_createExpressionStatement(
_createAdd(
// Don't make a mess of jumping around (and make scope building
@@ -5505,7 +5515,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
Nullability.nullable,
);
VariableDeclaration temp = _createVariable(value, nullableElementType);
body.add(temp);
body.add(extern.createVariableStatement(temp));
Statement statement = _createIf(
temp.fileOffset,
@@ -5622,14 +5632,14 @@ class InferenceVisitorImpl extends InferenceVisitorBase
_createMapLiteral(node.fileOffset, node.keyType, node.valueType, []),
receiverType,
);
body = [result];
body = [extern.createVariableStatement(result)];
// Add all the entries up to the first control-flow entry.
for (int j = 0; j < index; ++j) {
_addNormalEntry(node.entries[j], receiverType, result, body);
}
}
body ??= [result];
body ??= [extern.createVariableStatement(result)];
// Translate the elements starting with the first non-expression.
for (; index < node.entries.length; ++index) {
@@ -5919,7 +5929,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
// Coverage-ignore(suite): Not run.
?.registerAlias(entry, loop);
body.add(entry.patternVariableDeclaration);
body.addAll(entry.intermediateVariables);
for (VariableDeclaration intermediateVariable
in entry.intermediateVariables) {
body.add(extern.createVariableStatement(intermediateVariable));
}
body.add(loop);
}
@@ -6007,7 +6020,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
Nullability.nullable,
),
);
body.add(temp);
body.add(extern.createVariableStatement(temp));
value = _createNullCheckedVariableGet(temp);
}
@@ -6041,7 +6054,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
Nullability.nullable,
),
);
body.add(temp);
body.add(extern.createVariableStatement(temp));
value = _createNullCheckedVariableGet(temp);
}
@@ -6079,8 +6092,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
valueType,
);
Statement loopBody = _createBlock(<Statement>[
keyVar,
valueVar,
extern.createVariableStatement(keyVar),
extern.createVariableStatement(valueVar),
_createExpressionStatement(
_createIndexSet(
entry.expression.fileOffset,
@@ -6169,8 +6182,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
);
addedEntryStatementParent ??= ifValueNotNullStatement;
desugaredStatement = _createBlock([valueTemp, ifValueNotNullStatement])
..fileOffset = entry.fileOffset;
desugaredStatement = _createBlock([
extern.createVariableStatement(valueTemp),
ifValueNotNullStatement,
])..fileOffset = entry.fileOffset;
}
if (entry.isKeyNullAware) {
@@ -6190,8 +6205,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
);
addedEntryStatementParent ??= ifKeyNotNullStatement;
desugaredStatement = _createBlock([keyTemp, ifKeyNotNullStatement])
..fileOffset = entry.fileOffset;
desugaredStatement = _createBlock([
extern.createVariableStatement(keyTemp),
ifKeyNotNullStatement,
])..fileOffset = entry.fileOffset;
} else if (entry.isValueNullAware) {
assert(!entry.isKeyNullAware);
// The key is non null-aware, but the value is null-aware. In this case,
@@ -6222,7 +6239,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
VariableDeclaration keyTemp = _createVariable(keyExpression, keyType);
keyExpression = _createVariableGet(keyTemp);
desugaredStatement.statements.insert(0, keyTemp);
desugaredStatement.statements.insert(
0,
extern.createVariableStatement(keyTemp),
);
keyTemp.parent = desugaredStatement;
}
@@ -6877,7 +6897,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
ForStatement _createForStatement(
int fileOffset,
List<VariableDeclaration> variables,
List<VariableStatement> variables,
Expression? condition,
List<Expression> updates,
Statement body,
@@ -7497,7 +7517,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
).expression..parent = intermediateVariable;
intermediateVariable.type = type;
entry.variables[i].type = type;
entry.variables[i].variable.type = type;
}
return _inferForMapEntryBase(
@@ -7553,9 +7573,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
_MapLiteralEntryOffsets offsets,
) {
// TODO(johnniwinther): Use _visitStatements instead.
List<VariableDeclaration>? variables;
List<VariableStatement>? variables;
for (int index = 0; index < entry.variables.length; index++) {
VariableDeclaration variable = entry.variables[index];
VariableStatement variableStatement = entry.variables[index];
VariableDeclaration variable = variableStatement.variable;
if (variable.name == null) {
if (variable.initializer != null) {
ExpressionInferenceResult result = inferExpression(
@@ -7567,24 +7588,26 @@ class InferenceVisitorImpl extends InferenceVisitorBase
variable.type = result.inferredType;
}
} else {
StatementInferenceResult variableResult = inferStatement(variable);
StatementInferenceResult variableResult = inferStatement(
variableStatement,
);
if (variableResult.hasChanged) {
// Coverage-ignore-block(suite): Not run.
if (variables == null) {
variables = <VariableDeclaration>[];
variables = [];
variables.addAll(entry.variables.sublist(0, index));
}
if (variableResult.statementCount == 1) {
variables.add(variableResult.statement as VariableDeclaration);
variables.add(variableResult.statement as VariableStatement);
} else {
for (Statement variable in variableResult.statements) {
variables.add(variable as VariableDeclaration);
variables.add(variable as VariableStatement);
}
}
}
// Coverage-ignore(suite): Not run.
else if (variables != null) {
variables.add(variable);
variables.add(variableStatement);
}
}
}
@@ -12533,7 +12556,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
);
// Now create a list of all statements needed.
List<Statement> statements = [setVar];
List<Statement> statements = [extern.createVariableStatement(setVar)];
for (int i = 0; i < node.expressions.length; i++) {
Expression entry = node.expressions[i];
DartType functionType = Substitution.fromInterfaceType(
@@ -13402,6 +13425,29 @@ class InferenceVisitorImpl extends InferenceVisitorBase
}
@override
StatementInferenceResult visitLegacyVariableStatement(
LegacyVariableStatement node,
) {
InternalVariable nodeVariable = node.variable as InternalVariable;
StatementInferenceResult statementInferenceResult =
_inferInternalExpressionVariableDeclaration(
node.variable,
nodeVariable,
variableStatement: node,
);
node.variable = nodeVariable.astVariable;
if (isClosureContextLoweringEnabled) {
// Coverage-ignore-block(suite): Not run.
_contextAllocationStrategy.handleDeclarationOfVariable(
node.variable,
captureKind: _captureKindForVariable(node.variable),
);
}
return statementInferenceResult;
}
@override
// Coverage-ignore(suite): Not run.
StatementInferenceResult visitVariableDeclaration(
covariant VariableDeclarationImpl node,
) {
@@ -16760,7 +16806,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase
) {
InternalVariable nodeVariable = node.variable as InternalVariable;
StatementInferenceResult statementInferenceResult =
_inferInternalExpressionVariableDeclaration(node, nodeVariable);
_inferInternalExpressionVariableDeclaration(
node.variable,
nodeVariable,
variableStatement: node,
);
node.variable = nodeVariable.astVariable;
if (isClosureContextLoweringEnabled) {
_contextAllocationStrategy.handleDeclarationOfVariable(
@@ -16773,8 +16823,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
StatementInferenceResult _inferInternalExpressionVariableDeclaration(
VariableDeclaration node,
InternalVariable nodeVariable,
) {
InternalVariable nodeVariable, {
VariableStatement? variableStatement,
}) {
DartType declaredType = nodeVariable.isImplicitlyTyped
? const UnknownType()
: node.type;
@@ -16785,7 +16836,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
// for loops, const variables, and late variables. This logic turns them
// into `ExpressionStatement`s or `EmptyStatement`s so the backends don't
// need to allocate space for them.
if (node.isWildcard && !node.isConst && node.parent is! ForStatement) {
if (node.isWildcard &&
!node.isConst &&
node.parent?.parent is! ForStatement) {
if (node.initializer case var initializer? when !node.isLate) {
return new StatementInferenceResult.single(
createExpressionStatement(
@@ -16871,7 +16924,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
int fileOffset = node.fileOffset;
List<Statement> result = <Statement>[];
result.add(node);
result.add(
variableStatement ?? // Coverage-ignore(suite): Not run.
extern.createVariableStatement(node),
);
late_lowering.IsSetEncoding isSetEncoding = late_lowering
.computeIsSetEncoding(
@@ -16886,7 +16942,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
type: coreTypes.boolRawType(Nullability.nonNullable),
isLowered: true,
)..fileOffset = fileOffset;
result.add(isSetVariable);
result.add(extern.createVariableStatement(isSetVariable));
}
Expression createVariableRead({bool needsPromotion = false}) {
@@ -4990,11 +4990,11 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
if (value is! VariableGet) return false;
if (expression.body.statements.isEmpty) return false;
Statement first = expression.body.statements.first;
if (first is! VariableDeclaration) return false;
Expression? initializer = first.initializer;
if (first is! VariableStatement) return false;
Expression? initializer = first.variable.initializer;
if (initializer is! StaticInvocation) return false;
if (initializer.target != engine.setFactory) return false;
return value.variable == first;
return value.variable == first.variable;
}
/// Determines if the given [expression]'s type is precisely known at compile
@@ -49,7 +49,7 @@ class MatchingCache {
bool _isClosed = false;
/// The declarations need for the cached expressions.
List<Statement> _declarations = [];
List<VariableDeclaration> _declarations = [];
/// Map for the known cached keys and their corresponding expressions.
Map<CacheKey, Cache> _cacheKeyMap = {};
@@ -166,7 +166,7 @@ class MatchingCache {
/// Registers that the variable or local function [declaration] is need for
/// the cached expressions.
void registerDeclaration(Statement declaration) {
void registerDeclaration(VariableDeclaration declaration) {
assert(!_isClosed);
_declarations.add(declaration);
}
@@ -176,7 +176,7 @@ class MatchingCache {
///
/// Once called, the matching cache is closed and no new cacheable expressions
/// can be created.
Iterable<Statement> get declarations {
Iterable<VariableDeclaration> get declarations {
_isClosed = true;
return _declarations;
}
+3 -3
View File
@@ -2210,10 +2210,10 @@ class Strategy extends EquivalenceStrategy {
}
@override
bool checkVariableStatement_binaryOffsetNoTag(
bool checkLegacyVariable_binaryOffsetNoTag(
EquivalenceVisitor visitor,
VariableDeclaration node,
VariableDeclaration other,
LegacyVariable node,
LegacyVariable other,
) {
return true;
}
@@ -215,7 +215,7 @@ class PredicateDataExtractor extends CfeDataExtractor<Features> {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
Object? identity;
String? name;
String? tag;
@@ -257,7 +257,7 @@ class PredicateDataExtractor extends CfeDataExtractor<Features> {
features[Tags.name] = name;
}
}
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
}
@override
@@ -65,12 +65,10 @@ class TypeArgumentsVisitor extends VerifyingAnalysis {
'AssertStatement',
uri: astUri,
);
InterfaceType variableDeclarationType = interface.createInterfaceType(
'VariableDeclaration',
InterfaceType variableStatementType = interface.createInterfaceType(
'VariableStatement',
uri: astUri,
);
InterfaceType variableInitializationType = interface
.createInterfaceType('VariableDeclaration', uri: astUri);
DartType typeArgument = receiver.arguments.types.single;
if (interface.isSubtypeOf(typeArgument, expressionType) &&
typeArgument != expressionType) {
@@ -93,28 +91,15 @@ class TypeArgumentsVisitor extends VerifyingAnalysis {
}
} else if (interface.isSubtypeOf(
typeArgument,
variableDeclarationType,
variableStatementType,
)) {
// [VariableDeclaration] is used as an exclusive member of, for
// instance, `FunctionNode.positionalParameters`.
if (typeArgument != variableDeclarationType) {
if (typeArgument != variableStatementType) {
registerError(
node,
"map().toList() with type argument "
"${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}",
"${typeArgument} instead of ${variableStatementType}",
);
}
} else if (typeArgument != statementType) {
+5 -5
View File
@@ -80,8 +80,8 @@ import 'package:kernel/ast.dart'
TreeNode,
Typedef,
UnevaluatedConstant,
VariableDeclaration,
Version;
Version,
LegacyVariable;
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/core_types.dart' show CoreTypes;
@@ -1713,10 +1713,10 @@ class Strategy extends EquivalenceStrategy {
}
@override
bool checkVariableStatement_binaryOffsetNoTag(
bool checkLegacyVariable_binaryOffsetNoTag(
EquivalenceVisitor visitor,
VariableDeclaration node,
VariableDeclaration other,
LegacyVariable node,
LegacyVariable other,
) {
return true;
}
@@ -46,6 +46,29 @@ void testStatement(
);
}
void testVariableDeclaration(
VariableDeclaration node,
String normal, {
String? verbose,
String? limited,
}) {
Expect.stringEquals(
normal,
node.toText(normalStrategy),
"Unexpected normal strategy text for ${node.runtimeType}",
);
Expect.stringEquals(
verbose ?? normal,
node.toText(verboseStrategy),
"Unexpected verbose strategy text for ${node.runtimeType}",
);
Expect.stringEquals(
limited ?? normal,
node.toText(limitedStrategy),
"Unexpected limited strategy text for ${node.runtimeType}",
);
}
void testExpression(
Expression node,
String normal, {
@@ -201,16 +224,20 @@ void main() {
void _testVariableDeclarations() {
testStatement(
forest.variablesDeclaration([
new VariableDeclaration('a'),
new VariableDeclaration('b'),
new VariableStatement(new VariableDeclaration('a')),
new VariableStatement(new VariableDeclaration('b')),
], dummyUri),
'''
dynamic a, b;''',
);
testStatement(
forest.variablesDeclaration([
new VariableDeclaration('a', type: const VoidType()),
new VariableDeclaration('b', initializer: new NullLiteral()),
new VariableStatement(
new VariableDeclaration('a', type: const VoidType()),
),
new VariableStatement(
new VariableDeclaration('b', initializer: new NullLiteral()),
),
], dummyUri),
'''
void a, b = null;''',
@@ -348,7 +375,9 @@ void _testInternalForInStatement() {
testStatement(
new InternalForInStatement(
new SingleVariableDeclarationForInElement(
variableDeclaration: new VariableDeclarationImpl('e', fileOffset: -1),
variableStatement: new LegacyVariableStatement(
new VariableDeclarationImpl('e', fileOffset: -1),
),
error: null,
),
new NullLiteral(),
@@ -364,10 +393,12 @@ for (var e in null) {}''',
testStatement(
new InternalForInStatement(
new SingleVariableDeclarationForInElement(
variableDeclaration: new VariableDeclarationImpl(
'e',
type: const VoidType(),
fileOffset: -1,
variableStatement: new LegacyVariableStatement(
new VariableDeclarationImpl(
'e',
type: const VoidType(),
fileOffset: -1,
),
),
error: null,
),
@@ -497,8 +528,12 @@ for (null in null) {}''',
new InternalForInStatement(
new MultiVariableDeclarationForInElement(
variableDeclarations: [
new VariableDeclarationImpl('a', fileOffset: -1),
new VariableDeclarationImpl('b', fileOffset: -1),
new VariableStatement(
new VariableDeclarationImpl('a', fileOffset: -1),
),
new VariableStatement(
new VariableDeclarationImpl('b', fileOffset: -1),
),
],
error: new InvalidExpression('error'),
),
@@ -516,12 +551,16 @@ for (var a, b in null) {}''',
new InternalForInStatement(
new MultiVariableDeclarationForInElement(
variableDeclarations: [
new VariableDeclarationImpl(
'a',
type: const VoidType(),
fileOffset: -1,
new VariableStatement(
new VariableDeclarationImpl(
'a',
type: const VoidType(),
fileOffset: -1,
),
),
new VariableStatement(
new VariableDeclarationImpl('b', fileOffset: -1),
),
new VariableDeclarationImpl('b', fileOffset: -1),
],
error: new InvalidExpression('error'),
),
@@ -1395,21 +1434,21 @@ return 0;''');
}
void _testVariableDeclarationImpl() {
testStatement(
testVariableDeclaration(
new VariableDeclarationImpl('foo', fileOffset: TreeNode.noOffset),
'''
dynamic foo;''',
dynamic foo''',
);
testStatement(
testVariableDeclaration(
new VariableDeclarationImpl(
'foo',
initializer: new IntLiteral(0),
fileOffset: TreeNode.noOffset,
),
'''
dynamic foo = 0;''',
dynamic foo = 0''',
);
testStatement(
testVariableDeclaration(
new VariableDeclarationImpl(
'foo',
type: const VoidType(),
@@ -1419,9 +1458,9 @@ dynamic foo = 0;''',
fileOffset: TreeNode.noOffset,
),
'''
required final void foo;''',
required final void foo''',
);
testStatement(
testVariableDeclaration(
new VariableDeclarationImpl(
'foo',
type: const VoidType(),
@@ -1430,9 +1469,9 @@ required final void foo;''',
fileOffset: TreeNode.noOffset,
),
'''
late void foo = 0;''',
late void foo = 0''',
);
testStatement(
testVariableDeclaration(
new VariableDeclarationImpl(
'foo',
type: const VoidType(),
@@ -1444,9 +1483,9 @@ late void foo = 0;''',
fileOffset: TreeNode.noOffset,
),
'''
late void foo = 0;''',
late void foo = 0''',
);
testStatement(
testVariableDeclaration(
new VariableDeclarationImpl(
'foo',
type: const VoidType(),
@@ -1459,7 +1498,7 @@ late void foo = 0;''',
)
..lateType = const DynamicType(),
'''
late dynamic foo = 0;''',
late dynamic foo = 0''',
);
}
@@ -14,7 +14,7 @@ static method test(positional-parameter list) → dynamic/* scope=[
s := "";
for /* scope=[
#ctx3: not-captured VariableContext([
SyntheticVariable
synthetic-variable #t1;
]),
] */ (synthetic-variable #t1 in list) {
s = #t1;
@@ -14,7 +14,7 @@ static method test(positional-parameter list) → dynamic/* scope=[
s := "";
for /* scope=[
#ctx3: not-captured VariableContext([
SyntheticVariable
synthetic-variable #t1;
]),
] */ (synthetic-variable #t1 in list) {
s = #t1;
+1 -1
View File
@@ -30,7 +30,7 @@ closure_context_lowering/foo45: Crash
closure_context_lowering/foo48: Crash
closure_context_lowering/assert_captured_variables: Crash
closure_context_lowering/late_variable_initializers: Crash
closure_context_lowering/catch_variables: Crash
closure_context_lowering/catch_variables: ExpectationFileMismatchSerialized
closure_context_lowering/synthetic_variables: Crash
closure_context_lowering/assert_captured_variables: ExpectationFileMismatchSerialized
closure_context_lowering/constructor_initializers: ExpectationFileMismatchSerialized
+1 -2
View File
@@ -267,9 +267,8 @@ closure_context_lowering/loop_depth_strategy: Crash
closure_context_lowering/foo42: Crash
closure_context_lowering/foo45: Crash
closure_context_lowering/foo48: Crash
closure_context_lowering/assert_captured_variables: Crash
closure_context_lowering/late_variable_initializers: Crash
closure_context_lowering/catch_variables: Crash
closure_context_lowering/catch_variables: ExpectationFileMismatchSerialized
closure_context_lowering/synthetic_variables: Crash
closure_context_lowering/assert_captured_variables: ExpectationFileMismatchSerialized
closure_context_lowering/constructor_initializers: ExpectationFileMismatchSerialized
+2 -2
View File
@@ -32,7 +32,7 @@ Uri computePackageConfig(Uri repoDir) =>
/// defining its identity.
const Map<String, String?> _declarativeClassesNames = const {
// TODO(johnniwinther): This should be [VariableDeclaration].
'VariableStatement': 'name',
'LegacyVariable': 'name',
'TypeParameter': 'name',
'StructuralParameter': 'name',
'LabeledStatement': null,
@@ -151,7 +151,7 @@ const Map<String?, Map<String, FieldRule?>> _fieldRuleMap = {
'SyntheticVariable': {
'variableInitialization': FieldRule(isDeclaration: false),
},
'VariableStatement': {'_name': FieldRule(name: 'name')},
'LegacyVariable': {'_name': FieldRule(name: 'name')},
'AssignedVariablePattern': {'variable': FieldRule(isDeclaration: false)},
'InvalidPattern': {'declaredVariables': FieldRule(isDeclaration: true)},
'OrPattern': {'orPatternJointVariables': FieldRule(isDeclaration: false)},
@@ -128,9 +128,9 @@ class EffectivelyFinal extends RecursiveVisitor {
EffectivelyFinal._();
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
unwritten.add(node);
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
}
@override
+18 -3
View File
@@ -3726,7 +3726,7 @@ class BinaryBuilder {
// 9.62% (6.92% - 12.64%).
case Tag.VariableDeclaration:
return _readVariableDeclaration();
return _readVariableStatement();
// 9.28% (6.69% - 11.18%).
case Tag.EmptyStatement:
@@ -3826,7 +3826,7 @@ class BinaryBuilder {
Statement _readForStatement() {
int variableStackHeight = variableStack.length;
int offset = readOffset();
List<VariableDeclaration> variables = readAndPushVariableDeclarationList();
List<VariableStatement> variables = readAndPushVariableStatementList();
Expression? condition = readExpressionOption();
List<Expression> updates = readExpressionList();
Statement body = readStatement();
@@ -3931,7 +3931,12 @@ class BinaryBuilder {
)..fileOffset = offset;
}
Statement _readVariableDeclaration() {
VariableStatement _readVariableStatement() {
VariableDeclaration variable = _readVariableDeclaration();
return new VariableStatement(variable)..fileOffset = variable.fileOffset;
}
VariableDeclaration _readVariableDeclaration() {
VariableDeclaration variable = readVariableDeclaration();
variableStack.add(variable); // Will be popped by the enclosing scope.
return variable;
@@ -4427,6 +4432,16 @@ class BinaryBuilder {
return new NamedExpression(readStringReference(), readExpression());
}
List<VariableStatement> readAndPushVariableStatementList() {
List<VariableDeclaration> list = readAndPushVariableDeclarationList();
return new List.generate(
list.length,
(int index) =>
new VariableStatement(list[index])
..fileOffset = list[index].fileOffset,
);
}
List<VariableDeclaration> readAndPushVariableDeclarationList() {
int length = readUInt30();
if (!useGrowableLists && length == 0) {
+10 -1
View File
@@ -20,6 +20,7 @@ class BinaryPrinter
TreeVisitorExperimentExclusionMixin<void>,
DartTypeVisitorExperimentExclusionMixin<void>,
StatementVisitorExperimentExclusionMixin<void>,
VariableVisitorExperimentExclusionMixin<void>,
ExpressionVisitorExperimentExclusionMixin<void>
implements Visitor<void>, BinarySink {
final VariableIndexer Function() _newVariableIndexer;
@@ -2358,7 +2359,7 @@ class BinaryPrinter
variableIndexer.pushScope();
writeByte(Tag.ForStatement);
writeOffset(node.fileOffset);
writeVariableDeclarationList(node.variables);
writeVariableStatementList(node.variables);
writeOptionalNode(node.condition);
writeNodeList(node.updates);
writeNode(node.body);
@@ -2480,6 +2481,10 @@ class BinaryPrinter
writeVariableDeclaration(node);
}
void writeVariableStatement(VariableStatement node) {
writeVariableDeclaration(node.variable);
}
void writeVariableDeclaration(VariableDeclaration node) {
if (_metadataSubsections != null) {
_writeNodeMetadata(node);
@@ -2497,6 +2502,10 @@ class BinaryPrinter
(_variableIndexer ??= _newVariableIndexer()).declare(node);
}
void writeVariableStatementList(List<VariableStatement> nodes) {
writeList(nodes, writeVariableStatement);
}
void writeVariableDeclarationList(List<VariableDeclaration> nodes) {
writeList(nodes, writeVariableDeclaration);
}
+10 -5
View File
@@ -607,7 +607,7 @@ class CloneVisitorNotMembers
@override
TreeNode visitForStatement(ForStatement node) {
List<VariableDeclaration> variables = node.variables.map(clone).toList();
List<VariableStatement> variables = node.variables.map(clone).toList();
return new ForStatement(
variables,
cloneOptional(node.condition),
@@ -792,10 +792,16 @@ class CloneVisitorNotMembers
}
@override
TreeNode visitVariableStatement(VariableStatement node) {
TreeNode visitLegacyVariableStatement(VariableStatement node) {
return new LegacyVariableStatement(clone(node.variable))
..fileOffset = _cloneFileOffset(node.fileOffset);
}
@override
TreeNode visitLegacyVariable(LegacyVariable node) {
return setVariableClone(
node,
new VariableStatement(
new LegacyVariable(
node.name,
initializer: cloneOptional(node.initializer),
type: visitType(node.type),
@@ -821,8 +827,7 @@ class CloneVisitorNotMembers
..flags = node.flags
..annotations = cloneAnnotations && !node.annotations.isEmpty
? node.annotations.map(clone).toList()
: const <Expression>[]
..fileEqualsOffset = _cloneFileOffset(node.fileEqualsOffset);
: const <Expression>[];
}
@override
+3 -1
View File
@@ -368,6 +368,8 @@ abstract class MetadataRepository<T> {
static bool isSupported(Node node) {
return !(node is MapLiteralEntry ||
node is Catch ||
(node is Block && node.parent is BlockExpression));
(node is Block && node.parent is BlockExpression) ||
// TODO(johnniwinther): Support
node is LegacyVariableStatement);
}
}
+9
View File
@@ -472,6 +472,15 @@ final List<MapPatternEntry> emptyListOfMapPatternEntry = List.filled(
growable: false,
);
/// Non-nullable [VariableStatement] dummy value.
///
/// This is used as the removal sentinel in [RemovingTransformer] and can be
/// used for instance as a dummy initial value for the `List.filled`
/// constructor.
final VariableStatement dummyVariableStatement = new VariableStatement(
dummyVariableDeclaration,
);
/// Non-nullable [VariableDeclaration] dummy value.
///
/// This is used as the removal sentinel in [RemovingTransformer] and can be
+89 -282
View File
@@ -539,10 +539,10 @@ class DoStatement extends Statement implements LoopStatement {
class ForStatement extends Statement implements LoopStatement, ScopeProvider {
// May be empty, but not null.
final List<VariableDeclaration> variables;
final List<VariableStatement> variables;
// TODO(61572): Remove this.
List<VariableDeclaration> get variableInitializations => variables;
List<VariableStatement> get variableInitializations => variables;
Expression? condition; // May be null.
final List<Expression> updates; // May be empty, but not null.
@@ -589,7 +589,7 @@ class ForStatement extends Statement implements LoopStatement, ScopeProvider {
@override
void transformOrRemoveChildren(RemovingTransformer v) {
v.transformVariableDeclarationList(variables, this);
v.transformStatementList(variables, this);
if (condition != null) {
condition = v.transformOrRemoveExpression(condition!);
condition?.parent = this;
@@ -612,7 +612,7 @@ class ForStatement extends Statement implements LoopStatement, ScopeProvider {
printer.write(', ');
}
printer.writeVariableInitialization(
variables[index],
variables[index].variable,
includeModifiersAndType: index == 0,
);
}
@@ -1459,6 +1459,7 @@ class YieldStatement extends Statement {
}
}
// TODO(johnniwinther): Move this to `variables.dart`.
/// Declaration of a local variable.
///
/// This may occur as a statement, but is also used in several non-statement
@@ -1467,8 +1468,8 @@ class YieldStatement extends Statement {
/// When this occurs as a statement, it must be a direct child of a [Block].
//
// DESIGN TODO: Should we remove the 'final' modifier from variables?
class VariableStatement extends Statement
implements Annotatable, VariableDeclaration {
class LegacyVariable extends TreeNode
implements VariableDeclaration, Annotatable {
/// Offset of the equals sign in the source file it comes from.
///
/// Valid values are from 0 and up, or -1 ([TreeNode.noOffset])
@@ -1511,7 +1512,7 @@ class VariableStatement extends Statement
@override
Expression? initializer; // May be null.
VariableStatement(
LegacyVariable(
this._name, {
this.initializer,
this.type = const DynamicType(),
@@ -1553,7 +1554,7 @@ class VariableStatement extends Statement
}
/// Creates a synthetic variable with the given expression as initializer.
VariableStatement.forValue(
LegacyVariable.forValue(
this.initializer, {
bool isFinal = true,
bool isConst = false,
@@ -1648,7 +1649,7 @@ class VariableStatement extends Statement
@override
bool get isErroneouslyInitialized => flags & FlagErroneouslyInitialized != 0;
/// If this [LegacyVariableDeclaration] is a parameter of a method, indicates
/// If this [LegacyVariable] is a parameter of a method, indicates
/// whether the method implementation needs to contain a runtime type check to
/// deal with generic covariance.
///
@@ -1827,11 +1828,11 @@ class VariableStatement extends Statement
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitVariableStatement(this);
R accept<R>(VariableVisitor<R> v) => v.visitLegacyVariable(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
v.visitVariableStatement(this, arg);
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitLegacyVariable(this, arg);
@override
void visitChildren(Visitor v) {
@@ -1889,13 +1890,13 @@ class VariableStatement extends Statement
}
@override
VariableDeclaration? get variableInitialization {
VariableInitialization? get variableInitialization {
throw new UnsupportedError("${this.runtimeType}.variableInitialization");
}
@override
void set variableInitialization(VariableDeclaration? value) {
throw new UnsupportedError("${this.runtimeType}.variableInitialization=");
void set variableInitialization(VariableInitialization? value) {
throw new UnsupportedError("${this.runtimeType}.variableInitialization");
}
@override
@@ -1962,6 +1963,73 @@ class VariableStatement extends Statement
bool get hasIsWildcard => true;
}
/// Declaration of a local variable.
abstract class VariableStatement extends Statement {
/// The declared variable.
abstract final VariableDeclaration variable;
/// The declared initializer, if any.
abstract Expression? initializer;
factory VariableStatement(VariableDeclaration variable) =
LegacyVariableStatement;
}
/// Declaration of a local variable.
class LegacyVariableStatement extends Statement implements VariableStatement {
/// The declared variable.
@override
VariableDeclaration variable;
LegacyVariableStatement(this.variable) {
variable.parent = this;
}
@override
Expression? get initializer => variable.initializer;
@override
void set initializer(Expression? value) {
variable.initializer = value;
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitLegacyVariableStatement(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
v.visitLegacyVariableStatement(this, arg);
@override
void visitChildren(Visitor v) {
variable.accept(v);
}
@override
void transformChildren(Transformer v) {
variable = v.transform(variable)..parent = this;
}
@override
void transformOrRemoveChildren(RemovingTransformer v) {
variable = v.transformOrRemove(variable, cannotRemoveSentinel)!
..parent = this;
}
/// Returns a possibly synthesized name for this variable, consistent with
/// the names used across all [toString] calls.
@override
String toString() {
return "VariableStatement(${toStringInternal()})";
}
@override
void toTextInternal(AstPrinter printer) {
printer.writeVariableInitialization(variable);
printer.write(';');
}
}
/// Declaration a local function.
///
/// The body of the function may use [variable] as its self-reference.
@@ -2025,7 +2093,8 @@ class FunctionDeclaration extends Statement implements LocalFunction {
}
}
class VariableInitialization extends Statement implements VariableDeclaration {
class VariableInitialization extends Statement
implements VariableStatement, ContextConsumer {
@override
VariableDeclaration variable;
@@ -2050,125 +2119,24 @@ class VariableInitialization extends Statement implements VariableDeclaration {
static const int FlagHasDeclaredInitializer = 1 << 0;
static const int FlagErroneouslyInitialized = 1 << 1;
@override
int flags = 0;
@override
bool get hasDeclaredInitializer => flags & FlagHasDeclaredInitializer != 0;
@override
void set hasDeclaredInitializer(bool value) {
flags = value
? (flags | FlagHasDeclaredInitializer)
: (flags & ~FlagHasDeclaredInitializer);
}
@override
bool get isErroneouslyInitialized => flags & FlagErroneouslyInitialized != 0;
@override
void set isErroneouslyInitialized(bool value) {
flags = value
? (flags | FlagErroneouslyInitialized)
: (flags & ~FlagErroneouslyInitialized);
}
@override
bool get isConst => variable.isConst;
@override
void set isConst(bool value) {
variable.isConst = value;
}
@override
bool get isCovariantByClass => variable.isCovariantByClass;
@override
void set isCovariantByClass(bool value) {
variable.isCovariantByClass = value;
}
@override
bool get isCovariantByDeclaration => variable.isCovariantByDeclaration;
@override
void set isCovariantByDeclaration(bool value) {
variable.isCovariantByDeclaration = value;
}
@override
bool get isFinal => variable.isFinal;
@override
void set isFinal(bool value) {
variable.isFinal = value;
}
@override
bool get isHoisted => variable.isHoisted;
@override
void set isHoisted(bool value) {
variable.isHoisted = value;
}
@override
bool get isInitializingFormal => variable.isInitializingFormal;
@override
void set isInitializingFormal(bool value) {
variable.isInitializingFormal = value;
}
@override
bool get isLate => variable.isLate;
@override
void set isLate(bool value) {
variable.isLate = value;
}
@override
bool get isLowered => variable.isLowered;
@override
void set isLowered(bool value) {
variable.isLowered = value;
}
@override
bool get isRequired => variable.isRequired;
@override
void set isRequired(bool value) {
variable.isRequired = value;
}
@override
bool get isSuperInitializingFormal => variable.isSuperInitializingFormal;
@override
void set isSuperInitializingFormal(bool value) {
variable.isSuperInitializingFormal = value;
}
@override
bool get isSynthesized => variable.isSynthesized;
@override
void set isSynthesized(bool value) {
variable.isSynthesized = value;
}
@override
bool get isWildcard => variable.isWildcard;
@override
void set isWildcard(bool value) {
variable.isWildcard = value;
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitVariableInitialization(this);
@@ -2178,8 +2146,7 @@ class VariableInitialization extends Statement implements VariableDeclaration {
@override
void transformChildren(Transformer v) {
// Note that [variable] is not owned by [VariableInitialization], so it's
// not visited.
variable = v.transform(variable)..parent = this;
v.transformList(annotations, this);
if (initializer != null) {
initializer = v.transform(initializer!);
@@ -2189,8 +2156,8 @@ class VariableInitialization extends Statement implements VariableDeclaration {
@override
void transformOrRemoveChildren(RemovingTransformer v) {
// Note that [variable] is not owned by [VariableInitialization], so it's
// not visited.
variable = v.transformOrRemove(variable, cannotRemoveSentinel)!
..parent = this;
v.transformExpressionList(annotations, this);
if (initializer != null) {
initializer = v.transformOrRemoveExpression(initializer!);
@@ -2200,8 +2167,7 @@ class VariableInitialization extends Statement implements VariableDeclaration {
@override
void visitChildren(Visitor v) {
// Note that [variable] is not owned by [VariableInitialization], so it's
// not visited.
variable.accept(v);
visitList(annotations, v);
initializer?.accept(v);
}
@@ -2221,32 +2187,8 @@ class VariableInitialization extends Statement implements VariableDeclaration {
printer.write(';');
}
@override
List<Expression> annotations = const <Expression>[];
@override
int binaryOffsetNoTag = TreeNode.noOffset;
@override
int fileEqualsOffset = TreeNode.noOffset;
@override
String? get name => variable.cosmeticName;
@override
void set name(String? value) {
variable.cosmeticName = value;
}
@override
DartType get type => variable.type;
@override
void set type(DartType value) {
variable.type = value;
}
@override
void addAnnotation(Expression node) {
if (annotations.isEmpty) {
annotations = <Expression>[];
@@ -2254,142 +2196,7 @@ class VariableInitialization extends Statement implements VariableDeclaration {
annotations.add(node..parent = this);
}
@override
void clearAnnotations() {
annotations = const <Expression>[];
}
@override
bool get isAssignable => variable.isAssignable;
@override
String? get cosmeticName => variable.cosmeticName;
@override
void set cosmeticName(String? value) {
variable.cosmeticName = value;
}
@override
VariableDeclaration? get variableInitialization => this;
@override
void set variableInitialization(VariableDeclaration? value) {
throw new UnsupportedError("${this.runtimeType}");
}
@override
VariableDeclaration get asVariableDeclaration => variable;
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
VariableContext get context {
throw UnsupportedError("${runtimeType}.context");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
void set context(VariableContext value) {
throw UnsupportedError("${runtimeType}.context=");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasHasDeclaredInitializer {
throw UnsupportedError("${runtimeType}.hasHasDeclaredInitializer");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsConst {
throw new UnsupportedError("${runtimeType}.hasIsConst");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsCovariantByClass {
throw new UnsupportedError("${runtimeType}.hasIsCovariantByClass");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsCovariantByDeclaration {
throw new UnsupportedError("${runtimeType}.hasIsCovariantByDeclaration");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsErroneouslyInitialized {
throw new UnsupportedError("${runtimeType}.hasIsErroneouslyInitialized");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsFinal {
throw new UnsupportedError("${runtimeType}.hasIsFinal");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsHoisted {
throw new UnsupportedError("${runtimeType}.hasIsHoisted");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsInitializingFormal {
throw new UnsupportedError("${runtimeType}.hasIsInitializingFormal");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsLate {
throw new UnsupportedError("${runtimeType}.hasIsLate");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsLowered {
throw new UnsupportedError("${runtimeType}.hasIsLowered");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsRequired {
throw new UnsupportedError("${runtimeType}.hasIsRequired");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsSuperInitializingFormal {
throw new UnsupportedError("${runtimeType}.hasIsSuperInitializingFormal");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsSynthesized {
throw new UnsupportedError("${runtimeType}.hasIsSynthesized");
}
@override
// TODO(62620): Remove the method when the [VariableInitialization] stops
// implementing [VariableDeclaration].
bool get hasIsWildcard {
throw new UnsupportedError("${runtimeType}.hasIsWildcard");
}
}
+34 -31
View File
@@ -28,7 +28,7 @@ sealed class VariableBase extends TreeNode implements Annotatable {
abstract interface class IVariable implements TreeNode {
abstract DartType type;
abstract String? cosmeticName;
abstract VariableDeclaration? variableInitialization;
abstract VariableInitialization? variableInitialization;
abstract Expression? initializer;
abstract VariableContext context;
abstract bool isFinal;
@@ -74,14 +74,14 @@ abstract interface class IVariable implements TreeNode {
/// The root of the sealed hierarchy of non-type variables.
sealed class VariableDeclaration extends VariableBase
implements IVariable, Statement, ContextConsumer {
implements IVariable, ContextConsumer {
/// Static type of the variable.
@override
abstract DartType type;
/// Initialization node for the variable, if available.
@override
abstract VariableDeclaration? variableInitialization;
abstract VariableInitialization? variableInitialization;
/// Derived from [variableInitialization], if available.
@override
@@ -136,7 +136,7 @@ sealed class VariableDeclaration extends VariableBase
bool isHoisted,
bool hasDeclaredInitializer,
bool isWildcard,
}) = VariableStatement;
}) = LegacyVariable;
factory VariableDeclaration.forValue(
Expression? initializer, {
@@ -148,7 +148,7 @@ sealed class VariableDeclaration extends VariableBase
bool isRequired,
bool isLowered,
DartType type,
}) = VariableStatement.forValue;
}) = LegacyVariable.forValue;
VariableDeclaration.empty();
@@ -188,6 +188,12 @@ sealed class VariableDeclaration extends VariableBase
VariableDeclaration get asVariableDeclaration => this;
abstract String? name;
@override
R accept<R>(VariableVisitor<R> visitor);
@override
R accept1<R, A>(VariableVisitor1<R, A> visitor, A arg);
}
/// Local variables. They aren't Statements. A [LocalVariable] is "declared" in
@@ -202,7 +208,7 @@ class LocalVariable extends VariableDeclaration {
DartType type;
@override
VariableDeclaration? variableInitialization;
VariableInitialization? variableInitialization;
@override
List<Expression> annotations = const <Expression>[];
@@ -319,9 +325,8 @@ class LocalVariable extends VariableDeclaration {
}
@override
bool get hasDeclaredInitializer {
throw new UnsupportedError("${this.runtimeType}");
}
bool get hasDeclaredInitializer =>
variableInitialization!.hasDeclaredInitializer;
@override
void set hasDeclaredInitializer(bool value) {
@@ -377,10 +382,10 @@ class LocalVariable extends VariableDeclaration {
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitLocalVariable(this);
R accept<R>(VariableVisitor<R> v) => v.visitLocalVariable(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitLocalVariable(this, arg);
@override
@@ -538,12 +543,12 @@ class CatchVariable extends VariableDeclaration {
}
@override
VariableDeclaration? get variableInitialization {
VariableInitialization? get variableInitialization {
throw new UnsupportedError("${this.runtimeType}.variableInitialization");
}
@override
void set variableInitialization(VariableDeclaration? value) {
void set variableInitialization(VariableInitialization? value) {
throw new UnsupportedError("${this.runtimeType}.variableInitialization=");
}
@@ -693,10 +698,10 @@ class CatchVariable extends VariableDeclaration {
bool get isAssignable => false;
@override
R accept<R>(StatementVisitor<R> v) => v.visitCatchVariable(this);
R accept<R>(VariableVisitor<R> v) => v.visitCatchVariable(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitCatchVariable(this, arg);
@override
@@ -719,9 +724,7 @@ class CatchVariable extends VariableDeclaration {
}
@override
Expression? get initializer {
throw new UnsupportedError("${this.runtimeType}.initializer");
}
Expression? get initializer => null;
@override
void set initializer(Expression? value) {
@@ -842,10 +845,10 @@ sealed class FunctionParameter extends VariableDeclaration {
/// Function parameters don't have initializers, only default values.
@override
VariableDeclaration? get variableInitialization => null;
VariableInitialization? get variableInitialization => null;
@override
void set variableInitialization(VariableDeclaration? value) {}
void set variableInitialization(VariableInitialization? value) {}
@override
Expression? get initializer => defaultValue;
@@ -1063,10 +1066,10 @@ class PositionalParameter extends FunctionParameter {
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitPositionalParameter(this);
R accept<R>(VariableVisitor<R> v) => v.visitPositionalParameter(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitPositionalParameter(this, arg);
@override
@@ -1210,10 +1213,10 @@ class NamedParameter extends FunctionParameter {
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitNamedParameter(this);
R accept<R>(VariableVisitor<R> v) => v.visitNamedParameter(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitNamedParameter(this, arg);
@override
@@ -1304,10 +1307,10 @@ class ThisVariable extends VariableDeclaration {
void set cosmeticName(String? value) {}
@override
VariableDeclaration? get variableInitialization => null;
VariableInitialization? get variableInitialization => null;
@override
void set variableInitialization(VariableDeclaration? value) {}
void set variableInitialization(VariableInitialization? value) {}
@override
DartType type;
@@ -1465,10 +1468,10 @@ class ThisVariable extends VariableDeclaration {
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitThisVariable(this);
R accept<R>(VariableVisitor<R> v) => v.visitThisVariable(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitThisVariable(this, arg);
@override
@@ -1588,7 +1591,7 @@ class SyntheticVariable extends VariableDeclaration {
DartType type;
@override
VariableDeclaration? variableInitialization;
VariableInitialization? variableInitialization;
// TODO(cstefantsova): Consider a throwing implementation instead.
@override
@@ -1741,10 +1744,10 @@ class SyntheticVariable extends VariableDeclaration {
}
@override
R accept<R>(StatementVisitor<R> v) => v.visitSyntheticVariable(this);
R accept<R>(VariableVisitor<R> v) => v.visitSyntheticVariable(this);
@override
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
R accept1<R, A>(VariableVisitor1<R, A> v, A arg) =>
v.visitSyntheticVariable(this, arg);
@override
+10 -3
View File
@@ -956,8 +956,8 @@ class CoverageVisitor implements Visitor<void> {
}
@override
void visitVariableStatement(VariableStatement node) {
visited.add(StatementKind.VariableStatement);
void visitLegacyVariableStatement(LegacyVariableStatement node) {
visited.add(StatementKind.LegacyVariableStatement);
node.visitChildren(this);
}
@@ -985,6 +985,12 @@ class CoverageVisitor implements Visitor<void> {
node.visitChildren(this);
}
@override
void visitLegacyVariable(LegacyVariable node) {
visited.add(NodeKind.LegacyVariable);
node.visitChildren(this);
}
@override
void visitLocalVariable(LocalVariable node) {
visited.add(VariableDeclarationKind.LocalVariable);
@@ -1324,6 +1330,7 @@ enum NodeKind {
Extension,
ExtensionTypeDeclaration,
FunctionNode,
LegacyVariable,
Library,
LibraryDependency,
LibraryPart,
@@ -1462,6 +1469,7 @@ enum StatementKind {
IfCaseStatement,
IfStatement,
LabeledStatement,
LegacyVariableStatement,
PatternSwitchStatement,
PatternVariableDeclaration,
ReturnStatement,
@@ -1469,7 +1477,6 @@ enum StatementKind {
TryCatch,
TryFinally,
VariableInitialization,
VariableStatement,
WhileStatement,
YieldStatement,
}
+144 -133
View File
@@ -836,8 +836,8 @@ class EquivalenceVisitor implements Visitor1<bool, Node> {
}
@override
bool visitVariableStatement(VariableStatement node, Node other) {
return strategy.checkVariableStatement(this, node, other);
bool visitLegacyVariableStatement(LegacyVariableStatement node, Node other) {
return strategy.checkLegacyVariableStatement(this, node, other);
}
@override
@@ -860,6 +860,11 @@ class EquivalenceVisitor implements Visitor1<bool, Node> {
return strategy.checkCatch(this, node, other);
}
@override
bool visitLegacyVariable(LegacyVariable node, Node other) {
return strategy.checkLegacyVariable(this, node, other);
}
@override
bool visitLocalVariable(LocalVariable node, Node other) {
return strategy.checkLocalVariable(this, node, other);
@@ -1306,8 +1311,8 @@ class EquivalenceVisitor implements Visitor1<bool, Node> {
if (a is LabeledStatement) {
return b is LabeledStatement;
}
if (a is VariableStatement) {
return b is VariableStatement && a.name == b.name;
if (a is LegacyVariable) {
return b is LegacyVariable && a.name == b.name;
}
if (a is StructuralParameter) {
return b is StructuralParameter && a.name == b.name;
@@ -5904,41 +5909,20 @@ class EquivalenceStrategy {
return result;
}
bool checkVariableStatement(
bool checkLegacyVariableStatement(
EquivalenceVisitor visitor,
VariableStatement? node,
LegacyVariableStatement? node,
Object? other,
) {
if (identical(node, other)) return true;
if (node is! VariableStatement) return false;
if (other is! VariableStatement) return false;
if (!visitor.checkDeclarations(node, other, '')) {
return false;
}
if (node is! LegacyVariableStatement) return false;
if (other is! LegacyVariableStatement) return false;
visitor.pushNodeState(node, other);
bool result = true;
if (!checkVariableStatement_fileEqualsOffset(visitor, node, other)) {
if (!checkLegacyVariableStatement_variable(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableStatement_annotations(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableStatement_name(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableStatement_flags(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableStatement_type(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableStatement_binaryOffsetNoTag(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableStatement_initializer(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableStatement_fileOffset(visitor, node, other)) {
if (!checkLegacyVariableStatement_fileOffset(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
visitor.popState();
@@ -5993,12 +5977,6 @@ class EquivalenceStrategy {
if (!checkVariableInitialization_annotations(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableInitialization_binaryOffsetNoTag(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableInitialization_fileEqualsOffset(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkVariableInitialization_fileOffset(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
@@ -6057,6 +6035,47 @@ class EquivalenceStrategy {
return result;
}
bool checkLegacyVariable(
EquivalenceVisitor visitor,
LegacyVariable? node,
Object? other,
) {
if (identical(node, other)) return true;
if (node is! LegacyVariable) return false;
if (other is! LegacyVariable) return false;
if (!visitor.checkDeclarations(node, other, '')) {
return false;
}
visitor.pushNodeState(node, other);
bool result = true;
if (!checkLegacyVariable_fileEqualsOffset(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkLegacyVariable_annotations(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkLegacyVariable_name(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkLegacyVariable_flags(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkLegacyVariable_type(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkLegacyVariable_binaryOffsetNoTag(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkLegacyVariable_initializer(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkLegacyVariable_fileOffset(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
visitor.popState();
return result;
}
bool checkLocalVariable(
EquivalenceVisitor visitor,
LocalVariable? node,
@@ -13259,83 +13278,18 @@ class EquivalenceStrategy {
return checkStatement_fileOffset(visitor, node, other);
}
bool checkVariableStatement_fileEqualsOffset(
bool checkLegacyVariableStatement_variable(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
LegacyVariableStatement node,
LegacyVariableStatement other,
) {
return visitor.checkValues(
node.fileEqualsOffset,
other.fileEqualsOffset,
'fileEqualsOffset',
);
return visitor.checkNodes(node.variable, other.variable, 'variable');
}
bool checkVariableStatement_annotations(
bool checkLegacyVariableStatement_fileOffset(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
) {
return visitor.checkLists(
node.annotations,
other.annotations,
visitor.checkNodes,
'annotations',
);
}
bool checkVariableStatement_name(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
) {
return visitor.checkValues(node.name, other.name, 'name');
}
bool checkVariableStatement_flags(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
) {
return visitor.checkValues(node.flags, other.flags, 'flags');
}
bool checkVariableStatement_type(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
) {
return visitor.checkNodes(node.type, other.type, 'type');
}
bool checkVariableStatement_binaryOffsetNoTag(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
) {
return visitor.checkValues(
node.binaryOffsetNoTag,
other.binaryOffsetNoTag,
'binaryOffsetNoTag',
);
}
bool checkVariableStatement_initializer(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
) {
return visitor.checkNodes(
node.initializer,
other.initializer,
'initializer',
);
}
bool checkVariableStatement_fileOffset(
EquivalenceVisitor visitor,
VariableStatement node,
VariableStatement other,
LegacyVariableStatement node,
LegacyVariableStatement other,
) {
return checkStatement_fileOffset(visitor, node, other);
}
@@ -13420,30 +13374,6 @@ class EquivalenceStrategy {
);
}
bool checkVariableInitialization_binaryOffsetNoTag(
EquivalenceVisitor visitor,
VariableInitialization node,
VariableInitialization other,
) {
return visitor.checkValues(
node.binaryOffsetNoTag,
other.binaryOffsetNoTag,
'binaryOffsetNoTag',
);
}
bool checkVariableInitialization_fileEqualsOffset(
EquivalenceVisitor visitor,
VariableInitialization node,
VariableInitialization other,
) {
return visitor.checkValues(
node.fileEqualsOffset,
other.fileEqualsOffset,
'fileEqualsOffset',
);
}
bool checkVariableInitialization_fileOffset(
EquivalenceVisitor visitor,
VariableInitialization node,
@@ -13517,6 +13447,87 @@ class EquivalenceStrategy {
return checkTreeNode_fileOffset(visitor, node, other);
}
bool checkLegacyVariable_fileEqualsOffset(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return visitor.checkValues(
node.fileEqualsOffset,
other.fileEqualsOffset,
'fileEqualsOffset',
);
}
bool checkLegacyVariable_annotations(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return visitor.checkLists(
node.annotations,
other.annotations,
visitor.checkNodes,
'annotations',
);
}
bool checkLegacyVariable_name(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return visitor.checkValues(node.name, other.name, 'name');
}
bool checkLegacyVariable_flags(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return visitor.checkValues(node.flags, other.flags, 'flags');
}
bool checkLegacyVariable_type(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return visitor.checkNodes(node.type, other.type, 'type');
}
bool checkLegacyVariable_binaryOffsetNoTag(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return visitor.checkValues(
node.binaryOffsetNoTag,
other.binaryOffsetNoTag,
'binaryOffsetNoTag',
);
}
bool checkLegacyVariable_initializer(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return visitor.checkNodes(
node.initializer,
other.initializer,
'initializer',
);
}
bool checkLegacyVariable_fileOffset(
EquivalenceVisitor visitor,
LegacyVariable node,
LegacyVariable other,
) {
return checkTreeNode_fileOffset(visitor, node, other);
}
bool checkLocalVariable_cosmeticName(
EquivalenceVisitor visitor,
LocalVariable node,
+34 -18
View File
@@ -135,7 +135,8 @@ class NodeCreator {
}
_neededLabeledStatements.clear();
statement = Block([
..._neededVariableDeclarations,
for (VariableDeclaration neededVariable in _neededVariableDeclarations)
VariableStatement(neededVariable),
..._neededFunctionDeclarations,
statement,
]);
@@ -385,6 +386,7 @@ class NodeCreator {
case NodeKind.PatternSwitchCase:
case NodeKind.SwitchExpressionCase:
case NodeKind.TypeVariable:
case NodeKind.LegacyVariable:
throw new UnimplementedError('Expected in body node $kind.');
case NodeKind.Class:
_needLibrary().addClass(node as Class);
@@ -919,11 +921,8 @@ class NodeCreator {
return IsExpression(_createExpression(), _createDartType())
..fileOffset = _needFileOffset();
case ExpressionKind.Let:
return Let(
_createStatementFromKind(StatementKind.VariableStatement)
as VariableDeclaration,
_createExpression(),
)..fileOffset = _needFileOffset();
return Let(_createVariableDeclaration(), _createExpression())
..fileOffset = _needFileOffset();
case ExpressionKind.ListConcatenation:
return _createOneOf(_pendingExpressions, kind, index, [
() =>
@@ -1474,13 +1473,16 @@ class NodeCreator {
ForStatement([], null, [], _createStatement())
..fileOffset = _needFileOffset(),
() => ForStatement(
[_createVariableDeclaration()],
[VariableStatement(_createVariableDeclaration())],
_createExpression(),
[_createExpression()],
_createStatement(),
)..fileOffset = _needFileOffset(),
() => ForStatement(
[_createVariableDeclaration(), _createVariableDeclaration()],
[
VariableStatement(_createVariableDeclaration()),
VariableStatement(_createVariableDeclaration()),
],
_createExpression(),
[_createExpression(), _createExpression()],
_createStatement(),
@@ -1539,15 +1541,19 @@ class NodeCreator {
case StatementKind.TryFinally:
return TryFinally(_createStatement(), _createStatement())
..fileOffset = _needFileOffset();
case StatementKind.VariableStatement:
case StatementKind.LegacyVariableStatement:
return _createOneOf(_pendingStatements, kind, index, [
() => VariableDeclaration('foo')..fileOffset = _needFileOffset(),
() =>
VariableDeclaration('foo', initializer: _createExpression())
..fileOffset = _needFileOffset(),
() =>
VariableDeclaration('foo', type: _createDartType())
..fileOffset = _needFileOffset(),
() => VariableStatement(
VariableDeclaration('foo')..fileOffset = _needFileOffset(),
)..fileOffset = _needFileOffset(),
() => VariableStatement(
VariableDeclaration('foo', initializer: _createExpression())
..fileOffset = _needFileOffset(),
)..fileOffset = _needFileOffset(),
() => VariableStatement(
VariableDeclaration('foo', type: _createDartType())
..fileOffset = _needFileOffset(),
)..fileOffset = _needFileOffset(),
]);
case StatementKind.WhileStatement:
return WhileStatement(_createExpression(), _createStatement())
@@ -1608,8 +1614,7 @@ class NodeCreator {
/// If there are any pending [VariableDeclaration] nodes, one of these is
/// created.
VariableDeclaration _createVariableDeclaration() {
return _createStatementFromKind(StatementKind.VariableStatement)
as VariableDeclaration;
return VariableDeclaration('foo');
}
/// Creates a [DartType] node.
@@ -2128,6 +2133,17 @@ class NodeCreator {
_createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
_createExpression(),
)..fileOffset = _needFileOffset();
case NodeKind.LegacyVariable:
return _createOneOf(_pendingNodes, kind, index, [
() => VariableDeclaration('foo')..fileOffset = _needFileOffset(),
() =>
VariableDeclaration('foo', initializer: _createExpression())
..fileOffset = _needFileOffset(),
() =>
VariableDeclaration('foo', type: _createDartType())
..fileOffset = _needFileOffset(),
]);
case NodeKind.TypeVariable:
throw new UnimplementedError("Unimplemented support for kind $kind.");
}
+1 -2
View File
@@ -260,8 +260,7 @@ class AstPrinter {
return _variableNames[node] ??= '#${_variableNames.length}';
case CatchVariable(catchVariableName: var name):
return name;
case VariableStatement(:var name):
case VariableInitialization(:var name):
case LegacyVariable(:var name):
if (name != null) {
return name;
}
+33 -24
View File
@@ -1248,9 +1248,16 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
endLine(';');
}
@override
void visitSyntheticVariable(SyntheticVariable node) {
writeIndentation();
writeExpressionVariable(node);
endLine(';');
}
void writeExpressionVariable(VariableDeclaration node) {
// TODO(cstefantsova): Printer of the new variables is broken.
if (node is VariableStatement && node is! FunctionParameter) {
if (node is LegacyVariable && node is! FunctionParameter) {
writeVariableDeclaration(node);
} else {
if (showOffsets) writeWord("[${node.fileOffset}]");
@@ -1267,7 +1274,7 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
writeWord('this-variable');
case SyntheticVariable():
writeWord('synthetic-variable');
case VariableStatement():
case LegacyVariable():
writeWord('variable-declaration');
case CatchVariable():
writeWord('catch-variable');
@@ -2580,7 +2587,7 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
ensureSpace();
}
writeSymbol('(');
writeList(node.variables, writeVariableInitialization);
writeList(node.variables, writeVariableStatement);
writeComma(';');
Expression? condition = node.condition;
if (condition != null) {
@@ -2604,7 +2611,7 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
ensureSpace();
}
writeSymbol('(');
if (node.variable case VariableStatement variable) {
if (node.variable case LegacyVariable variable) {
writeVariableDeclaration(variable, useVarKeyword: true);
} else {
writeExpressionVariable(node.variable);
@@ -2751,16 +2758,16 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void visitLegacyVariableStatement(LegacyVariableStatement node) {
writeIndentation();
writeVariableDeclaration(node, useVarKeyword: true);
writeVariableStatement(node);
endLine(';');
}
@override
void visitVariableInitialization(VariableInitialization node) {
writeIndentation();
writeVariableInitialization(node);
writeVariableStatement(node);
_writeContexts(node);
endLine(';');
}
@@ -2786,7 +2793,7 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
case PositionalParameter():
case NamedParameter():
writeExpressionVariable(node);
case VariableStatement():
case LegacyVariable():
if (showOffsets) writeWord("[${node.fileOffset}]");
if (showMetadata) writeMetadata(node);
writeAnnotationList(node.annotations, separateLines: false);
@@ -2835,41 +2842,43 @@ class Printer extends VisitorDefault<void> with VisitorVoidMixin {
writeSpaced('=');
writeExpression(initializer);
}
case VariableInitialization():
writeVariableInitialization(node);
}
}
void writeVariableInitialization(VariableDeclaration node) {
void writeVariableStatement(VariableStatement node) {
VariableDeclaration variable = node.variable;
if (node is VariableInitialization) {
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
variable.initializer is NullLiteral ||
(variable.initializer is ConstantExpression &&
(variable.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) {
if ((variable.initializer == null || hasImplicitInitializer) &&
variable.hasDeclaredInitializer) {
writeModifier(
node.hasDeclaredInitializer,
variable.hasDeclaredInitializer,
'has-declared-initializer',
);
} else if (variable.initializer != null &&
!hasImplicitInitializer &&
!variable.hasDeclaredInitializer) {
writeModifier(
variable.hasDeclaredInitializer,
'has-no-declared-initializer',
);
}
writeWord(getVariableName(node.variable));
Expression? initializer = node.initializer;
writeWord(getVariableName(variable.variable));
Expression? initializer = variable.initializer;
if (initializer != null) {
writeSpaced(':=');
writeExpression(initializer);
}
} else {
writeVariableDeclaration(node);
writeVariableDeclaration(variable);
}
}
+1 -1
View File
@@ -85,7 +85,7 @@ class DebugPrinter extends VisitorDefault<void>
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
openNode(node, '${node.runtimeType}', {
'name': '${node.name ?? '--unnamed--'}',
'isFinal': '${node.isFinal}',
+20 -10
View File
@@ -1183,7 +1183,7 @@ class TypeCheckingVisitor
@override
void visitForStatement(ForStatement node) {
node.variables.forEach(_handleVariableInitialization);
node.variables.forEach(_handleVariableStatement);
if (node.condition != null) {
node.condition = checkExpressionAndAssignability(
node.condition!,
@@ -1257,15 +1257,6 @@ class TypeCheckingVisitor
@override
void visitVariableDeclaration(VariableDeclaration node) {
_handleVariableInitialization(node);
}
@override
void visitVariableInitialization(VariableInitialization node) {
_handleVariableInitialization(node);
}
void _handleVariableInitialization(VariableDeclaration node) {
if (node.initializer != null) {
node.initializer = checkExpressionAndAssignability(
node.initializer!,
@@ -1274,6 +1265,25 @@ class TypeCheckingVisitor
}
}
@override
void visitLegacyVariableStatement(LegacyVariableStatement node) {
_handleVariableStatement(node);
}
@override
void visitVariableInitialization(VariableInitialization node) {
_handleVariableStatement(node);
}
void _handleVariableStatement(VariableStatement node) {
if (node.initializer != null) {
node.initializer = checkExpressionAndAssignability(
node.initializer!,
node.variable.type,
);
}
}
@override
void visitWhileStatement(WhileStatement node) {
node.condition = checkExpressionAndAssignability(
+20 -21
View File
@@ -270,7 +270,7 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
// TODO(cstefantsova): Remove this method when the new variable model is
// supported.
bool _isNewModelVariable(TreeNode node) {
return node is VariableDeclaration && node is! VariableStatement ||
return node is VariableDeclaration && node is! LegacyVariable ||
node is FunctionParameter;
}
@@ -1137,37 +1137,36 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
return _verifyVariableInitialization(node);
void visitLegacyVariableStatement(LegacyVariableStatement node) {
_verifyVariableStatement(node);
super.visitLegacyVariableStatement(node);
}
@override
void visitVariableInitialization(VariableDeclaration node) {
return _verifyVariableInitialization(node);
void visitVariableInitialization(VariableInitialization node) {
_verifyVariableStatement(node);
super.visitVariableInitialization(node);
}
void _verifyVariableInitialization(VariableDeclaration node) {
enterTreeNode(node);
void _verifyVariableStatement(VariableStatement node) {
TreeNode? parent = node.parent;
if (parent is! Block &&
!(parent is Catch && parent.body != node) &&
!(parent is FunctionNode && parent.body != node) &&
parent is! FunctionDeclaration &&
!(parent is ForStatement && parent.body != node) &&
!(parent is ForInStatement && parent.body != node) &&
parent is! Let &&
parent is! LocalInitializer &&
parent is! Typedef) {
if (parent is! Block && !(parent is ForStatement && parent.body != node)) {
problem(
node,
"VariableDeclaration must be a direct child of a Block, "
"VariableStatement must be a direct child of a Block or ForStatement, "
"not ${parent.runtimeType}.",
);
}
TreeNode? oldParent = enterParent(node);
_visitAnnotations(node.annotations);
node.initializer?.accept(this);
exitParent(oldParent);
}
@override
void defaultVariableDeclaration(VariableDeclaration node) {
return _verifyVariableDeclaration(node);
}
void _verifyVariableDeclaration(VariableDeclaration node) {
enterTreeNode(node);
visitChildren(node);
declareVariable(node.variable);
if (afterConst && node.isConst && constantLocalsShouldBeRemoved) {
Expression? initializer = node.initializer;
+125 -70
View File
@@ -502,36 +502,54 @@ abstract class StatementVisitor<R> {
const StatementVisitor();
R visitAuxiliaryStatement(AuxiliaryStatement node);
R visitExpressionStatement(ExpressionStatement node);
R visitBlock(Block node);
R visitAssertBlock(AssertBlock node);
R visitEmptyStatement(EmptyStatement node);
R visitAssertStatement(AssertStatement node);
R visitLabeledStatement(LabeledStatement node);
R visitVariableInitialization(VariableInitialization node);
R visitBreakStatement(BreakStatement node);
R visitWhileStatement(WhileStatement node);
R visitDoStatement(DoStatement node);
R visitForStatement(ForStatement node);
R visitForInStatement(ForInStatement node);
R visitSwitchStatement(SwitchStatement node);
R visitPatternSwitchStatement(PatternSwitchStatement node);
R visitContinueSwitchStatement(ContinueSwitchStatement node);
R visitIfStatement(IfStatement node);
R visitIfCaseStatement(IfCaseStatement node);
R visitReturnStatement(ReturnStatement node);
R visitTryCatch(TryCatch node);
R visitTryFinally(TryFinally node);
R visitYieldStatement(YieldStatement node);
R visitPatternVariableDeclaration(PatternVariableDeclaration node);
R visitFunctionDeclaration(FunctionDeclaration node);
R visitVariableStatement(VariableStatement node);
R visitPositionalParameter(PositionalParameter node);
R visitNamedParameter(NamedParameter node);
R visitLocalVariable(LocalVariable node);
R visitCatchVariable(CatchVariable node);
R visitThisVariable(ThisVariable node);
R visitSyntheticVariable(SyntheticVariable node);
R visitLegacyVariableStatement(LegacyVariableStatement node);
}
/// Helper mixin for [StatementVisitor] that implements visit methods by
@@ -587,8 +605,6 @@ mixin StatementVisitorDefaultMixin<R> implements StatementVisitor<R> {
R visitTryFinally(TryFinally node) => defaultStatement(node);
@override
R visitYieldStatement(YieldStatement node) => defaultStatement(node);
R visitVariableDeclaration(VariableDeclaration node) =>
defaultStatement(node);
@override
R visitPatternVariableDeclaration(PatternVariableDeclaration node) =>
defaultStatement(node);
@@ -596,21 +612,45 @@ mixin StatementVisitorDefaultMixin<R> implements StatementVisitor<R> {
R visitFunctionDeclaration(FunctionDeclaration node) =>
defaultStatement(node);
@override
R visitVariableStatement(VariableStatement node) =>
visitVariableDeclaration(node);
R visitLegacyVariableStatement(LegacyVariableStatement node) =>
defaultStatement(node);
}
abstract class VariableVisitor<R> {
const VariableVisitor();
R visitLegacyVariable(LegacyVariable node);
R visitPositionalParameter(PositionalParameter node);
R visitNamedParameter(NamedParameter node);
R visitLocalVariable(LocalVariable node);
R visitCatchVariable(CatchVariable node);
R visitThisVariable(ThisVariable node);
R visitSyntheticVariable(SyntheticVariable node);
}
/// Helper mixin for [VariableVisitor] that implements visit methods by
/// delegating to the [visitVariableDeclaration] method.
mixin VariableVisitorDefaultMixin<R> implements VariableVisitor<R> {
R defaultVariableDeclaration(VariableDeclaration node);
@override
R visitLegacyVariable(LegacyVariable node) =>
defaultVariableDeclaration(node);
@override
R visitPositionalParameter(PositionalParameter node) =>
defaultStatement(node);
defaultVariableDeclaration(node);
@override
R visitNamedParameter(NamedParameter node) => defaultStatement(node);
R visitNamedParameter(NamedParameter node) =>
defaultVariableDeclaration(node);
@override
R visitLocalVariable(LocalVariable node) => defaultStatement(node);
R visitLocalVariable(LocalVariable node) => defaultVariableDeclaration(node);
@override
R visitCatchVariable(CatchVariable node) => defaultStatement(node);
R visitCatchVariable(CatchVariable node) => defaultVariableDeclaration(node);
@override
R visitThisVariable(ThisVariable node) => defaultStatement(node);
R visitThisVariable(ThisVariable node) => defaultVariableDeclaration(node);
@override
R visitSyntheticVariable(SyntheticVariable node) => defaultStatement(node);
R visitSyntheticVariable(SyntheticVariable node) =>
defaultVariableDeclaration(node);
}
abstract class MemberVisitor<R> {
@@ -737,6 +777,7 @@ abstract class TreeVisitor<R>
ExpressionVisitor<R>,
PatternVisitor<R>,
StatementVisitor<R>,
VariableVisitor<R>,
MemberVisitor<R>,
InitializerVisitor<R> {
const TreeVisitor();
@@ -832,6 +873,7 @@ abstract class TreeVisitorDefault<R>
with
ExpressionVisitorDefaultMixin<R>,
StatementVisitorDefaultMixin<R>,
VariableVisitorDefaultMixin<R>,
PatternVisitorDefaultMixin<R>,
InitializerVisitorDefaultMixin<R>,
MemberVisitorDefaultMixin<R>,
@@ -846,6 +888,9 @@ abstract class TreeVisitorDefault<R>
@override
R defaultStatement(Statement node) => defaultTreeNode(node);
@override
R defaultVariableDeclaration(VariableDeclaration node) =>
defaultTreeNode(node);
@override
R defaultInitializer(Initializer node) => defaultTreeNode(node);
@override
R defaultMember(Member node) => defaultTreeNode(node);
@@ -856,6 +901,7 @@ abstract class TreeVisitor1<R, A>
ExpressionVisitor1<R, A>,
PatternVisitor1<R, A>,
StatementVisitor1<R, A>,
VariableVisitor1<R, A>,
MemberVisitor1<R, A>,
InitializerVisitor1<R, A> {
const TreeVisitor1();
@@ -960,6 +1006,7 @@ abstract class TreeVisitor1Default<R, A>
ExpressionVisitor1DefaultMixin<R, A>,
PatternVisitor1DefaultMixin<R, A>,
StatementVisitor1DefaultMixin<R, A>,
VariableVisitor1DefaultMixin<R, A>,
InitializerVisitor1DefaultMixin<R, A>,
MemberVisitor1DefaultMixin<R, A>
implements TreeVisitor1<R, A> {
@@ -972,6 +1019,9 @@ abstract class TreeVisitor1Default<R, A>
@override
R defaultStatement(Statement node, A arg) => defaultTreeNode(node, arg);
@override
R defaultVariableDeclaration(VariableDeclaration node, A arg) =>
defaultTreeNode(node, arg);
@override
R defaultInitializer(Initializer node, A arg) => defaultTreeNode(node, arg);
@override
R defaultMember(Member node, A arg) => defaultTreeNode(node, arg);
@@ -2822,13 +2872,7 @@ abstract class StatementVisitor1<R, A> {
R visitYieldStatement(YieldStatement node, A arg);
R visitPatternVariableDeclaration(PatternVariableDeclaration node, A arg);
R visitFunctionDeclaration(FunctionDeclaration node, A arg);
R visitVariableStatement(VariableStatement node, A arg);
R visitPositionalParameter(PositionalParameter node, A arg);
R visitNamedParameter(NamedParameter node, A arg);
R visitLocalVariable(LocalVariable node, A arg);
R visitCatchVariable(CatchVariable node, A arg);
R visitThisVariable(ThisVariable node, A arg);
R visitSyntheticVariable(SyntheticVariable node, A arg);
R visitLegacyVariableStatement(LegacyVariableStatement node, A arg);
}
/// Helper mixin for [StatementVisitor1] that implements visit methods by
@@ -2895,8 +2939,6 @@ mixin StatementVisitor1DefaultMixin<R, A> implements StatementVisitor1<R, A> {
@override
R visitYieldStatement(YieldStatement node, A arg) =>
defaultStatement(node, arg);
R visitVariableDeclaration(VariableDeclaration node, A arg) =>
defaultStatement(node, arg);
@override
R visitPatternVariableDeclaration(PatternVariableDeclaration node, A arg) =>
defaultStatement(node, arg);
@@ -2904,25 +2946,48 @@ mixin StatementVisitor1DefaultMixin<R, A> implements StatementVisitor1<R, A> {
R visitFunctionDeclaration(FunctionDeclaration node, A arg) =>
defaultStatement(node, arg);
@override
R visitVariableStatement(VariableStatement node, A arg) =>
visitVariableDeclaration(node, arg);
R visitLegacyVariableStatement(LegacyVariableStatement node, A arg) =>
defaultStatement(node, arg);
}
abstract class VariableVisitor1<R, A> {
const VariableVisitor1();
R visitLegacyVariable(LegacyVariable node, A arg);
R visitPositionalParameter(PositionalParameter node, A arg);
R visitNamedParameter(NamedParameter node, A arg);
R visitLocalVariable(LocalVariable node, A arg);
R visitCatchVariable(CatchVariable node, A arg);
R visitThisVariable(ThisVariable node, A arg);
R visitSyntheticVariable(SyntheticVariable node, A arg);
}
/// Helper mixin for [VariableVisitor1] that implements visit methods by
/// delegating to the [visitVariableDeclaration] method.
mixin VariableVisitor1DefaultMixin<R, A> implements VariableVisitor1<R, A> {
R defaultVariableDeclaration(VariableDeclaration node, A arg);
@override
R visitLegacyVariable(LegacyVariable node, A arg) =>
defaultVariableDeclaration(node, arg);
@override
R visitPositionalParameter(PositionalParameter node, A arg) =>
defaultStatement(node, arg);
defaultVariableDeclaration(node, arg);
@override
R visitNamedParameter(NamedParameter node, A arg) =>
defaultStatement(node, arg);
defaultVariableDeclaration(node, arg);
@override
R visitLocalVariable(LocalVariable node, A arg) =>
defaultStatement(node, arg);
defaultVariableDeclaration(node, arg);
@override
R visitCatchVariable(CatchVariable node, A arg) =>
defaultStatement(node, arg);
defaultVariableDeclaration(node, arg);
@override
R visitThisVariable(ThisVariable node, A arg) => defaultStatement(node, arg);
R visitThisVariable(ThisVariable node, A arg) =>
defaultVariableDeclaration(node, arg);
@override
R visitSyntheticVariable(SyntheticVariable node, A arg) =>
defaultStatement(node, arg);
defaultVariableDeclaration(node, arg);
}
/// [DartTypeVisitorExperimentExclusionMixin] is intended to reduce the effects
@@ -3178,9 +3243,31 @@ mixin StatementVisitorExperimentExclusionMixin<R>
R visitVariableDeclaration(VariableDeclaration node);
@override
R visitVariableStatement(VariableStatement node) {
return visitVariableDeclaration(node);
R visitLegacyVariableStatement(LegacyVariableStatement node) {
return visitVariableDeclaration(node.variable);
}
}
/// [VariableVisitorExperimentExclusionMixin] is intended to reduce the effects
/// of CFE experiments on the backends.
///
/// The mixin provides implementations of the visit methods for the experimental
/// nodes. The methods throw an exception signaling that the experimental nodes
/// aren't supported.
mixin VariableVisitorExperimentExclusionMixin<R> implements VariableVisitor<R> {
/// Since [VariableDeclaration] is abstract due to an experiment, it doesn't
/// have its own visit method in [VariableVisitor]. However, for the
/// transitional period the backends would rely on having
/// [visitVariableDeclaration] and on needing to override it. Since the
/// statement visitors in the backends should mix in
/// [VariableVisitorExperimentExclusionMixin], we can deliver the abstract
/// declaration of [visitVariableDeclaration] to them via the mixin. At the
/// same time, it allows us to redirect [visitVariableStatement] to the
/// overrides of [visitVariableDeclarations] the backends already have.
R visitVariableDeclaration(VariableDeclaration node);
@override
R visitLegacyVariable(LegacyVariable node) => visitVariableDeclaration(node);
@override
R visitPositionalParameter(PositionalParameter node) {
@@ -3242,40 +3329,8 @@ mixin StatementVisitor1ExperimentExclusionMixin<R, A>
R visitVariableDeclaration(VariableDeclaration node, A arg);
@override
R visitVariableStatement(VariableStatement node, A arg) {
return visitVariableDeclaration(node, arg);
}
@override
R visitPositionalParameter(PositionalParameter node, A arg) {
throw StateError(
"${runtimeType}.visitPositionalParameter isn't supported.",
);
}
@override
R visitNamedParameter(NamedParameter node, A arg) {
throw StateError("${runtimeType}.visitNamedParameter isn't supported.");
}
@override
R visitLocalVariable(LocalVariable node, A arg) {
throw StateError("${runtimeType}.visitLocalVariable isn't supported.");
}
@override
R visitCatchVariable(CatchVariable node, A arg) {
throw StateError("${runtimeType}.visitCatchVariable isn't supported.");
}
@override
R visitThisVariable(ThisVariable node, A arg) {
throw StateError("${runtimeType}.visitThisVariable isn't supported.");
}
@override
R visitSyntheticVariable(SyntheticVariable node, A arg) {
throw StateError("${runtimeType}.visitSyntheticVariable isn't supported.");
R visitLegacyVariableStatement(LegacyVariableStatement node, A arg) {
return visitVariableDeclaration(node.variable, arg);
}
}
+9 -2
View File
@@ -48,7 +48,7 @@ void main() {
VariableDeclaration variable = test.makeVariable();
test.addNode(
Block([
new Block([variable]),
new Block([new VariableStatement(variable)]),
new ReturnStatement(new VariableGet(variable)),
]),
);
@@ -75,7 +75,14 @@ void main() {
'Variable redeclared',
(TestHarness test) {
VariableDeclaration variable = test.makeVariable();
test.addNode(Block([variable, variable]));
test.addNode(
Procedure(
new Name('bar'),
ProcedureKind.Method,
FunctionNode(null, positionalParameters: [variable, variable]),
fileUri: dummyUri,
)..fileOffset = dummyFileOffset,
);
return variable;
},
(Node? node) => "${errorPrefix}Variable '$node' declared more than once.",
@@ -78,8 +78,10 @@ mixin FinalizableTransformer on Transformer {
final possiblyUninitialized = entry.key;
final alwaysInitialized = entry.value;
addPossiblyUninitializedTo!.statements.insert(
addPossiblyUninitializedTo.statements.indexOf(possiblyUninitialized),
alwaysInitialized,
addPossiblyUninitializedTo.statements.indexOf(
possiblyUninitialized.parent as VariableStatement,
),
VariableStatement(alwaysInitialized),
);
}
assert(_currentScope == scope);
@@ -269,8 +271,8 @@ mixin FinalizableTransformer on Transformer {
}
@override
TreeNode visitVariableDeclaration(VariableDeclaration node) {
node = super.visitVariableDeclaration(node) as VariableDeclaration;
TreeNode defaultVariableDeclaration(VariableDeclaration node) {
node = super.defaultVariableDeclaration(node) as VariableDeclaration;
if (_currentScope == null) {
// Global variable.
return node;
@@ -559,7 +561,10 @@ mixin FinalizableTransformer on Transformer {
isSynthesized: true,
);
return BlockExpression(
Block(<Statement>[resultVariable, ..._reachabilityFences(declarations)]),
Block(<Statement>[
VariableStatement(resultVariable),
..._reachabilityFences(declarations),
]),
VariableGet(resultVariable),
);
}
@@ -642,11 +647,11 @@ class FindCaptures extends RecursiveVisitor {
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
void defaultVariableDeclaration(VariableDeclaration node) {
if (_isFinalizable(node.type)) {
_currentScope.addDeclaration(node);
}
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
}
@override
@@ -740,6 +745,7 @@ ${parent?.toStringIndented(indentation: indentation + 2)}
VariableDeclaration possiblyUninitialized,
VariableDeclaration nullableValue,
) {
assert(possiblyUninitialized.parent is VariableStatement);
_possiblyUninitializedDeclarations[possiblyUninitialized] = nullableValue;
addDeclaration(possiblyUninitialized);
}
@@ -296,7 +296,7 @@ class FfiNativeTransformer extends FfiTransformer {
);
pointerAddress = BlockExpression(
Block([
pointerAddressVar,
VariableStatement(pointerAddressVar),
IfStatement(
InstanceInvocation(
InstanceAccessKind.Instance,
@@ -363,7 +363,7 @@ class FfiNativeTransformer extends FfiTransformer {
List<DartType> dartParameters = dartFunctionType.positionalParameters;
// Create lists of temporary variables for arguments potentially being
// wrapped, and the (potentially) wrapped arguments to be passed.
final temporariesForArguments = [];
final temporariesForArguments = <Statement>[];
final callArguments = <Expression>[];
final fencedArguments = [];
for (int i = 0; i < invocation.arguments.positional.length; i++) {
@@ -374,7 +374,7 @@ class FfiNativeTransformer extends FfiTransformer {
);
// Note: We also evaluate, and assign temporaries for, non-wrapped
// arguments as we need to preserve the original evaluation order.
temporariesForArguments.add(temporary);
temporariesForArguments.add(VariableStatement(temporary));
callArguments.add(
_getTemporary(
temporary,
@@ -419,7 +419,7 @@ class FfiNativeTransformer extends FfiTransformer {
final resultBlock = BlockExpression(
Block(<Statement>[
...temporariesForArguments,
result,
VariableStatement(result),
for (final argument in fencedArguments)
ExpressionStatement(
StaticInvocation(
@@ -387,8 +387,8 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
return BlockExpression(
Block([
arrayVar,
indexVar,
VariableStatement(arrayVar),
VariableStatement(indexVar),
ExpressionStatement(
InstanceInvocation(
InstanceAccessKind.Instance,
@@ -916,7 +916,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
)..fileOffset = fileOffset;
final result = BlockExpression(
Block([pointerVar, closure]),
Block([VariableStatement(pointerVar), closure]),
VariableGet(closure.variable),
);
@@ -1209,7 +1209,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
// expression result: _callback;
return BlockExpression(
Block([nativeCallable, pointerSetter]),
Block([VariableStatement(nativeCallable), pointerSetter]),
VariableGet(nativeCallable),
);
}
@@ -1507,7 +1507,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
)..fileOffset = node.fileOffset;
return BlockExpression(
Block([sourceVar]),
Block([VariableStatement(sourceVar)]),
referencedStruct.generateStore(
sourceVar,
dartType: node.arguments.types[0],
@@ -1588,8 +1588,8 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
return BlockExpression(
Block([
arrayVar,
indexVar,
VariableStatement(arrayVar),
VariableStatement(indexVar),
ExpressionStatement(
InstanceInvocation(
InstanceAccessKind.Instance,
@@ -1858,8 +1858,8 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
)..fileOffset = node.fileOffset;
final checkIndexAndLocalVars = [
arrayVar,
indexVar,
VariableStatement(arrayVar),
VariableStatement(indexVar),
ExpressionStatement(
InstanceInvocation(
InstanceAccessKind.Instance,
@@ -1870,9 +1870,9 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
functionType: arrayCheckIndex.getterType as FunctionType,
),
),
singleElementSizeVar,
elementSizeVar,
offsetVar,
VariableStatement(singleElementSizeVar),
VariableStatement(elementSizeVar),
VariableStatement(offsetVar),
];
if (!setter) {
@@ -1930,7 +1930,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
isSynthesized: true,
)..fileOffset = node.fileOffset;
return BlockExpression(
Block([...checkIndexAndLocalVars, valueVar]),
Block([...checkIndexAndLocalVars, VariableStatement(valueVar)]),
StaticInvocation(
memCopy,
Arguments([
@@ -2440,7 +2440,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer {
isSynthesized: true,
)..fileOffset = fileOffset;
final newArgument = BlockExpression(
Block([valueVar]),
Block([VariableStatement(valueVar)]),
ConstructorInvocation(
compoundFromTypedDataBase,
Arguments([
@@ -143,7 +143,11 @@ class ForInLowering {
)..fileOffset = stmt.bodyOffset;
valueVariable.initializer!.parent = valueVariable;
final whileBody = new Block(<Statement>[valueVariable, stmt.body]);
final whileBody = new Block(<Statement>[
new VariableStatement(valueVariable)
..fileOffset = valueVariable.fileOffset,
stmt.body,
]);
final tryBody = new WhileStatement(whileCondition, whileBody)
..fileOffset = stmt.fileOffset;
@@ -182,8 +186,10 @@ class ForInLowering {
final tryFinally = new TryFinally(tryBody, tryFinalizer);
final block = new Block(<Statement>[
streamVariable,
forIteratorVariable,
new VariableStatement(streamVariable)
..fileOffset = streamVariable.fileOffset,
new VariableStatement(forIteratorVariable)
..fileOffset = forIteratorVariable.fileOffset,
tryFinally,
]);
return block;
@@ -269,17 +275,24 @@ class ForInLowering {
initializer: syncForLoopVariableInitializer,
);
final Block body = Block([syncForLoopVariableInitialization, stmt.body])
..fileOffset = stmt.bodyOffset;
final Block body = Block([
syncForLoopVariableInitialization
..fileOffset = syncForLoopVariableInitialization.fileOffset,
stmt.body,
])..fileOffset = stmt.bodyOffset;
final forStatement = ForStatement([], condition, [], body)
..scope = stmt.scope
..fileOffset = stmt.fileOffset;
return Block([syncForIteratorVariableInitialization, forStatement]);
return Block([
syncForIteratorVariableInitialization
..fileOffset = syncForIteratorVariableInitialization.fileOffset,
forStatement,
]);
}
(VariableDeclaration, VariableDeclaration)
(VariableDeclaration, Statement)
_createSyncForIteratorVariableAndInitialization({
required Expression initializer,
required DartType type,
@@ -302,11 +315,14 @@ class ForInLowering {
type: type,
isSynthesized: true,
)..fileOffset = fileOffset;
return (variableAndInitialization, variableAndInitialization);
return (
variableAndInitialization,
VariableStatement(variableAndInitialization)..fileOffset = fileOffset,
);
}
}
VariableDeclaration _ensureSyncForLoopVariableInitialization({
Statement _ensureSyncForLoopVariableInitialization({
required VariableDeclaration variable,
required Expression initializer,
}) {
@@ -314,10 +330,11 @@ class ForInLowering {
return VariableInitialization(
variable: variable,
initializer: initializer,
);
)..fileOffset = variable.fileOffset;
} else {
initializer.parent = variable;
return variable..initializer = initializer;
variable..initializer = initializer;
return VariableStatement(variable)..fileOffset = variable.fileOffset;
}
}
}
@@ -9,16 +9,16 @@ class LateVarInitTransformer {
const LateVarInitTransformer();
bool _shouldApplyTransform(Statement s) {
if (s is VariableDeclaration) {
if (s is VariableStatement) {
// This transform only applies to late variables.
if (!s.isLate) return false;
if (!s.variable.isLate) return false;
// Const variables are ignored.
if (s.isConst) return false;
if (s.variable.isConst) return false;
// Variables with no initializer or a trivial initializer are ignored.
if (s.initializer == null) return false;
final Expression? init = s.initializer;
if (s.variable.initializer == null) return false;
final Expression? init = s.variable.initializer;
if (init is StringLiteral) return false;
if (init is BoolLiteral) return false;
if (init is IntLiteral) return false;
@@ -34,29 +34,29 @@ class LateVarInitTransformer {
}
List<Statement> _transformVariableDeclaration(
VariableDeclaration node,
VariableStatement node,
LocalFunctionIdGenerator localFunctionIdGenerator,
) {
final fnNode = FunctionNode(
ReturnStatement(node.initializer),
returnType: node.type,
ReturnStatement(node.variable.initializer),
returnType: node.variable.type,
);
final functionType = fnNode.computeThisFunctionType(
Nullability.nonNullable,
);
final fn = FunctionDeclaration(
VariableDeclaration(
"#${node.name}#initializer",
"#${node.variable.name}#initializer",
type: functionType,
isSynthesized: true,
),
fnNode,
)..id = localFunctionIdGenerator.allocateId();
node.initializer = LocalFunctionInvocation(
node.variable.initializer = LocalFunctionInvocation(
fn.variable,
Arguments([]),
functionType: functionType,
)..parent = node;
)..parent = node.variable;
return [fn, node];
}
@@ -71,7 +71,7 @@ class LateVarInitTransformer {
if (_shouldApplyTransform(s)) {
newStatements.addAll(
_transformVariableDeclaration(
s as VariableDeclaration,
s as VariableStatement,
localFunctionIdGenerator,
),
);
@@ -409,7 +409,7 @@ class _VariablesInfoCollector extends RecursiveVisitor {
}
@override
visitVariableDeclaration(VariableDeclaration node) {
defaultVariableDeclaration(VariableDeclaration node) {
final int index = numVariables;
varDeclarations.add(node);
varIndex[node] = index;
@@ -2600,7 +2600,7 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
@override
TypeExpr? visitForStatement(ForStatement node) {
node.variables.forEach(visitVariableDeclaration);
node.variables.forEach((v) => defaultVariableDeclaration(v.variable));
final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
@@ -2808,15 +2808,22 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
}
@override
TypeExpr? visitVariableDeclaration(VariableDeclaration node) {
node.annotations.forEach(_visitAnnotation);
final initializer = node.initializer;
TypeExpr? visitLegacyVariableStatement(LegacyVariableStatement node) {
defaultVariableDeclaration(node.variable);
return null;
}
TypeExpr? defaultVariableDeclaration(VariableDeclaration node) {
final variable = node.variable;
variable.annotations.forEach(_visitAnnotation);
final initializer = variable.initializer;
final TypeExpr initialValue = initializer == null
? ((node.type.nullability == Nullability.nonNullable || node.isLate)
? ((variable.type.nullability == Nullability.nonNullable ||
variable.isLate)
? emptyType
: _nullType)
: _visit(initializer);
_declareVariable(node, initialValue);
_declareVariable(variable, initialValue);
return null;
}
@@ -2886,7 +2893,7 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
@override
TypeExpr? visitLocalInitializer(LocalInitializer node) {
visitVariableDeclaration(node.variable);
defaultVariableDeclaration(node.variable);
return null;
}
@@ -899,12 +899,12 @@ class AnnotateKernel extends RecursiveVisitor {
}
@override
visitVariableDeclaration(VariableDeclaration node) {
defaultVariableDeclaration(VariableDeclaration node) {
final inferredType = _typeFlowAnalysis.capturedVariableType(node);
if (inferredType != null) {
_setInferredType(node, inferredType);
}
super.visitVariableDeclaration(node);
super.defaultVariableDeclaration(node);
}
@override
@@ -12,13 +12,13 @@ RESULT: t3
%this = _Parameter #0 [_T (#lib::C)+]
%x = _Parameter #1
t2 = _Extract (%this[#lib::C/0])
t3 = _TypeCheck (%x against t2) (for #lib::C.T% x;)
t3 = _TypeCheck (%x against t2) (for #lib::C.T% x)
RESULT: t3
------------ C.id2 ------------
%this = _Parameter #0 [_T (#lib::C)+]
%x = _Parameter #1
t2 = _Extract (%this[#lib::C/0])
t3 = _TypeCheck (%x against t2) (for #lib::C.T% x;)
t3 = _TypeCheck (%x against t2) (for #lib::C.T% x)
RESULT: t3
------------ D. ------------
%this = _Parameter #0 [_T (#lib::D)+]
@@ -77,7 +77,7 @@ RESULT: _T {}
%x = _Parameter #1
t2 = _Extract (%this[#lib::C2/0])
t3 = _CreateRuntimeType (dart.core::Comparable @ (t2))
t4 = _TypeCheck (%x against t3) (for dart.core::Comparable<#lib::C2.T%> x;)
t4 = _TypeCheck (%x against t3) (for dart.core::Comparable<#lib::C2.T%> x)
RESULT: t4
------------ C2.id4 ------------
%this = _Parameter #0 [_T (#lib::C2)+]
@@ -85,7 +85,7 @@ RESULT: t4
t2 = _Extract (%this[#lib::C2/0])
t3 = _CreateRuntimeType (#lib::I @ (t2))
t4 = _CreateRuntimeType (#lib::K @ (t3))
t5 = _TypeCheck (%x against t4) (for #lib::K<#lib::I<#lib::C2.T%>> x;)
t5 = _TypeCheck (%x against t4) (for #lib::K<#lib::I<#lib::C2.T%>> x)
RESULT: t5
------------ main ------------
t0* = _Call direct [#lib::C.] (_T (#lib::C<dart.core::int>))
@@ -17,9 +17,9 @@ RESULT: _T {}
%key = _Parameter #1
%value = _Parameter #2
t3 = _Extract (%this[#lib::_NotRealHashMap/0])
t4 = _TypeCheck (%key against t3) (for #lib::_NotRealHashMap.K% key;)
t4 = _TypeCheck (%key against t3) (for #lib::_NotRealHashMap.K% key)
t5 = _Extract (%this[#lib::_NotRealHashMap/1])
t6 = _TypeCheck (%value against t5) (for #lib::_NotRealHashMap.V% value;)
t6 = _TypeCheck (%value against t5) (for #lib::_NotRealHashMap.V% value)
RESULT: _T {}?
------------ InheritedElement. ------------
%this = _Parameter #0 [_T (#lib::InheritedElement)+]