[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:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
046d473d5e
commit
e30cd0322c
@@ -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 &&
|
||||
|
||||
Reference in New Issue
Block a user