[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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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), () {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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''',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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}',
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-4
@@ -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>))
|
||||
|
||||
+2
-2
@@ -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)+]
|
||||
|
||||
Reference in New Issue
Block a user