From e30cd0322c811cb003da251aaf0b21eb12c39b4e Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Mon, 18 May 2026 05:49:28 -0700 Subject: [PATCH] [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 Reviewed-by: Nicholas Shahan Reviewed-by: Alexander Markov Reviewed-by: Martin Kustermann Commit-Queue: Johnni Winther --- .../shared_interop_transformer.dart | 12 +- pkg/cfg/lib/front_end/ast_to_ir.dart | 9 +- pkg/cfg/lib/front_end/computed_scopes.dart | 7 +- .../src/deferred_load/entity_data_info.dart | 2 +- pkg/compiler/lib/src/inferrer/builder.dart | 11 +- pkg/compiler/lib/src/ir/impact_data.dart | 2 +- pkg/compiler/lib/src/ir/scope_visitor.dart | 25 +- .../modular/late_lowering.dart | 10 +- .../modular/list_factory_specializer.dart | 10 +- .../transformations/modular/transform.dart | 2 +- .../lib/src/serialization/node_indexer.dart | 4 +- pkg/compiler/lib/src/ssa/builder.dart | 11 +- .../lib/src/ssa/switch_continue_analysis.dart | 2 +- pkg/dart2bytecode/lib/bytecode_generator.dart | 9 +- pkg/dart2bytecode/lib/local_vars.dart | 43 +- pkg/dart2wasm/lib/await_transformer.dart | 54 ++- pkg/dart2wasm/lib/closures.dart | 8 +- pkg/dart2wasm/lib/code_generator.dart | 22 +- .../lib/deferred_load/dependencies.dart | 5 +- .../lib/js/callback_specializer.dart | 2 +- pkg/dart2wasm/lib/state_machine.dart | 8 +- pkg/dart2wasm/lib/transformers.dart | 29 +- pkg/dev_compiler/lib/src/kernel/compiler.dart | 47 ++- .../lib/src/kernel/compiler_new.dart | 47 ++- .../src/kernel/module_symbols_collector.dart | 2 +- .../lib/src/kernel/nullable_inference.dart | 2 +- .../api_prototype/lowering_predicates.dart | 8 +- .../src/fragment/constructor/encoding.dart | 25 +- .../lib/src/fragment/setter/declaration.dart | 9 +- .../lib/src/kernel/body_builder.dart | 136 ++++--- pkg/front_end/lib/src/kernel/collections.dart | 28 +- .../lib/src/kernel/constant_evaluator.dart | 113 ++++-- .../lib/src/kernel/dart_scope_calculator.dart | 4 +- .../lib/src/kernel/external_ast_helper.dart | 4 + .../lib/src/kernel/internal_ast.dart | 67 ++-- .../lib/src/kernel/internal_ast_helper.dart | 30 +- .../lib/src/kernel/late_lowering.dart | 2 +- .../lib/src/testing/id_extractor.dart | 2 +- .../src/type_inference/inference_visitor.dart | 156 +++++--- .../inference_visitor_base.dart | 6 +- .../src/type_inference/matching_cache.dart | 6 +- pkg/front_end/test/incremental_suite.dart | 6 +- .../test/predicates/predicate_test.dart | 4 +- .../static_types/type_arguments_test.dart | 25 +- pkg/front_end/test/testing/suite.dart | 10 +- ...internal_ast_text_representation_test.dart | 95 +++-- .../synthetic_variables.dart.strong.expect | 2 +- ...hetic_variables.dart.strong.modular.expect | 2 +- pkg/front_end/testcases/modular.status | 2 +- pkg/front_end/testcases/strong.status | 3 +- pkg/front_end/tool/ast_model.dart | 4 +- pkg/front_end/tool/unreachable_if_finder.dart | 4 +- pkg/kernel/lib/binary/ast_from_binary.dart | 21 +- pkg/kernel/lib/binary/ast_to_binary.dart | 11 +- pkg/kernel/lib/clone.dart | 15 +- pkg/kernel/lib/src/ast/components.dart | 4 +- pkg/kernel/lib/src/ast/dummies.dart | 9 + pkg/kernel/lib/src/ast/statements.dart | 371 +++++------------- pkg/kernel/lib/src/ast/variables.dart | 65 +-- pkg/kernel/lib/src/coverage.dart | 13 +- pkg/kernel/lib/src/equivalence.dart | 277 ++++++------- pkg/kernel/lib/src/node_creator.dart | 52 ++- pkg/kernel/lib/src/printer.dart | 3 +- pkg/kernel/lib/text/ast_to_text.dart | 57 +-- pkg/kernel/lib/text/debug_printer.dart | 2 +- pkg/kernel/lib/type_checker.dart | 30 +- pkg/kernel/lib/verifier.dart | 41 +- pkg/kernel/lib/visitor.dart | 195 +++++---- pkg/kernel/test/verify_test.dart | 11 +- .../transformations/ffi/finalizable.dart | 20 +- .../modular/transformations/ffi/native.dart | 8 +- .../transformations/ffi/use_sites.dart | 28 +- .../transformations/for_in_lowering.dart | 39 +- .../late_var_init_transformer.dart | 24 +- .../type_flow/summary_collector.dart | 23 +- .../type_flow/transformer.dart | 4 +- .../class_generics_basic.dart.expect | 8 +- .../class_generics_case1.dart.expect | 4 +- 78 files changed, 1341 insertions(+), 1132 deletions(-) diff --git a/pkg/_js_interop_checks/lib/src/transformations/shared_interop_transformer.dart b/pkg/_js_interop_checks/lib/src/transformations/shared_interop_transformer.dart index 6ac643e6435..f00b095379d 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/shared_interop_transformer.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/shared_interop_transformer.dart @@ -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 diff --git a/pkg/cfg/lib/front_end/ast_to_ir.dart b/pkg/cfg/lib/front_end/ast_to_ir.dart index 42514101c31..07457ffc45e 100644 --- a/pkg/cfg/lib/front_end/ast_to_ir.dart +++ b/pkg/cfg/lib/front_end/ast_to_ir.dart @@ -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 diff --git a/pkg/cfg/lib/front_end/computed_scopes.dart b/pkg/cfg/lib/front_end/computed_scopes.dart index 046c730ba69..8037d1b3b9d 100644 --- a/pkg/cfg/lib/front_end/computed_scopes.dart +++ b/pkg/cfg/lib/front_end/computed_scopes.dart @@ -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); } diff --git a/pkg/compiler/lib/src/deferred_load/entity_data_info.dart b/pkg/compiler/lib/src/deferred_load/entity_data_info.dart index a97dd2923f9..cb1d6c04b64 100644 --- a/pkg/compiler/lib/src/deferred_load/entity_data_info.dart +++ b/pkg/compiler/lib/src/deferred_load/entity_data_info.dart @@ -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. diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart index 11537531b37..1f637771396 100644 --- a/pkg/compiler/lib/src/inferrer/builder.dart +++ b/pkg/compiler/lib/src/inferrer/builder.dart @@ -939,7 +939,14 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault } @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 @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), () { diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart index b61767854ef..20324dee283 100644 --- a/pkg/compiler/lib/src/ir/impact_data.dart +++ b/pkg/compiler/lib/src/ir/impact_data.dart @@ -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(); } diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart index 0bdaa57c06f..577eb13b029 100644 --- a/pkg/compiler/lib/src/ir/scope_visitor.dart +++ b/pkg/compiler/lib/src/ir/scope_visitor.dart @@ -322,8 +322,15 @@ class ScopeModelBuilder extends ir.VisitorDefault } @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 // 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 }); // 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); } } }); diff --git a/pkg/compiler/lib/src/kernel/transformations/modular/late_lowering.dart b/pkg/compiler/lib/src/kernel/transformations/modular/late_lowering.dart index add55135743..25c23c5dcc7 100644 --- a/pkg/compiler/lib/src/kernel/transformations/modular/late_lowering.dart +++ b/pkg/compiler/lib/src/kernel/transformations/modular/late_lowering.dart @@ -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( diff --git a/pkg/compiler/lib/src/kernel/transformations/modular/list_factory_specializer.dart b/pkg/compiler/lib/src/kernel/transformations/modular/list_factory_specializer.dart index 448d2ee7e62..f85cb9ae0ef 100644 --- a/pkg/compiler/lib/src/kernel/transformations/modular/list_factory_specializer.dart +++ b/pkg/compiler/lib/src/kernel/transformations/modular/list_factory_specializer.dart @@ -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 diff --git a/pkg/compiler/lib/src/kernel/transformations/modular/transform.dart b/pkg/compiler/lib/src/kernel/transformations/modular/transform.dart index 117a9c1dd7e..952b0229918 100644 --- a/pkg/compiler/lib/src/kernel/transformations/modular/transform.dart +++ b/pkg/compiler/lib/src/kernel/transformations/modular/transform.dart @@ -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); } diff --git a/pkg/compiler/lib/src/serialization/node_indexer.dart b/pkg/compiler/lib/src/serialization/node_indexer.dart index 91c459b94ec..15ae06855c4 100644 --- a/pkg/compiler/lib/src/serialization/node_indexer.dart +++ b/pkg/compiler/lib/src/serialization/node_indexer.dart @@ -44,11 +44,11 @@ class TreeNodeIndexerVisitor extends ir.VisitorDefault } @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 diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart index 4152cbaa56d..4a5e23f672a 100644 --- a/pkg/compiler/lib/src/ssa/builder.dart +++ b/pkg/compiler/lib/src/ssa/builder.dart @@ -2565,7 +2565,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault 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 } @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 with ir.VisitorVoidMixin { } @override - void visitVariableDeclaration(ir.VariableDeclaration node) { + void defaultVariableDeclaration(ir.VariableDeclaration node) { registerRegularNode(); skipReductiveNodes(() { visitList(node.annotations); diff --git a/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart b/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart index df00c38681d..b1276b4d09d 100644 --- a/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart +++ b/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart @@ -120,7 +120,7 @@ class SwitchContinueAnalysis extends ir.VisitorDefault 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 ' diff --git a/pkg/dart2bytecode/lib/bytecode_generator.dart b/pkg/dart2bytecode/lib/bytecode_generator.dart index 4829531df93..3609bb892df 100644 --- a/pkg/dart2bytecode/lib/bytecode_generator.dart +++ b/pkg/dart2bytecode/lib/bytecode_generator.dart @@ -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) { diff --git a/pkg/dart2bytecode/lib/local_vars.dart b/pkg/dart2bytecode/lib/local_vars.dart index 73696214902..f46f8ff4df1 100644 --- a/pkg/dart2bytecode/lib/local_vars.dart +++ b/pkg/dart2bytecode/lib/local_vars.dart @@ -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); } diff --git a/pkg/dart2wasm/lib/await_transformer.dart b/pkg/dart2wasm/lib/await_transformer.dart index 78114b45fae..0f54c13af1a 100644 --- a/pkg/dart2wasm/lib/await_transformer.dart +++ b/pkg/dart2wasm/lib/await_transformer.dart @@ -91,7 +91,8 @@ class _AwaitTransformer extends Transformer { Statement newBody = transformer.transform(body); final List newStatements = [ - ...transformer.expressionTransformer.variables, + for (final variable in transformer.expressionTransformer.variables) + VariableStatement(variable), ...transformer.statements, ]; @@ -248,13 +249,13 @@ class _AwaitTransformer extends Transformer { List> initEffects = List>.generate(length, ( int i, ) { - VariableDeclaration decl = stmt.variables[i]; + VariableStatement decl = stmt.variables[i]; List statements = []; - 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 updates = []; List newBody = [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([...temps, labeled]); + return Block([ + 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 { // // // and return the body's value. - statements.add(variable); + statements.add(VariableStatement(variable)); var index = nameIndex; seenAwait = false; variable.initializer = transform(variable.initializer!) diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart index 3ae1be209a4..9f29388a465 100644 --- a/pkg/dart2wasm/lib/closures.dart +++ b/pkg/dart2wasm/lib/closures.dart @@ -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 diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart index 7b374f38cd6..12c47f63088 100644 --- a/pkg/dart2wasm/lib/code_generator.dart +++ b/pkg/dart2wasm/lib/code_generator.dart @@ -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 diff --git a/pkg/dart2wasm/lib/deferred_load/dependencies.dart b/pkg/dart2wasm/lib/deferred_load/dependencies.dart index 3e3f346f916..c55c21785fc 100644 --- a/pkg/dart2wasm/lib/deferred_load/dependencies.dart +++ b/pkg/dart2wasm/lib/deferred_load/dependencies.dart @@ -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); diff --git a/pkg/dart2wasm/lib/js/callback_specializer.dart b/pkg/dart2wasm/lib/js/callback_specializer.dart index 76ec11db72f..92e454de8cd 100644 --- a/pkg/dart2wasm/lib/js/callback_specializer.dart +++ b/pkg/dart2wasm/lib/js/callback_specializer.dart @@ -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 diff --git a/pkg/dart2wasm/lib/state_machine.dart b/pkg/dart2wasm/lib/state_machine.dart index 36eb636d12c..7fa0a85135c 100644 --- a/pkg/dart2wasm/lib/state_machine.dart +++ b/pkg/dart2wasm/lib/state_machine.dart @@ -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); diff --git a/pkg/dart2wasm/lib/transformers.dart b/pkg/dart2wasm/lib/transformers.dart index 49e6082bc1d..b8fb4a4d9bd 100644 --- a/pkg/dart2wasm/lib/transformers.dart +++ b/pkg/dart2wasm/lib/transformers.dart @@ -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(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(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 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) { diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index ca43d5a9dbf..4b0780095bb 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -4861,10 +4861,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor @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.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 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 // 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 // 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. diff --git a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart index 922e363bfbe..200cbf49dec 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart @@ -5475,10 +5475,10 @@ class LibraryCompiler extends ComputeOnceConstantVisitor @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.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 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 // 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 // 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. diff --git a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart index eea2bfa8cfb..1de9e3ab4d2 100644 --- a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart +++ b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart @@ -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; diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart index 30ef95e9141..7569c3d05d3 100644 --- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart +++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart @@ -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 && diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart index 412e43e4190..7fb1228ddc1 100644 --- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart +++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart @@ -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 `` 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; diff --git a/pkg/front_end/lib/src/fragment/constructor/encoding.dart b/pkg/front_end/lib/src/fragment/constructor/encoding.dart index 1d10e09f4ca..bcc89d261ef 100644 --- a/pkg/front_end/lib/src/fragment/constructor/encoding.dart +++ b/pkg/front_end/lib/src/fragment/constructor/encoding.dart @@ -778,11 +778,14 @@ mixin _ExtensionTypeConstructorEncodingMixin } if (!_isExternal) { VariableDeclaration thisVariable = this.thisVariable!; - List statements = [thisVariable]; + VariableStatement thisVariableStatement = extern.createVariableStatement( + thisVariable, + ); + List statements = [thisVariableStatement]; _ExtensionTypeInitializerToStatementConverter visitor = new _ExtensionTypeInitializerToStatementConverter( statements, - thisVariable, + thisVariableStatement, ); for (Initializer initializer in _initializers) { initializer.accept(visitor); @@ -847,12 +850,12 @@ mixin _ExtensionTypeConstructorEncodingMixin class _ExtensionTypeInitializerToStatementConverter implements InitializerVisitor { - VariableDeclaration thisVariable; + VariableStatement thisVariableStatement; final List 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 diff --git a/pkg/front_end/lib/src/fragment/setter/declaration.dart b/pkg/front_end/lib/src/fragment/setter/declaration.dart index 33af73ef304..2bcaf5099db 100644 --- a/pkg/front_end/lib/src/fragment/setter/declaration.dart +++ b/pkg/front_end/lib/src/fragment/setter/declaration.dart @@ -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 statements = []; 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, diff --git a/pkg/front_end/lib/src/kernel/body_builder.dart b/pkg/front_end/lib/src/kernel/body_builder.dart index 51adcef3699..aa47bdbbe9e 100644 --- a/pkg/front_end/lib/src/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/kernel/body_builder.dart @@ -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 ??= []).add( - // variableInitialization, - // ); + _registerSingleTargetAnnotations(variableInitialization.variable); } push(variableInitialization); } else { - List? variables = - const FixedNullableList().popNonNullable( + List? variables = + const FixedNullableList().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? _buildForLoopVariableDeclarations( + List? _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 [variableOrExpression]; + variableOrExpression.variable.isLate = false; + return [variableOrExpression]; } else if (variableOrExpression is Expression) { VariableDeclaration variable = new VariableDeclarationImpl.forEffect( variableOrExpression, ); - return [variable]; + return [intern.createVariableStatement(variable)]; } else if (variableOrExpression is ExpressionStatement) { // Coverage-ignore-block(suite): Not run. VariableDeclaration variable = new VariableDeclarationImpl.forEffect( variableOrExpression.expression, ); - return [variable]; + return [intern.createVariableStatement(variable)]; } else if (intern.isVariablesDeclaration(variableOrExpression)) { return intern.variablesDeclarationExtractDeclarations( variableOrExpression, ); } else if (variableOrExpression is List) { // Coverage-ignore-block(suite): Not run. - List variables = []; + List variables = []; for (Object v in variableOrExpression) { variables.addAll(_buildForLoopVariableDeclarations(v)!); } return variables; } else if (variableOrExpression is PatternVariableDeclaration) { // Coverage-ignore-block(suite): Not run. - return []; + return []; } else if (variableOrExpression is ParserRecovery) { - return []; + return []; } else if (variableOrExpression == null) { - return []; + 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? variables; + List? variables; List? intermediateVariables; if (variableOrExpression is PatternVariableDeclaration) { - variables = pop() as List; // Internal variables. + variables = (pop() as List) + .map(intern.createVariableStatement) + .toList(); // Internal variables. intermediateVariables = pop() as List; } else { variables = _buildForLoopVariableDeclarations(variableOrExpression)!; @@ -4086,10 +4092,12 @@ class BodyBuilderImpl extends StackListenerImpl .deferNode(); Object? variableOrExpression = pop(); - List? variables; + List? variables; List? intermediateVariables; if (variableOrExpression is PatternVariableDeclaration) { - variables = pop() as List; + variables = (pop() as List) + .map(intern.createVariableStatement) + .toList(); // Internal variables. intermediateVariables = pop() as List; } else { variables = _buildForLoopVariableDeclarations(variableOrExpression); @@ -4132,7 +4140,13 @@ class BodyBuilderImpl extends StackListenerImpl result = intern.createBlock( fileOffset: result.fileOffset, fileEndOffset: result.fileOffset, - [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) { diff --git a/pkg/front_end/lib/src/kernel/collections.dart b/pkg/front_end/lib/src/kernel/collections.dart index c0865b7440b..ef4dd177686 100644 --- a/pkg/front_end/lib/src/kernel/collections.dart +++ b/pkg/front_end/lib/src/kernel/collections.dart @@ -222,10 +222,10 @@ class ForElement extends ControlFlowElement implements ForElementBase { // May be empty, but not null. @override - final List variableInitializations; + final List variableInitializations; @override - List get variables => variableInitializations.cast(); + List 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 get variableInitializations; + List get variableInitializations; - List get variables; + List get variables; abstract Expression? condition; @@ -481,10 +481,10 @@ class PatternForElement extends ControlFlowElementImpl // May be empty, but not null. @override - final List variableInitializations; + final List variableInitializations; @override - List get variables => variableInitializations.cast(); + List 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 variables, + required List 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 get variables; + List 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 variables; + final List 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 intermediateVariables; @override - final List variables; + final List variables; @override Expression? condition; @@ -788,7 +788,7 @@ class PatternForMapEntry extends TreeNode printer.write(', '); } printer.writeVariableInitialization( - variables[index], + variables[index].variable, includeModifiersAndType: index == 0, ); } diff --git a/pkg/front_end/lib/src/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/kernel/constant_evaluator.dart index c5a38048943..8c453e38ad3 100644 --- a/pkg/front_end/lib/src/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/kernel/constant_evaluator.dart @@ -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 cacheVariables = [...matchingCache.declarations]; - Iterable declarations = + List cacheVariables = [ + for (VariableDeclaration declaration in matchingCache.declarations) + extern.createVariableStatement(declaration), + ]; + Iterable 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 - implements StatementVisitor { + with + StatementVisitorExperimentExclusionMixin, + VariableVisitorExperimentExclusionMixin + implements + StatementVisitor, + VariableVisitor { 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; } diff --git a/pkg/front_end/lib/src/kernel/dart_scope_calculator.dart b/pkg/front_end/lib/src/kernel/dart_scope_calculator.dart index cbcb0fbda58..10e84e24552 100644 --- a/pkg/front_end/lib/src/kernel/dart_scope_calculator.dart +++ b/pkg/front_end/lib/src/kernel/dart_scope_calculator.dart @@ -376,9 +376,9 @@ class DartScopeBuilder2 extends VisitorDefault 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); } diff --git a/pkg/front_end/lib/src/kernel/external_ast_helper.dart b/pkg/front_end/lib/src/kernel/external_ast_helper.dart index 9992bff78b6..5a0a01cd9ba 100644 --- a/pkg/front_end/lib/src/kernel/external_ast_helper.dart +++ b/pkg/front_end/lib/src/kernel/external_ast_helper.dart @@ -916,3 +916,7 @@ Expression createVariableSet( return new VariableSet(variable, value)..fileOffset = fileOffset; } } + +VariableStatement createVariableStatement(VariableDeclaration variable) { + return new VariableStatement(variable)..fileOffset = variable.fileOffset; +} diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart index f25b4ce1cd3..451dd36a5eb 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast.dart @@ -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(StatementVisitor v) => v.visitLocalVariable(astVariable); + R accept(VariableVisitor v) => v.visitLocalVariable(astVariable); @override // Coverage-ignore(suite): Not run. - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 v, A arg) => v.visitLocalVariable(astVariable, arg); @override @@ -1125,13 +1124,12 @@ class InternalLocalVariable extends TreeNode int binaryOffsetNoTag = -1; @override - List? get capturedContexts { - throw new UnsupportedError("${this.runtimeType}.capturedContexts"); - } + List? get capturedContexts => + variableInitialization?.capturedContexts; @override void set capturedContexts(List? value) { - throw new UnsupportedError("${this.runtimeType}.capturedContexts="); + variableInitialization!.capturedContexts = value; } @override @@ -1190,11 +1188,11 @@ class InternalPositionalParameter extends TreeNode } @override - R accept(StatementVisitor v) => v.visitPositionalParameter(astVariable); + R accept(VariableVisitor v) => v.visitPositionalParameter(astVariable); @override // Coverage-ignore(suite): Not run. - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 v, A arg) => v.visitPositionalParameter(astVariable, arg); @override @@ -1296,11 +1294,11 @@ class InternalNamedParameter extends TreeNode } @override - R accept(StatementVisitor v) => v.visitNamedParameter(astVariable); + R accept(VariableVisitor v) => v.visitNamedParameter(astVariable); @override // Coverage-ignore(suite): Not run. - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 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(StatementVisitor v) { + R accept(VariableVisitor v) { return astVariable.accept(v); } @override // Coverage-ignore(suite): Not run. - R accept1(StatementVisitor1 v, A arg) { + R accept1(VariableVisitor1 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 variableDeclarations; + final List 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, ); diff --git a/pkg/front_end/lib/src/kernel/internal_ast_helper.dart b/pkg/front_end/lib/src/kernel/internal_ast_helper.dart index 21c79b0f36d..f27b961e5ed 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast_helper.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast_helper.dart @@ -302,7 +302,7 @@ Statement createExpressionStatement( ForElement createForElement( int fileOffset, - List variables, + List variables, Expression? condition, List updates, Expression body, @@ -363,7 +363,7 @@ ForInStatement createForInStatement( ForMapEntry createForMapEntry( int fileOffset, - List variables, + List variables, Expression? condition, List updates, MapLiteralEntry body, @@ -375,7 +375,7 @@ ForMapEntry createForMapEntry( /// Return a representation of a for statement. Statement createForStatement( int fileOffset, - List? variables, + List? variables, Expression? condition, List updaters, Statement body, @@ -810,7 +810,7 @@ PatternForElement createPatternForElement( int fileOffset, { required PatternVariableDeclaration patternVariableDeclaration, required List intermediateVariables, - required List variables, + required List variables, required Expression? condition, required List updates, required Expression body, @@ -829,7 +829,7 @@ PatternForMapEntry createPatternForMapEntry( int fileOffset, { required PatternVariableDeclaration patternVariableDeclaration, required List intermediateVariables, - required List variableInitializations, + required List variableInitializations, required Expression? condition, required List 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 declarations, + List declarations, Uri uri, ) { return new _VariablesDeclaration(declarations, uri); } -List variablesDeclarationExtractDeclarations( +List variablesDeclarationExtractDeclarations( Object? variablesDeclaration, ) { return (variablesDeclaration as _VariablesDeclaration).declarations; @@ -1306,9 +1310,13 @@ List variablesDeclarationExtractDeclarations( Statement wrapVariables(Statement statement) { if (statement is _VariablesDeclaration) { return new Block( - new List.of(statement.declarations, growable: true), + new List.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])..fileOffset = statement.fileOffset; } else { return statement; @@ -1316,7 +1324,7 @@ Statement wrapVariables(Statement statement) { } class _VariablesDeclaration extends AuxiliaryStatement { - final List declarations; + final List 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, ); } diff --git a/pkg/front_end/lib/src/kernel/late_lowering.dart b/pkg/front_end/lib/src/kernel/late_lowering.dart index 6d6c5b4d0ce..8346c854b74 100644 --- a/pkg/front_end/lib/src/kernel/late_lowering.dart +++ b/pkg/front_end/lib/src/kernel/late_lowering.dart @@ -158,7 +158,7 @@ Statement createGetterWithInitializerWithRecheck( new Not(createIsSetRead()..fileOffset = fileOffset) ..fileOffset = fileOffset, new Block([ - temp, + new VariableStatement(temp)..fileOffset = temp.fileOffset, new IfStatement( createIsSetRead()..fileOffset = fileOffset, new ExpressionStatement(exception)..fileOffset = fileOffset, diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart index 6ea2b2eb229..44e8719f482 100644 --- a/pkg/front_end/lib/src/testing/id_extractor.dart +++ b/pkg/front_end/lib/src/testing/id_extractor.dart @@ -334,7 +334,7 @@ abstract class DataExtractor extends VisitorDefault } @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( diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/type_inference/inference_visitor.dart index 37be2a76f85..962b50defbc 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart @@ -3441,9 +3441,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase scopeProviderInfoKind: ScopeProviderInfoKind.Loop, ); } - List? variables; + List? 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 = []; + 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 inferredConditionTypes, ) { // TODO(johnniwinther): Use _visitStatements instead. - List? variables; + List? 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 = []; + 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([ - 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([ - 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 variables, + List variables, Expression? condition, List 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? variables; + List? 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 = []; + 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 statements = [setVar]; + List 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 result = []; - 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}) { diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart index d188701240f..add668f9f18 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart @@ -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 diff --git a/pkg/front_end/lib/src/type_inference/matching_cache.dart b/pkg/front_end/lib/src/type_inference/matching_cache.dart index 0aec636f303..01d3a8a071a 100644 --- a/pkg/front_end/lib/src/type_inference/matching_cache.dart +++ b/pkg/front_end/lib/src/type_inference/matching_cache.dart @@ -49,7 +49,7 @@ class MatchingCache { bool _isClosed = false; /// The declarations need for the cached expressions. - List _declarations = []; + List _declarations = []; /// Map for the known cached keys and their corresponding expressions. Map _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 get declarations { + Iterable get declarations { _isClosed = true; return _declarations; } diff --git a/pkg/front_end/test/incremental_suite.dart b/pkg/front_end/test/incremental_suite.dart index 630ac96db17..b737162e728 100644 --- a/pkg/front_end/test/incremental_suite.dart +++ b/pkg/front_end/test/incremental_suite.dart @@ -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; } diff --git a/pkg/front_end/test/predicates/predicate_test.dart b/pkg/front_end/test/predicates/predicate_test.dart index 8e40f68ab2c..e45e47438ba 100644 --- a/pkg/front_end/test/predicates/predicate_test.dart +++ b/pkg/front_end/test/predicates/predicate_test.dart @@ -215,7 +215,7 @@ class PredicateDataExtractor extends CfeDataExtractor { } @override - void visitVariableDeclaration(VariableDeclaration node) { + void defaultVariableDeclaration(VariableDeclaration node) { Object? identity; String? name; String? tag; @@ -257,7 +257,7 @@ class PredicateDataExtractor extends CfeDataExtractor { features[Tags.name] = name; } } - super.visitVariableDeclaration(node); + super.defaultVariableDeclaration(node); } @override diff --git a/pkg/front_end/test/static_types/type_arguments_test.dart b/pkg/front_end/test/static_types/type_arguments_test.dart index 8fc3bd834f4..dcd21e9e48a 100644 --- a/pkg/front_end/test/static_types/type_arguments_test.dart +++ b/pkg/front_end/test/static_types/type_arguments_test.dart @@ -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) { diff --git a/pkg/front_end/test/testing/suite.dart b/pkg/front_end/test/testing/suite.dart index e13de588e28..17ec5d37510 100644 --- a/pkg/front_end/test/testing/suite.dart +++ b/pkg/front_end/test/testing/suite.dart @@ -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; } diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart index 8cb4f904236..a1524db2abe 100644 --- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart +++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart @@ -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''', ); } diff --git a/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.expect b/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.expect index 2d4352ed503..0eedf765112 100644 --- a/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.expect +++ b/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.expect @@ -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; diff --git a/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.modular.expect b/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.modular.expect index 2d4352ed503..0eedf765112 100644 --- a/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.modular.expect +++ b/pkg/front_end/testcases/closure_context_lowering/synthetic_variables.dart.strong.modular.expect @@ -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; diff --git a/pkg/front_end/testcases/modular.status b/pkg/front_end/testcases/modular.status index 37bbc147126..7a635f042c7 100644 --- a/pkg/front_end/testcases/modular.status +++ b/pkg/front_end/testcases/modular.status @@ -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 diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status index bba943fdade..18e12cddf25 100644 --- a/pkg/front_end/testcases/strong.status +++ b/pkg/front_end/testcases/strong.status @@ -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 diff --git a/pkg/front_end/tool/ast_model.dart b/pkg/front_end/tool/ast_model.dart index a3d0a0e8ac5..664f7598893 100644 --- a/pkg/front_end/tool/ast_model.dart +++ b/pkg/front_end/tool/ast_model.dart @@ -32,7 +32,7 @@ Uri computePackageConfig(Uri repoDir) => /// defining its identity. const Map _declarativeClassesNames = const { // TODO(johnniwinther): This should be [VariableDeclaration]. - 'VariableStatement': 'name', + 'LegacyVariable': 'name', 'TypeParameter': 'name', 'StructuralParameter': 'name', 'LabeledStatement': null, @@ -151,7 +151,7 @@ const Map> _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)}, diff --git a/pkg/front_end/tool/unreachable_if_finder.dart b/pkg/front_end/tool/unreachable_if_finder.dart index f7b0a4db103..94cf0e64db3 100644 --- a/pkg/front_end/tool/unreachable_if_finder.dart +++ b/pkg/front_end/tool/unreachable_if_finder.dart @@ -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 diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 04c4be82744..61637e5bca1 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -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 variables = readAndPushVariableDeclarationList(); + List variables = readAndPushVariableStatementList(); Expression? condition = readExpressionOption(); List 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 readAndPushVariableStatementList() { + List list = readAndPushVariableDeclarationList(); + return new List.generate( + list.length, + (int index) => + new VariableStatement(list[index]) + ..fileOffset = list[index].fileOffset, + ); + } + List readAndPushVariableDeclarationList() { int length = readUInt30(); if (!useGrowableLists && length == 0) { diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index c94bd1f1bd0..6385f2343d6 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -20,6 +20,7 @@ class BinaryPrinter TreeVisitorExperimentExclusionMixin, DartTypeVisitorExperimentExclusionMixin, StatementVisitorExperimentExclusionMixin, + VariableVisitorExperimentExclusionMixin, ExpressionVisitorExperimentExclusionMixin implements Visitor, 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 nodes) { + writeList(nodes, writeVariableStatement); + } + void writeVariableDeclarationList(List nodes) { writeList(nodes, writeVariableDeclaration); } diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart index 3e5ea9af643..907db1a5743 100644 --- a/pkg/kernel/lib/clone.dart +++ b/pkg/kernel/lib/clone.dart @@ -607,7 +607,7 @@ class CloneVisitorNotMembers @override TreeNode visitForStatement(ForStatement node) { - List variables = node.variables.map(clone).toList(); + List 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 [] - ..fileEqualsOffset = _cloneFileOffset(node.fileEqualsOffset); + : const []; } @override diff --git a/pkg/kernel/lib/src/ast/components.dart b/pkg/kernel/lib/src/ast/components.dart index 8086702d6fd..49557bb614a 100644 --- a/pkg/kernel/lib/src/ast/components.dart +++ b/pkg/kernel/lib/src/ast/components.dart @@ -368,6 +368,8 @@ abstract class MetadataRepository { 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); } } diff --git a/pkg/kernel/lib/src/ast/dummies.dart b/pkg/kernel/lib/src/ast/dummies.dart index b0cb53efa20..a1eb579e935 100644 --- a/pkg/kernel/lib/src/ast/dummies.dart +++ b/pkg/kernel/lib/src/ast/dummies.dart @@ -472,6 +472,15 @@ final List 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 diff --git a/pkg/kernel/lib/src/ast/statements.dart b/pkg/kernel/lib/src/ast/statements.dart index 8c62e39040a..e12626cc220 100644 --- a/pkg/kernel/lib/src/ast/statements.dart +++ b/pkg/kernel/lib/src/ast/statements.dart @@ -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 variables; + final List variables; // TODO(61572): Remove this. - List get variableInitializations => variables; + List get variableInitializations => variables; Expression? condition; // May be null. final List 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(StatementVisitor v) => v.visitVariableStatement(this); + R accept(VariableVisitor v) => v.visitLegacyVariable(this); @override - R accept1(StatementVisitor1 v, A arg) => - v.visitVariableStatement(this, arg); + R accept1(VariableVisitor1 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(StatementVisitor v) => v.visitLegacyVariableStatement(this); + + @override + R accept1(StatementVisitor1 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(StatementVisitor 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 annotations = const []; - @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 = []; @@ -2254,142 +2196,7 @@ class VariableInitialization extends Statement implements VariableDeclaration { annotations.add(node..parent = this); } - @override void clearAnnotations() { annotations = const []; } - - @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"); - } } diff --git a/pkg/kernel/lib/src/ast/variables.dart b/pkg/kernel/lib/src/ast/variables.dart index b2368c32f5f..382e3de9586 100644 --- a/pkg/kernel/lib/src/ast/variables.dart +++ b/pkg/kernel/lib/src/ast/variables.dart @@ -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(VariableVisitor visitor); + + @override + R accept1(VariableVisitor1 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 annotations = const []; @@ -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(StatementVisitor v) => v.visitLocalVariable(this); + R accept(VariableVisitor v) => v.visitLocalVariable(this); @override - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 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(StatementVisitor v) => v.visitCatchVariable(this); + R accept(VariableVisitor v) => v.visitCatchVariable(this); @override - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 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(StatementVisitor v) => v.visitPositionalParameter(this); + R accept(VariableVisitor v) => v.visitPositionalParameter(this); @override - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 v, A arg) => v.visitPositionalParameter(this, arg); @override @@ -1210,10 +1213,10 @@ class NamedParameter extends FunctionParameter { } @override - R accept(StatementVisitor v) => v.visitNamedParameter(this); + R accept(VariableVisitor v) => v.visitNamedParameter(this); @override - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 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(StatementVisitor v) => v.visitThisVariable(this); + R accept(VariableVisitor v) => v.visitThisVariable(this); @override - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 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(StatementVisitor v) => v.visitSyntheticVariable(this); + R accept(VariableVisitor v) => v.visitSyntheticVariable(this); @override - R accept1(StatementVisitor1 v, A arg) => + R accept1(VariableVisitor1 v, A arg) => v.visitSyntheticVariable(this, arg); @override diff --git a/pkg/kernel/lib/src/coverage.dart b/pkg/kernel/lib/src/coverage.dart index 32dfd84b190..c4998baf39d 100644 --- a/pkg/kernel/lib/src/coverage.dart +++ b/pkg/kernel/lib/src/coverage.dart @@ -956,8 +956,8 @@ class CoverageVisitor implements Visitor { } @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 { 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, } diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart index 2b5249cd814..6ecaafd410e 100644 --- a/pkg/kernel/lib/src/equivalence.dart +++ b/pkg/kernel/lib/src/equivalence.dart @@ -836,8 +836,8 @@ class EquivalenceVisitor implements Visitor1 { } @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 { 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 { 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, diff --git a/pkg/kernel/lib/src/node_creator.dart b/pkg/kernel/lib/src/node_creator.dart index 4eb2fc1f8ab..ebca61bb722 100644 --- a/pkg/kernel/lib/src/node_creator.dart +++ b/pkg/kernel/lib/src/node_creator.dart @@ -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."); } diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart index cf7298deea4..04fb2b70998 100644 --- a/pkg/kernel/lib/src/printer.dart +++ b/pkg/kernel/lib/src/printer.dart @@ -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; } diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart index 1734f524fbc..44b3d6c25b9 100644 --- a/pkg/kernel/lib/text/ast_to_text.dart +++ b/pkg/kernel/lib/text/ast_to_text.dart @@ -1248,9 +1248,16 @@ class Printer extends VisitorDefault 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 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 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 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 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 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 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); } } diff --git a/pkg/kernel/lib/text/debug_printer.dart b/pkg/kernel/lib/text/debug_printer.dart index c3b66ff4135..c234028ecf5 100644 --- a/pkg/kernel/lib/text/debug_printer.dart +++ b/pkg/kernel/lib/text/debug_printer.dart @@ -85,7 +85,7 @@ class DebugPrinter extends VisitorDefault } @override - void visitVariableDeclaration(VariableDeclaration node) { + void defaultVariableDeclaration(VariableDeclaration node) { openNode(node, '${node.runtimeType}', { 'name': '${node.name ?? '--unnamed--'}', 'isFinal': '${node.isFinal}', diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart index 0bfd15822d9..8ac6b0336be 100644 --- a/pkg/kernel/lib/type_checker.dart +++ b/pkg/kernel/lib/type_checker.dart @@ -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( diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart index 307c3f36f37..8572cb936b4 100644 --- a/pkg/kernel/lib/verifier.dart +++ b/pkg/kernel/lib/verifier.dart @@ -270,7 +270,7 @@ class VerifyingVisitor extends RecursiveResultVisitor { // 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 { } @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; diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart index 6b6cf2647c1..2705e852772 100644 --- a/pkg/kernel/lib/visitor.dart +++ b/pkg/kernel/lib/visitor.dart @@ -502,36 +502,54 @@ abstract class StatementVisitor { 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 implements StatementVisitor { 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 implements StatementVisitor { R visitFunctionDeclaration(FunctionDeclaration node) => defaultStatement(node); @override - R visitVariableStatement(VariableStatement node) => - visitVariableDeclaration(node); + R visitLegacyVariableStatement(LegacyVariableStatement node) => + defaultStatement(node); +} + +abstract class VariableVisitor { + 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 implements VariableVisitor { + 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 { @@ -737,6 +777,7 @@ abstract class TreeVisitor ExpressionVisitor, PatternVisitor, StatementVisitor, + VariableVisitor, MemberVisitor, InitializerVisitor { const TreeVisitor(); @@ -832,6 +873,7 @@ abstract class TreeVisitorDefault with ExpressionVisitorDefaultMixin, StatementVisitorDefaultMixin, + VariableVisitorDefaultMixin, PatternVisitorDefaultMixin, InitializerVisitorDefaultMixin, MemberVisitorDefaultMixin, @@ -846,6 +888,9 @@ abstract class TreeVisitorDefault @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 ExpressionVisitor1, PatternVisitor1, StatementVisitor1, + VariableVisitor1, MemberVisitor1, InitializerVisitor1 { const TreeVisitor1(); @@ -960,6 +1006,7 @@ abstract class TreeVisitor1Default ExpressionVisitor1DefaultMixin, PatternVisitor1DefaultMixin, StatementVisitor1DefaultMixin, + VariableVisitor1DefaultMixin, InitializerVisitor1DefaultMixin, MemberVisitor1DefaultMixin implements TreeVisitor1 { @@ -972,6 +1019,9 @@ abstract class TreeVisitor1Default @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 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 implements StatementVisitor1 { @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 implements StatementVisitor1 { 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 { + 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 implements VariableVisitor1 { + 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 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 implements VariableVisitor { + /// 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 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); } } diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart index 8f86518afa6..02647f4b131 100644 --- a/pkg/kernel/test/verify_test.dart +++ b/pkg/kernel/test/verify_test.dart @@ -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.", diff --git a/pkg/vm/lib/modular/transformations/ffi/finalizable.dart b/pkg/vm/lib/modular/transformations/ffi/finalizable.dart index 882c173e300..88fd45dc3f8 100644 --- a/pkg/vm/lib/modular/transformations/ffi/finalizable.dart +++ b/pkg/vm/lib/modular/transformations/ffi/finalizable.dart @@ -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([resultVariable, ..._reachabilityFences(declarations)]), + Block([ + 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); } diff --git a/pkg/vm/lib/modular/transformations/ffi/native.dart b/pkg/vm/lib/modular/transformations/ffi/native.dart index 79a6f26e427..49c22d6be56 100644 --- a/pkg/vm/lib/modular/transformations/ffi/native.dart +++ b/pkg/vm/lib/modular/transformations/ffi/native.dart @@ -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 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 = []; final callArguments = []; 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([ ...temporariesForArguments, - result, + VariableStatement(result), for (final argument in fencedArguments) ExpressionStatement( StaticInvocation( diff --git a/pkg/vm/lib/modular/transformations/ffi/use_sites.dart b/pkg/vm/lib/modular/transformations/ffi/use_sites.dart index 20651228e19..42a1d09214d 100644 --- a/pkg/vm/lib/modular/transformations/ffi/use_sites.dart +++ b/pkg/vm/lib/modular/transformations/ffi/use_sites.dart @@ -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([ diff --git a/pkg/vm/lib/modular/transformations/for_in_lowering.dart b/pkg/vm/lib/modular/transformations/for_in_lowering.dart index 18f32dde866..8d67a25fef9 100644 --- a/pkg/vm/lib/modular/transformations/for_in_lowering.dart +++ b/pkg/vm/lib/modular/transformations/for_in_lowering.dart @@ -143,7 +143,11 @@ class ForInLowering { )..fileOffset = stmt.bodyOffset; valueVariable.initializer!.parent = valueVariable; - final whileBody = new Block([valueVariable, stmt.body]); + final whileBody = new Block([ + 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([ - 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; } } } diff --git a/pkg/vm/lib/modular/transformations/late_var_init_transformer.dart b/pkg/vm/lib/modular/transformations/late_var_init_transformer.dart index 7d788fd9fb8..bfb6a01aebe 100644 --- a/pkg/vm/lib/modular/transformations/late_var_init_transformer.dart +++ b/pkg/vm/lib/modular/transformations/late_var_init_transformer.dart @@ -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 _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, ), ); diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart index 1f8dcd70a4a..41845317172 100644 --- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart +++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart @@ -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 { @override TypeExpr? visitForStatement(ForStatement node) { - node.variables.forEach(visitVariableDeclaration); + node.variables.forEach((v) => defaultVariableDeclaration(v.variable)); final List joins = _insertJoinsForModifiedVariables(node, false); final trueState = _cloneVariableValues(_variableValues); final falseState = _cloneVariableValues(_variableValues); @@ -2808,15 +2808,22 @@ class SummaryCollector extends RecursiveResultVisitor { } @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 { @override TypeExpr? visitLocalInitializer(LocalInitializer node) { - visitVariableDeclaration(node.variable); + defaultVariableDeclaration(node.variable); return null; } diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart index f57bf6fe7b5..0424f71ad0a 100644 --- a/pkg/vm/lib/transformations/type_flow/transformer.dart +++ b/pkg/vm/lib/transformations/type_flow/transformer.dart @@ -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 diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect index 53f1c940c57..7014027f5ab 100644 --- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect +++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect @@ -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)) diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect index f15002efc11..eb3653813e3 100644 --- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect +++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect @@ -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)+]