[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
@@ -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!)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user