From 6b693e00bc82faabe736fc713a139cf7cea3dd2f Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Wed, 27 May 2026 00:41:34 -0700 Subject: [PATCH] [kernel][Contexts] Add VariableDeclaration This adds a VariableDeclaration node which is used in ForStatement instead of VariableStatement. This is a step towards removing the initializer from Variable. Long term, VariableDeclaration will own the initializer expression for variables and function parameters will have a defaultValue property instead of using the initializer property for the default value. TEST=existing Change-Id: I4a663eeb6006a0f9f098fb2b3e3b502d2ae583b0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505681 Reviewed-by: Stephen Adams Reviewed-by: Martin Kustermann Reviewed-by: Chloe Stefantsova Reviewed-by: Nicholas Shahan --- .../shared_interop_transformer.dart | 12 +- pkg/cfg/lib/front_end/ast_to_ir.dart | 6 +- pkg/cfg/lib/front_end/computed_scopes.dart | 2 +- pkg/compiler/lib/src/inferrer/builder.dart | 11 +- pkg/compiler/lib/src/ir/scope_visitor.dart | 13 +- .../modular/late_lowering.dart | 10 +- .../modular/list_factory_specializer.dart | 9 +- pkg/compiler/lib/src/ssa/builder.dart | 9 +- pkg/dart2bytecode/lib/bytecode_generator.dart | 6 +- pkg/dart2wasm/lib/await_transformer.dart | 34 +- pkg/dart2wasm/lib/code_generator.dart | 24 +- .../lib/deferred_load/dependencies.dart | 2 +- .../lib/js/callback_specializer.dart | 2 +- pkg/dart2wasm/lib/state_machine.dart | 16 +- pkg/dart2wasm/lib/transformers.dart | 30 +- pkg/dev_compiler/lib/src/kernel/compiler.dart | 6 +- .../lib/src/kernel/compiler_new.dart | 6 +- .../api_prototype/lowering_predicates.dart | 2 +- .../src/fragment/constructor/encoding.dart | 20 +- .../lib/src/fragment/setter/declaration.dart | 6 +- .../lib/src/kernel/body_builder.dart | 141 ++--- pkg/front_end/lib/src/kernel/collections.dart | 57 +- .../lib/src/kernel/constant_evaluator.dart | 203 +++++--- .../lib/src/kernel/external_ast_helper.dart | 49 +- .../lib/src/kernel/internal_ast.dart | 110 ++-- .../lib/src/kernel/internal_ast_helper.dart | 61 ++- .../lib/src/kernel/late_lowering.dart | 4 +- .../src/type_inference/inference_results.dart | 62 +++ .../src/type_inference/inference_visitor.dart | 314 +++++------ .../inference_visitor_base.dart | 4 +- .../src/type_inference/matching_cache.dart | 57 +- .../test/dart_scope_calculator_test.dart | 4 +- ...internal_ast_text_representation_test.dart | 22 +- pkg/front_end/testcases/modular.status | 25 +- pkg/front_end/testcases/strong.status | 24 +- pkg/front_end/tool/ast_model.dart | 5 +- pkg/kernel/lib/binary/ast_from_binary.dart | 37 +- pkg/kernel/lib/binary/ast_to_binary.dart | 51 +- pkg/kernel/lib/clone.dart | 18 +- pkg/kernel/lib/src/ast/components.dart | 6 +- pkg/kernel/lib/src/ast/dummies.dart | 16 +- pkg/kernel/lib/src/ast/functions.dart | 4 +- pkg/kernel/lib/src/ast/patterns.dart | 2 +- pkg/kernel/lib/src/ast/statements.dart | 118 +---- pkg/kernel/lib/src/ast/variables.dart | 102 +++- pkg/kernel/lib/src/coverage.dart | 20 +- pkg/kernel/lib/src/equivalence.dart | 183 ++++--- pkg/kernel/lib/src/node_creator.dart | 38 +- pkg/kernel/lib/src/printer.dart | 26 + pkg/kernel/lib/text/ast_to_text.dart | 54 +- pkg/kernel/lib/type_checker.dart | 13 +- pkg/kernel/lib/verifier.dart | 23 - pkg/kernel/lib/visitor.dart | 82 +-- pkg/kernel/test/verify_test.dart | 486 ++++++++---------- .../transformations/ffi/finalizable.dart | 8 +- .../modular/transformations/ffi/native.dart | 8 +- .../transformations/ffi/use_sites.dart | 34 +- .../transformations/for_in_lowering.dart | 36 +- .../late_var_init_transformer.dart | 18 +- .../type_flow/summary_collector.dart | 8 +- 60 files changed, 1400 insertions(+), 1359 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 748b75b84b6..b1ee93d677b 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 @@ -372,7 +372,9 @@ class SharedInteropTransformer extends Transformer { isSynthesized: true, )..fileOffset = invocation.fileOffset; block.add( - VariableStatement(dartInstance)..fileOffset = invocation.fileOffset, + VariableStatement( + VariableDeclaration(dartInstance)..fileOffset = invocation.fileOffset, + )..fileOffset = invocation.fileOffset, ); var jsExporter = Variable( @@ -382,7 +384,9 @@ class SharedInteropTransformer extends Transformer { isSynthesized: true, )..fileOffset = invocation.fileOffset; block.add( - VariableStatement(jsExporter)..fileOffset = invocation.fileOffset, + VariableStatement( + VariableDeclaration(jsExporter)..fileOffset = invocation.fileOffset, + )..fileOffset = invocation.fileOffset, ); for (var MapEntry(key: exportName, value: exports) in exportMap.entries) { @@ -465,7 +469,9 @@ class SharedInteropTransformer extends Transformer { isSynthesized: true, )..fileOffset = invocation.fileOffset; block.add( - VariableStatement(getSetMap)..fileOffset = invocation.fileOffset, + VariableStatement( + VariableDeclaration(getSetMap)..fileOffset = invocation.fileOffset, + )..fileOffset = invocation.fileOffset, ); var (:getter, :setter) = _exportChecker.getGetterSetter(exports); if (getter != null) { diff --git a/pkg/cfg/lib/front_end/ast_to_ir.dart b/pkg/cfg/lib/front_end/ast_to_ir.dart index a232c8c71dd..8fea633cfbb 100644 --- a/pkg/cfg/lib/front_end/ast_to_ir.dart +++ b/pkg/cfg/lib/front_end/ast_to_ir.dart @@ -924,13 +924,13 @@ class AstToIr extends ast.RecursiveVisitor { } @override - void visitLegacyVariableStatement(ast.LegacyVariableStatement node) { + void visitVariableDeclaration(ast.VariableDeclaration node) { defaultVariable(node.variable); } @override - void visitVariableInitialization(ast.VariableInitialization node) { - defaultVariable(node.variable); + void visitVariableStatement(ast.VariableStatement node) { + visitVariableDeclaration(node.declaration); } @override diff --git a/pkg/cfg/lib/front_end/computed_scopes.dart b/pkg/cfg/lib/front_end/computed_scopes.dart index 68debcfb30b..941356c2145 100644 --- a/pkg/cfg/lib/front_end/computed_scopes.dart +++ b/pkg/cfg/lib/front_end/computed_scopes.dart @@ -304,7 +304,7 @@ class _ScopeBuilder extends ast.RecursiveVisitor { } @override - void visitLegacyVariableStatement(ast.LegacyVariableStatement node) { + void visitVariableStatement(ast.VariableStatement node) { node.visitChildren(this); } diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart index 315cb9c9ede..73d2ce6e533 100644 --- a/pkg/compiler/lib/src/inferrer/builder.dart +++ b/pkg/compiler/lib/src/inferrer/builder.dart @@ -936,12 +936,15 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault } @override - TypeInformation? visitLegacyVariableStatement( - ir.LegacyVariableStatement node, - ) { + TypeInformation? visitVariableDeclaration(ir.VariableDeclaration node) { return defaultVariable(node.variable); } + @override + TypeInformation? visitVariableStatement(ir.VariableStatement node) { + return visitVariableDeclaration(node.declaration); + } + @override TypeInformation? defaultVariable(ir.Variable node) { assert( @@ -2461,7 +2464,7 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault @override Null visitForStatement(ir.ForStatement node) { - for (ir.VariableStatement variable in node.variables) { + for (ir.VariableDeclaration variable in node.variables) { visit(variable); } return handleLoop(node, _localsMap.getJumpTargetForFor(node), () { diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart index 5489e92ebbd..3558bb8b1fc 100644 --- a/pkg/compiler/lib/src/ir/scope_visitor.dart +++ b/pkg/compiler/lib/src/ir/scope_visitor.dart @@ -318,12 +318,15 @@ class ScopeModelBuilder extends ir.VisitorDefault } @override - EvaluationComplexity visitLegacyVariableStatement( - ir.LegacyVariableStatement node, - ) { + EvaluationComplexity visitVariableDeclaration(ir.VariableDeclaration node) { return defaultVariable(node.variable); } + @override + EvaluationComplexity visitVariableStatement(ir.VariableStatement node) { + return visitVariableDeclaration(node.declaration); + } + @override EvaluationComplexity defaultVariable(ir.Variable node) { _handleVariableDeclaration(node.variable, SimpleVariableUse.localType); @@ -504,7 +507,7 @@ 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.VariableStatement variableDeclaration in node.variables) { + for (ir.VariableDeclaration variableDeclaration in node.variables) { if (!_capturedVariables.contains(variableDeclaration.variable)) { _mutatedVariables.remove(variableDeclaration.variable); } @@ -521,7 +524,7 @@ class ScopeModelBuilder extends ir.VisitorDefault }); // See if we have declared loop variables that need to be boxed. - for (ir.VariableStatement variableDeclaration in node.variables) { + for (ir.VariableDeclaration 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(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 12d292cc50a..e9fbaf61dc3 100644 --- a/pkg/compiler/lib/src/kernel/transformations/modular/late_lowering.dart +++ b/pkg/compiler/lib/src/kernel/transformations/modular/late_lowering.dart @@ -307,10 +307,6 @@ class LateLowering { if (!_shouldLowerVariable(variable)) return variable; - // A [VariableDeclaration] being used as a statement must be a direct child - // of a [VariableStatement]. - if (variable.parent is! VariableStatement) return variable; - return _variableCell(variable); } @@ -597,11 +593,11 @@ class LateLowering { VariableGet resultRead() => VariableGet(result)..fileOffset = fileOffset; return Block([ - VariableStatement(value), + VariableStatement(VariableDeclaration(value)), IfStatement( _callIsSentinel(valueRead(), fileOffset), Block([ - VariableStatement(result), + VariableStatement(VariableDeclaration(result)), ExpressionStatement( StaticInvocation( _coreTypes.lateInitializeOnceCheck, @@ -646,7 +642,7 @@ class LateLowering { )..fileOffset = fileOffset; VariableGet valueRead() => VariableGet(value)..fileOffset = fileOffset; return Block([ - VariableStatement(value), + VariableStatement(VariableDeclaration(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 73a8689ac64..4d4e925398b 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 - [VariableStatement(indexVariable)], + [VariableDeclaration(indexVariable)], // condition: _i < _length InstanceInvocation( InstanceAccessKind.Instance, @@ -171,8 +171,9 @@ class ListFactorySpecializer extends BaseSpecializer { return BlockExpression( Block([ - if (lengthVariable != null) VariableStatement(lengthVariable!), - VariableStatement(listVariable), + if (lengthVariable != null) + VariableStatement(VariableDeclaration(lengthVariable!)), + VariableStatement(VariableDeclaration(listVariable)), loop, ]), VariableGet(listVariable)..fileOffset = node.fileOffset, @@ -320,7 +321,7 @@ class ListGenerateLoopBodyInliner extends CloneVisitorNotMembers { Statement run() { Statement body = cloneInContext(function.body!); - return Block([VariableStatement(parameter), body]); + return Block([VariableStatement(VariableDeclaration(parameter)), body]); } @override diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart index 27b55938f7c..b306ee12e11 100644 --- a/pkg/compiler/lib/src/ssa/builder.dart +++ b/pkg/compiler/lib/src/ssa/builder.dart @@ -2560,7 +2560,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault void visitForStatement(ir.ForStatement node) { assert(_isReachable); void buildInitializer() { - for (ir.VariableStatement declaration in node.variables) { + for (ir.VariableDeclaration declaration in node.variables) { declaration.accept(this); } } @@ -4747,10 +4747,15 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault } @override - void visitLegacyVariableStatement(ir.LegacyVariableStatement node) { + void visitVariableDeclaration(ir.VariableDeclaration node) { defaultVariable(node.variable); } + @override + void visitVariableStatement(ir.VariableStatement node) { + visitVariableDeclaration(node.declaration); + } + @override void defaultVariable(ir.Variable node) { Local local = _localsMap.getLocalVariable(node); diff --git a/pkg/dart2bytecode/lib/bytecode_generator.dart b/pkg/dart2bytecode/lib/bytecode_generator.dart index 27a938241b9..f68e0762c84 100644 --- a/pkg/dart2bytecode/lib/bytecode_generator.dart +++ b/pkg/dart2bytecode/lib/bytecode_generator.dart @@ -4888,13 +4888,13 @@ class BytecodeGenerator extends RecursiveVisitor { } @override - void visitLegacyVariableStatement(LegacyVariableStatement node) { + void visitVariableDeclaration(VariableDeclaration node) { _handleVariableInitialization(node.variable); } @override - void visitVariableInitialization(VariableInitialization node) { - _handleVariableInitialization(node.variable); + void visitVariableStatement(VariableStatement node) { + visitVariableDeclaration(node.declaration); } void _handleVariableInitialization(Variable node) { diff --git a/pkg/dart2wasm/lib/await_transformer.dart b/pkg/dart2wasm/lib/await_transformer.dart index 9ef53edb150..34642d29a9f 100644 --- a/pkg/dart2wasm/lib/await_transformer.dart +++ b/pkg/dart2wasm/lib/await_transformer.dart @@ -92,7 +92,7 @@ class _AwaitTransformer extends Transformer { final List newStatements = [ for (final variable in transformer.expressionTransformer.variables) - VariableStatement(variable), + VariableStatement(VariableDeclaration(variable)), ...transformer.statements, ]; @@ -249,7 +249,7 @@ class _AwaitTransformer extends Transformer { List> initEffects = List>.generate(length, ( int i, ) { - VariableStatement decl = stmt.variables[i]; + VariableDeclaration decl = stmt.variables[i]; List statements = []; if (decl.variable.initializer != null) { decl.variable.initializer = expressionTransformer.rewrite( @@ -346,9 +346,9 @@ class _AwaitTransformer extends Transformer { List updates = []; List newBody = [body]; for (int i = 0; i < stmt.variables.length; ++i) { - VariableStatement decl = stmt.variables[i]; + VariableDeclaration decl = stmt.variables[i]; temps.add(Variable(null, type: decl.variable.type, isSynthesized: true)); - loopBody.add(decl); + loopBody.add(VariableStatement(decl)); if (decl.variable.initializer != null) { initializers.addAll(initEffects[i]); initializers.add( @@ -393,7 +393,7 @@ class _AwaitTransformer extends Transformer { labeled.body = WhileStatement(BoolLiteral(true), Block(loopBody)) ..parent = labeled; return Block([ - for (Variable temp in temps) VariableStatement(temp), + for (Variable temp in temps) VariableStatement(VariableDeclaration(temp)), labeled, ]); } @@ -545,23 +545,29 @@ class _AwaitTransformer extends Transformer { } return Block([ - VariableStatement(continuationVar), - VariableStatement(exceptionVar), - VariableStatement(stackTraceVar), + VariableStatement(VariableDeclaration(continuationVar)), + VariableStatement(VariableDeclaration(exceptionVar)), + VariableStatement(VariableDeclaration(stackTraceVar)), TryFinally(body, finalizer), ]); } @override - TreeNode visitLegacyVariableStatement(LegacyVariableStatement stmt) { - final initializer = stmt.variable.initializer; + TreeNode visitVariableDeclaration(VariableDeclaration node) { + final initializer = node.variable.initializer; if (initializer != null) { - stmt.variable.initializer = expressionTransformer.rewrite( + node.variable.initializer = expressionTransformer.rewrite( initializer, statements, - )..parent = stmt.variable; + )..parent = node.variable; } - return stmt; + return node; + } + + @override + TreeNode visitVariableStatement(VariableStatement node) { + visitVariableDeclaration(node.declaration); + return node; } @override @@ -1263,7 +1269,7 @@ class _ExpressionTransformer extends Transformer { // // // and return the body's value. - statements.add(VariableStatement(variable)); + statements.add(VariableStatement(VariableDeclaration(variable))); var index = nameIndex; seenAwait = false; variable.initializer = transform(variable.initializer!) diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart index d26a0f5af69..6fa8f357661 100644 --- a/pkg/dart2wasm/lib/code_generator.dart +++ b/pkg/dart2wasm/lib/code_generator.dart @@ -672,7 +672,19 @@ abstract class AstCodeGenerator } } - void translateVariableDeclaration(Variable node) { + void translateVariableDeclaration(VariableDeclaration node) { + final oldFileOffset = setSourceMapFileOffset(node.fileOffset); + try { + visitVariable(node.variable); + } catch (_) { + _printLocation(node); + rethrow; + } finally { + setSourceMapFileOffset(oldFileOffset); + } + } + + void translateVariable(Variable node) { final oldFileOffset = setSourceMapFileOffset(node.fileOffset); try { visitVariable(node); @@ -1277,8 +1289,8 @@ abstract class AstCodeGenerator @override void visitForStatement(ForStatement node) { allocateContext(node); - for (VariableStatement variable in node.variables) { - translateStatement(variable); + for (VariableDeclaration variable in node.variables) { + translateVariableDeclaration(variable); } w.Label block = b.block(); w.Label loop = b.loop(); @@ -1301,7 +1313,7 @@ abstract class AstCodeGenerator w.Local newContext = context.currentLocal; // Copy the values of captured loop variables to the new context. - for (VariableStatement variableDeclaration in node.variables) { + for (VariableDeclaration variableDeclaration in node.variables) { Capture? capture = closures.captures[variableDeclaration.variable]; if (capture != null) { assert(capture.context == context); @@ -1570,7 +1582,7 @@ abstract class AstCodeGenerator @override w.ValueType visitLet(Let node, w.ValueType expectedType) { - translateVariableDeclaration(node.variable); + translateVariable(node.variable); return translateExpression(node.body, expectedType); } @@ -4451,7 +4463,7 @@ class ConstructorInitializerCodeGenerator extends ConstructorCodeGeneratorBase { @override void visitLocalInitializer(LocalInitializer node) { - translateVariableDeclaration(node.variable); + translateVariable(node.variable); } @override diff --git a/pkg/dart2wasm/lib/deferred_load/dependencies.dart b/pkg/dart2wasm/lib/deferred_load/dependencies.dart index 1352560c197..931491c5890 100644 --- a/pkg/dart2wasm/lib/deferred_load/dependencies.dart +++ b/pkg/dart2wasm/lib/deferred_load/dependencies.dart @@ -738,7 +738,7 @@ class _ReferenceDependenciesCollector extends RecursiveVisitor { @override void visitYieldStatement(YieldStatement node) => node.visitChildren(this); @override - void visitLegacyVariableStatement(LegacyVariableStatement node) => + void visitVariableStatement(VariableStatement node) => node.visitChildren(this); @override diff --git a/pkg/dart2wasm/lib/js/callback_specializer.dart b/pkg/dart2wasm/lib/js/callback_specializer.dart index 63d17e91d6d..fac118527c5 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(VariableStatement(argumentsLength)); + body.add(VariableStatement(VariableDeclaration(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 8f55ba29ee7..cfe974d8320 100644 --- a/pkg/dart2wasm/lib/state_machine.dart +++ b/pkg/dart2wasm/lib/state_machine.dart @@ -495,11 +495,17 @@ class Finalizer extends _ExceptionHandler { Finalizer._(this.codeGen, TryFinally node, this.parentFinalizer, super.target) : _continuationVar = - ((node.parent as Block).statements[0] as VariableStatement).variable, + ((node.parent as Block).statements[0] as VariableStatement) + .declaration + .variable, _exceptionVar = - ((node.parent as Block).statements[1] as VariableStatement).variable, + ((node.parent as Block).statements[1] as VariableStatement) + .declaration + .variable, _stackTraceVar = - ((node.parent as Block).statements[2] as VariableStatement).variable; + ((node.parent as Block).statements[2] as VariableStatement) + .declaration + .variable; @override bool get canHandleJSExceptions => true; @@ -869,8 +875,8 @@ abstract class StateMachineCodeGenerator extends AstCodeGenerator { StateTarget after = afterTargets[node]!; allocateContext(node); - for (VariableStatement variable in node.variables) { - translateStatement(variable); + for (VariableDeclaration variable in node.variables) { + translateVariableDeclaration(variable); } emitTargetLabel(inner); _jumpToTarget(after, condition: node.condition, negated: true); diff --git a/pkg/dart2wasm/lib/transformers.dart b/pkg/dart2wasm/lib/transformers.dart index 85e19bd7a91..0fefce4d896 100644 --- a/pkg/dart2wasm/lib/transformers.dart +++ b/pkg/dart2wasm/lib/transformers.dart @@ -440,8 +440,10 @@ class _WasmTransformer extends Transformer { resultType: elementType, )..fileOffset = stmt.bodyOffset); - Block body = Block([VariableStatement(variable), stmt.body]) - ..fileOffset = stmt.fileOffset; + Block body = Block([ + VariableStatement(VariableDeclaration(variable)), + stmt.body, + ])..fileOffset = stmt.fileOffset; Statement forStatement = ForStatement( const [], @@ -480,8 +482,8 @@ class _WasmTransformer extends Transformer { } return Block([ - VariableStatement(iterator), - if (isAsync) VariableStatement(jumpSentinel), + VariableStatement(VariableDeclaration(iterator)), + if (isAsync) VariableStatement(VariableDeclaration(jumpSentinel)), forStatement, ]).accept(this); } @@ -884,17 +886,17 @@ class _WasmTransformer extends Transformer { return FunctionNode( Block([ - VariableStatement(pausedVar), - VariableStatement(cancelCompleterVar), - VariableStatement(isDoneVar), - VariableStatement(onCancelCallbackVar), - VariableStatement(onResumeCallbackVar), + VariableStatement(VariableDeclaration(pausedVar)), + VariableStatement(VariableDeclaration(cancelCompleterVar)), + VariableStatement(VariableDeclaration(isDoneVar)), + VariableStatement(VariableDeclaration(onCancelCallbackVar)), + VariableStatement(VariableDeclaration(onResumeCallbackVar)), // var controller = StreamController(sync: true, onCancel: onCancelCallback, onResume: onResumeCallback); - VariableStatement(controllerVar), + VariableStatement(VariableDeclaration(controllerVar)), // var #body = ...; - VariableStatement(bodyVar), + VariableStatement(VariableDeclaration(bodyVar)), // controller.onListen = ...; ExpressionStatement(setControllerOnListen), @@ -1347,7 +1349,7 @@ class PushPopWasmArrayTransformer { } final List arrayGrowStatements = [ - VariableStatement(newArrayVariable), + VariableStatement(VariableDeclaration(newArrayVariable)), ExpressionStatement(newArrayCopy), arrayFieldUpdate, ]; @@ -1476,7 +1478,9 @@ class PushPopWasmArrayTransformer { isFinal: true, type: elementType, ); - blockStatements.add(VariableStatement(arrayGetVariable)); + blockStatements.add( + VariableStatement(VariableDeclaration(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 ddf15a58838..af5be6fc0af 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -4857,10 +4857,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor @override js_ast.Statement visitForStatement(ForStatement node) { return _translateLoop(node, () { - js_ast.VariableInitialization emitForInitializer(VariableStatement s) => + js_ast.VariableInitialization emitForInitializer(VariableDeclaration d) => js_ast.VariableInitialization( - _emitVariableDef(s.variable), - _visitInitializer(s.variable.initializer, s.variable.annotations), + _emitVariableDef(d.variable), + _visitInitializer(d.variable.initializer, d.variable.annotations), ); if (node.variables.any(containsFunctionExpression)) { diff --git a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart index 100911d774b..f6abb56c196 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart @@ -5471,10 +5471,10 @@ class LibraryCompiler extends ComputeOnceConstantVisitor @override js_ast.Statement visitForStatement(ForStatement node) { return _translateLoop(node, () { - js_ast.VariableInitialization emitForInitializer(VariableStatement s) => + js_ast.VariableInitialization emitForInitializer(VariableDeclaration d) => js_ast.VariableInitialization( - _emitVariableDef(s.variable), - _visitInitializer(s.variable.initializer, s.variable.annotations), + _emitVariableDef(d.variable), + _visitInitializer(d.variable.initializer, d.variable.annotations), ); if (node.variables.any(containsFunctionExpression)) { 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 aa162ccf814..f54d09a5a98 100644 --- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart +++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart @@ -355,7 +355,7 @@ Expression? getLateFieldInitializer(Member node) { // in case `` is the initializer. VariableStatement variableStatement = block.statements.first as VariableStatement; - return variableStatement.variable.initializer; + return variableStatement.declaration.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 194b3bb5fa9..9bb5098999e 100644 --- a/pkg/front_end/lib/src/fragment/constructor/encoding.dart +++ b/pkg/front_end/lib/src/fragment/constructor/encoding.dart @@ -773,7 +773,7 @@ mixin _ExtensionTypeConstructorEncodingMixin if (!_isExternal) { Variable thisVariable = this.thisVariable!; VariableStatement thisVariableStatement = extern.createVariableStatement( - thisVariable, + extern.createVariableDeclaration(thisVariable), ); List statements = [thisVariableStatement]; _ExtensionTypeInitializerToStatementConverter visitor = @@ -863,7 +863,7 @@ class _ExtensionTypeInitializerToStatementConverter statements.add( extern.createExpressionStatement( extern.createVariableSet( - thisVariableStatement.variable, + thisVariableStatement.declaration.variable, extern.createStaticInvocation( node.target, node.arguments.toArguments( @@ -881,8 +881,9 @@ class _ExtensionTypeInitializerToStatementConverter ); return; } else if (node is ExtensionTypeRepresentationFieldInitializer) { - thisVariableStatement.variable - ..initializer = (node.value..parent = thisVariableStatement.variable) + thisVariableStatement.declaration.variable + ..initializer = (node.value + ..parent = thisVariableStatement.declaration.variable) ..fileOffset = node.fileOffset; thisVariableStatement.fileOffset = node.fileOffset; return; @@ -896,8 +897,9 @@ class _ExtensionTypeInitializerToStatementConverter @override // Coverage-ignore(suite): Not run. void visitFieldInitializer(FieldInitializer node) { - thisVariableStatement.variable - ..initializer = (node.value..parent = thisVariableStatement.variable) + thisVariableStatement.declaration.variable + ..initializer = (node.value + ..parent = thisVariableStatement.declaration.variable) ..fileOffset = node.fileOffset; thisVariableStatement.fileOffset = node.fileOffset; } @@ -916,7 +918,11 @@ class _ExtensionTypeInitializerToStatementConverter @override void visitLocalInitializer(LocalInitializer node) { - statements.add(extern.createVariableStatement(node.variable)); + statements.add( + extern.createVariableStatement( + extern.createVariableDeclaration(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 e50d055066b..fd110ad5498 100644 --- a/pkg/front_end/lib/src/fragment/setter/declaration.dart +++ b/pkg/front_end/lib/src/fragment/setter/declaration.dart @@ -331,7 +331,11 @@ class RegularSetterDeclaration // Add them as local variable to put them in scope of the body. List statements = []; for (FormalParameterBuilder parameter in declaredFormals) { - statements.add(extern.createVariableStatement(parameter.variable)); + statements.add( + extern.createVariableStatement( + extern.createVariableDeclaration(parameter.variable), + ), + ); } statements.add(body); body = extern.createBlock(statements, fileOffset: fileOffset); diff --git a/pkg/front_end/lib/src/kernel/body_builder.dart b/pkg/front_end/lib/src/kernel/body_builder.dart index bc81971b2a4..e5c4a6987c7 100644 --- a/pkg/front_end/lib/src/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/kernel/body_builder.dart @@ -1990,10 +1990,7 @@ class BodyBuilderImpl extends StackListenerImpl } List jointVariables = [ for (Variable leftVariable in left.declaredVariables) - intern.createVariableDeclaration( - leftVariable.fileOffset, - leftVariable.name!, - ), + intern.createVariable(leftVariable.fileOffset, leftVariable.name!), ]; for (Variable variable in jointVariables) { declareVariable(variable, _localScope); @@ -3334,14 +3331,14 @@ class BodyBuilderImpl extends StackListenerImpl } pushNewLocalVariable(initializer, equalsToken: assignmentOperator); if (isLate) { - VariableStatement node = peek() as VariableStatement; + VariableDeclaration node = peek() as VariableDeclaration; // 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.variable as InternalVariable).astVariable, + (node.variable as InternalVariable).astVariable, assignedVariablesInfo!, ); } @@ -3393,7 +3390,7 @@ class BodyBuilderImpl extends StackListenerImpl name = createWildcardVariableName(wildcardVariableIndex); wildcardVariableIndex++; } - Statement variableInitialization; + VariableDeclaration variableDeclaration; InternalVariable internalVariable; if (isClosureContextLoweringEnabled) { internalVariable = new InternalLocalVariable( @@ -3404,6 +3401,7 @@ class BodyBuilderImpl extends StackListenerImpl isConst: isConst, isLate: isLate, isWildcard: isWildcard, + hasDeclaredInitializer: initializer != null, fileOffset: identifier.nameOffset, initializer: initializer, ), @@ -3411,14 +3409,12 @@ class BodyBuilderImpl extends StackListenerImpl isImplicitlyTyped: currentLocalVariableType == null, fileOffset: identifier.nameOffset, ); - variableInitialization = intern.createVariableInitialization( - variable: internalVariable.asVariableDeclaration, - - hasDeclaredInitializer: initializer != null, + variableDeclaration = intern.createVariableDeclaration( + internalVariable.asVariableDeclaration, fileOffset: offsetForToken(equalsToken), ); } else { - variableInitialization = intern.createVariableStatement( + variableDeclaration = intern.createVariableDeclaration( internalVariable = new VariableDeclarationImpl( name, forSyntheticToken: identifier.token.isSynthetic, @@ -3434,10 +3430,11 @@ class BodyBuilderImpl extends StackListenerImpl fileOffset: identifier.nameOffset, fileEqualsOffset: offsetForToken(equalsToken), ), + fileOffset: offsetForToken(equalsToken), ); } assignedVariables.declare(internalVariable.astVariable); - push(variableInitialization); + push(variableDeclaration); } /// Sets up the local scope for a field initializer. @@ -3522,17 +3519,17 @@ class BodyBuilderImpl extends StackListenerImpl push(node); return; } - VariableStatement variableInitialization = node as VariableStatement; - variableInitialization.variable.fileOffset = - variableInitialization.fileOffset = nameToken.charOffset; - push(variableInitialization); + VariableDeclaration declaration = node as VariableDeclaration; + declaration.variable.fileOffset = declaration.fileOffset = + nameToken.charOffset; + push(declaration); // 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.variable.isWildcard)) { - declareVariable(variableInitialization.variable, _localScope); + declaration.variable.isWildcard)) { + declareVariable(declaration.variable, _localScope); } } @@ -3579,20 +3576,22 @@ class BodyBuilderImpl extends StackListenerImpl push(node); return; } - VariableStatement variableInitialization = node as VariableStatement; + VariableDeclaration declaration = node as VariableDeclaration; if (annotations != null) { for (int i = 0; i < annotations.length; i++) { - variableInitialization.variable.addAnnotation(annotations[i]); + declaration.variable.addAnnotation(annotations[i]); } - _registerSingleTargetAnnotations(variableInitialization.variable); + _registerSingleTargetAnnotations(declaration.variable); } - push(variableInitialization); + // TODO(johnniwinther): Should [VariableStatement] use offset from + // [endToken]? + push(intern.createVariableStatement(declaration)); } else { - List? variables = - const FixedNullableList().popNonNullable( + List? variables = + const FixedNullableList().popNonNullable( stack, count, - dummyVariableStatement, + dummyVariableDeclaration, ); constantContext = pop() as ConstantContext; currentLocalVariableType = pop(NullValues.Type) as DartType?; @@ -3603,7 +3602,7 @@ class BodyBuilderImpl extends StackListenerImpl return; } if (annotations != null) { - VariableStatement first = variables.first; + VariableDeclaration first = variables.first; for (int i = 0; i < annotations.length; i++) { first.variable.addAnnotation(annotations[i]); } @@ -3714,7 +3713,7 @@ class BodyBuilderImpl extends StackListenerImpl } } - List? _buildForLoopVariableDeclarations( + List? _buildForLoopVariableDeclarations( variableOrExpression, ) { // TODO(ahe): This can be simplified now that we have the events @@ -3723,6 +3722,16 @@ class BodyBuilderImpl extends StackListenerImpl variableOrExpression = variableOrExpression.buildForEffect(); } if (variableOrExpression is VariableStatement) { + // TODO(johnniwinther): Avoid parsing variable declarations initializers + // in for statements as statements. + VariableDeclaration variableDeclaration = + variableOrExpression.declaration; + // Late for loop variables are not supported. An error has already been + // reported by the parser. + variableDeclaration.variable.isLate = false; + return [variableDeclaration]; + } else if (variableOrExpression is VariableDeclaration) { + // Coverage-ignore-block(suite): Not run. // Late for loop variables are not supported. An error has already been // reported by the parser. variableOrExpression.variable.isLate = false; @@ -3731,20 +3740,20 @@ class BodyBuilderImpl extends StackListenerImpl Variable variable = new VariableDeclarationImpl.forEffect( variableOrExpression, ); - return [intern.createVariableStatement(variable)]; + return [intern.createVariableDeclaration(variable)]; } else if (variableOrExpression is ExpressionStatement) { // Coverage-ignore-block(suite): Not run. Variable variable = new VariableDeclarationImpl.forEffect( variableOrExpression.expression, ); - return [intern.createVariableStatement(variable)]; + return [intern.createVariableDeclaration(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)!); } @@ -3757,6 +3766,8 @@ class BodyBuilderImpl extends StackListenerImpl } else if (variableOrExpression == null) { return []; } + // Coverage-ignore(suite): Not run. + assert(false, "Unexpected for statement initializer $variableOrExpression"); return null; } @@ -3787,7 +3798,7 @@ class BodyBuilderImpl extends StackListenerImpl // have erroneously set the `isStaticLate` flag, so un-set it. Object? declaration = peek(); if (declaration case VariableStatement( - :VariableDeclarationImpl variable, + declaration: VariableDeclaration(:VariableDeclarationImpl variable), )) { variable.isStaticLate = false; } @@ -3849,7 +3860,7 @@ class BodyBuilderImpl extends StackListenerImpl ); intermediateVariables.add(intermediateVariable); - Variable internalVariable = intern.createVariableDeclaration( + Variable internalVariable = intern.createVariable( variable.fileOffset, variable.name!, initializer: intern.createVariableGet( @@ -3961,13 +3972,15 @@ class BodyBuilderImpl extends StackListenerImpl .popNode(); Object? variableOrExpression = pop(); - List? variables; - List? intermediateVariables; + List? variables; + List? intermediateVariables; if (variableOrExpression is PatternVariableDeclaration) { variables = (pop() as List) - .map(intern.createVariableStatement) + .map(intern.createVariableDeclaration) .toList(); // Internal variables. - intermediateVariables = pop() as List; + intermediateVariables = (pop() as List) + .map(intern.createVariableDeclaration) + .toList(); } else { variables = _buildForLoopVariableDeclarations(variableOrExpression)!; } @@ -4082,13 +4095,15 @@ class BodyBuilderImpl extends StackListenerImpl .deferNode(); Object? variableOrExpression = pop(); - List? variables; - List? intermediateVariables; + List? variables; + List? intermediateVariables; if (variableOrExpression is PatternVariableDeclaration) { variables = (pop() as List) - .map(intern.createVariableStatement) + .map(intern.createVariableDeclaration) .toList(); // Internal variables. - intermediateVariables = pop() as List; + intermediateVariables = (pop() as List) + .map(intern.createVariableDeclaration) + .toList(); } else { variables = _buildForLoopVariableDeclarations(variableOrExpression); } @@ -4132,7 +4147,8 @@ class BodyBuilderImpl extends StackListenerImpl fileEndOffset: result.fileOffset, [ variableOrExpression, - for (Variable intermediateVariable in intermediateVariables!) + for (VariableDeclaration intermediateVariable + in intermediateVariables!) intern.createVariableStatement(intermediateVariable), result, ], @@ -8044,7 +8060,7 @@ class BodyBuilderImpl extends StackListenerImpl // `anonymous#this` because no user-written variable can have that name, // and we never have access to more than one of these variables. It does // not disrupt other backends that this name exists. - variable = intern.createVariableDeclaration( + variable = intern.createVariable( offsetForToken(punctuation), "anonymous#this", initializer: receiver, @@ -8361,32 +8377,35 @@ class BodyBuilderImpl extends StackListenerImpl required Token inToken, required Object? lvalue, }) { - if (lvalue is VariableInitialization) { + if (lvalue is VariableStatement) { + // TODO(johnniwinther): Avoid parsing variable declarations in + // for-in statements as statements. + VariableDeclaration declaration = lvalue.declaration; // Variable initializers are not supported. An error has already been // reported by the parser. - lvalue.variable.initializer = null; - lvalue.hasDeclaredInitializer = false; + declaration.variable.initializer = null; + declaration.variable.hasDeclaredInitializer = false; // Late for-in variables are not supported. An error has already been // reported by the parser. - lvalue.variable.isLate = false; + declaration.variable.isLate = false; InvalidExpression? error; - if (lvalue.variable.isConst) { - // Coverage-ignore-block(suite): Not run. + if (declaration.variable.isConst) { error = buildProblem( message: diag.forInLoopWithConstVariable, fileUri: uri, - fileOffset: lvalue.fileOffset, - length: lvalue.variable.cosmeticName!.length, + fileOffset: declaration.fileOffset, + length: declaration.variable.cosmeticName!.length, ); // As a recovery step, remove the const flag, to not confuse the // constant evaluator further in the pipeline. - lvalue.variable.isConst = false; + declaration.variable.isConst = false; } - return new VariableInitializationForInElement( - variableInitialization: lvalue, + return new SingleVariableDeclarationForInElement( + variableDeclaration: declaration, error: error, ); - } else if (lvalue is LegacyVariableStatement) { + } else if (lvalue is VariableDeclaration) { + // Coverage-ignore-block(suite): Not run. // Variable initializers are not supported. An error has already been // reported by the parser. lvalue.variable.initializer = null; @@ -8407,7 +8426,7 @@ class BodyBuilderImpl extends StackListenerImpl lvalue.variable.isConst = false; } return new SingleVariableDeclarationForInElement( - variableStatement: lvalue, + variableDeclaration: lvalue, error: error, ); } else if (lvalue is Generator) { @@ -8942,10 +8961,8 @@ class BodyBuilderImpl extends StackListenerImpl if (jointPatternVariables == null) { jointPatternVariables = [ for (Variable variable in patternGuard.pattern.declaredVariables) - intern.createVariableDeclaration( - variable.fileOffset, - variable.name!, - )..isFinal = variable.isFinal, + intern.createVariable(variable.fileOffset, variable.name!) + ..isFinal = variable.isFinal, ]; if (i != 0) { // The previous heads were non-pattern ones, so no variables can @@ -8976,7 +8993,7 @@ class BodyBuilderImpl extends StackListenerImpl } if (patternVariablesByName.isNotEmpty) { for (Variable variable in patternVariablesByName.values) { - Variable jointVariable = intern.createVariableDeclaration( + Variable jointVariable = intern.createVariable( variable.fileOffset, variable.name!, )..isFinal = variable.isFinal; @@ -11061,7 +11078,7 @@ class BodyBuilderImpl extends StackListenerImpl declaredVariables: const [], ); } else { - Variable declaredVariable = intern.createVariableDeclaration( + Variable declaredVariable = intern.createVariable( variable.charOffset, variable.lexeme, type: patternType, diff --git a/pkg/front_end/lib/src/kernel/collections.dart b/pkg/front_end/lib/src/kernel/collections.dart index 92a71134003..abb6e5b0c89 100644 --- a/pkg/front_end/lib/src/kernel/collections.dart +++ b/pkg/front_end/lib/src/kernel/collections.dart @@ -222,10 +222,7 @@ class ForElement extends ControlFlowElement implements ForElementBase { // May be empty, but not null. @override - final List variableInitializations; - - @override - List get variables => variableInitializations; + final List variables; @override Expression? condition; // May be null. @@ -236,13 +233,8 @@ class ForElement extends ControlFlowElement @override Expression body; - ForElement( - this.variableInitializations, - this.condition, - this.updates, - this.body, - ) { - setParents(variableInitializations, this); + ForElement(this.variables, this.condition, this.updates, this.body) { + setParents(variables, this); condition?.parent = this; setParents(updates, this); body.parent = this; @@ -278,12 +270,12 @@ class ForElement extends ControlFlowElement // Coverage-ignore(suite): Not run. void toTextInternal(AstPrinter printer) { printer.write('for ('); - for (int index = 0; index < variableInitializations.length; index++) { + for (int index = 0; index < variables.length; index++) { if (index > 0) { printer.write(', '); } - printer.writeVariableInitialization( - variableInitializations[index].variable, + printer.writeVariableDeclaration( + variables[index], includeModifiersAndType: index == 0, ); } @@ -462,9 +454,7 @@ class IfCaseElement extends ControlFlowElementImpl } abstract interface class ForElementBase implements AuxiliaryExpression { - List get variableInitializations; - - List get variables; + List get variables; abstract Expression? condition; @@ -477,14 +467,11 @@ class PatternForElement extends ControlFlowElementImpl with ControlFlowElementMixin implements ForElementBase { PatternVariableDeclaration patternVariableDeclaration; - List intermediateVariables; + List intermediateVariables; // May be empty, but not null. @override - final List variableInitializations; - - @override - List get variables => variableInitializations; + final List variables; @override Expression? condition; // May be null. @@ -498,11 +485,11 @@ class PatternForElement extends ControlFlowElementImpl PatternForElement({ required this.patternVariableDeclaration, required this.intermediateVariables, - required List variables, + required this.variables, required this.condition, required this.updates, required this.body, - }) : variableInitializations = variables; + }); @override ExpressionInferenceResult acceptInference( @@ -517,12 +504,12 @@ class PatternForElement extends ControlFlowElementImpl void toTextInternal(AstPrinter printer) { patternVariableDeclaration.toTextInternal(printer); printer.write('for ('); - for (int index = 0; index < variableInitializations.length; index++) { + for (int index = 0; index < variables.length; index++) { if (index > 0) { printer.write(', '); } - printer.writeVariableInitialization( - variableInitializations[index].variable, + printer.writeVariableDeclaration( + variables[index], includeModifiersAndType: index == 0, ); } @@ -689,7 +676,7 @@ class IfMapEntry extends TreeNode } abstract interface class ForMapEntryBase implements TreeNode, MapLiteralEntry { - List get variables; + List get variables; abstract Expression? condition; @@ -704,7 +691,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. @@ -735,8 +722,8 @@ class ForMapEntry extends TreeNode if (index > 0) { printer.write(', '); } - printer.writeVariableInitialization( - variables[index].variable, + printer.writeVariableDeclaration( + variables[index], includeModifiersAndType: index == 0, ); } @@ -755,10 +742,10 @@ class PatternForMapEntry extends TreeNode with InternalTreeNode, ControlFlowMapEntryMixin implements ForMapEntryBase, ControlFlowMapEntry { PatternVariableDeclaration patternVariableDeclaration; - List intermediateVariables; + List intermediateVariables; @override - final List variables; + final List variables; @override Expression? condition; @@ -787,8 +774,8 @@ class PatternForMapEntry extends TreeNode if (index > 0) { printer.write(', '); } - printer.writeVariableInitialization( - variables[index].variable, + printer.writeVariableDeclaration( + variables[index], 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 b3a56161b1c..8c5b2a0931d 100644 --- a/pkg/front_end/lib/src/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/kernel/constant_evaluator.dart @@ -447,20 +447,36 @@ class ConstantsTransformer extends RemovingTransformer { } @override - TreeNode visitLegacyVariableStatement( - LegacyVariableStatement node, + TreeNode visitVariableStatement( + VariableStatement node, TreeNode? removalSentinel, ) { if (removalSentinel != null) { - Variable? variable = transformOrRemoveVariableDeclaration(node.variable); - if (variable == null) { + VariableDeclaration? declaration = transformOrRemoveVariableDeclaration( + node.declaration, + ); + if (declaration == null) { return removalSentinel; } - node.variable = variable..parent = node; + node.declaration = declaration..parent = node; return node; } else { // Coverage-ignore-block(suite): Not run. - node.variable = transform(node.variable)..parent = node; + node.declaration = transform(node.declaration)..parent = node; + return node; + } + } + + @override + TreeNode visitVariableDeclaration( + VariableDeclaration node, + TreeNode? removalSentinel, + ) { + Variable? variable = transformOrRemoveVariable(node.variable); + if (variable == null) { + // Remove variable, if possible. + return removalSentinel ?? node; + } else { return node; } } @@ -1002,23 +1018,24 @@ class ConstantsTransformer extends RemovingTransformer { fileOffset: node.fileOffset, ); } else { - // matchResultVariable: int RVAR = -1; - Variable matchResultVariable = extern.createInitializedVariable( - extern.createIntLiteral( - typeEnvironment.coreTypes, - -1, - fileOffset: node.fileOffset, - ), - typeEnvironment.coreTypes.intNonNullableRawType, - fileOffset: node.fileOffset, - ); + // matchResultVariableDeclaration: int RVAR = -1; + VariableDeclaration matchResultVariableDeclaration = extern + .createInitializedVariableDeclaration( + expression: extern.createIntLiteral( + typeEnvironment.coreTypes, + -1, + fileOffset: node.fileOffset, + ), + type: typeEnvironment.coreTypes.intNonNullableRawType, + fileOffset: node.fileOffset, + ); LabeledStatement innerLabeledStatement = extern.createLabeledStatement( dummyStatement, fileOffset: node.fileOffset, ); _PatternSwitchStatementInfo info = new _PatternSwitchStatementInfo( - matchResultVariable, + matchResultVariableDeclaration.variable, innerLabeledStatement, switchCaseIndex, ); @@ -1044,7 +1061,7 @@ class ConstantsTransformer extends RemovingTransformer { List replacementCases = []; - List declaredVariableHelpers = []; + List declaredVariableHelpers = []; List cases = []; @@ -1090,10 +1107,10 @@ class ConstantsTransformer extends RemovingTransformer { // TODO(cstefantsova): Make sure an error is reported if the variables // declared in the heads aren't compatible to each other. - Map caseDeclaredVariableHelpersByName = { + Map caseDeclaredVariableHelpersByName = { for (Variable variable in switchCase.jointVariables) - variable.name!: extern.createUninitializedVariable( - const DynamicType(), + variable.name!: extern.createUninitializedVariableDeclaration( + type: const DynamicType(), // Avoid step debugging on the declaration of intermediate // variables. // TODO(johnniwinther): Find a more systematic way of omitting @@ -1122,9 +1139,11 @@ 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. - for (Variable declaredVariable in pattern.declaredVariables) { + for (Variable variable in pattern.declaredVariables) { replacementStatements.add( - extern.createVariableStatement(declaredVariable), + extern.createVariableStatement( + extern.createVariableDeclaration(variable), + ), ); } @@ -1156,7 +1175,7 @@ class ConstantsTransformer extends RemovingTransformer { for (Variable declaredVariable in pattern.declaredVariables) { String variableName = declaredVariable.name!; - Variable? variableHelper = + VariableDeclaration? variableHelper = caseDeclaredVariableHelpersByName[variableName]; if (variableHelper != null) { // headCondition: `headCondition` && @@ -1165,7 +1184,7 @@ class ConstantsTransformer extends RemovingTransformer { headCondition, extern.createLetEffect( effect: extern.createVariableSet( - variableHelper, + variableHelper.variable, extern.createVariableGet(declaredVariable), fileOffset: node.fileOffset, ), @@ -1223,7 +1242,7 @@ class ConstantsTransformer extends RemovingTransformer { // `declaredVariableHelper`{`declaredVariable.type`} // ==> `jointVariable` = HVAR{`declaredVariable.type`} jointVariable.initializer = extern.createVariableGet( - caseDeclaredVariableHelpersByName[jointVariable.name!]!, + caseDeclaredVariableHelpersByName[jointVariable.name!]!.variable, promotedType: jointVariable.type, )..parent = jointVariable; } @@ -1236,7 +1255,7 @@ class ConstantsTransformer extends RemovingTransformer { // ==> RVAR = `caseIndex`; Statement setMatchResult = extern.createExpressionStatement( extern.createVariableSet( - matchResultVariable, + matchResultVariableDeclaration.variable, extern.createIntLiteral( typeEnvironment.coreTypes, continueTargetIndex, @@ -1265,7 +1284,9 @@ class ConstantsTransformer extends RemovingTransformer { [node.fileOffset], extern.createBlock([ for (Variable jointVariable in switchCase.jointVariables) - extern.createVariableStatement(jointVariable), + extern.createVariableStatement( + extern.createVariableDeclaration(jointVariable), + ), if (body is! Block || body.statements.isNotEmpty) body, ], fileOffset: node.fileOffset), isDefault: switchCase.isDefault, @@ -1288,7 +1309,9 @@ class ConstantsTransformer extends RemovingTransformer { } else { caseBlock = extern.createBlock([ for (Variable jointVariable in switchCase.jointVariables) - extern.createVariableStatement(jointVariable), + extern.createVariableStatement( + extern.createVariableDeclaration(jointVariable), + ), if (body is! Block || body.statements.isNotEmpty) body, ], fileOffset: switchCase.fileOffset); } @@ -1322,7 +1345,9 @@ class ConstantsTransformer extends RemovingTransformer { cases.add( extern.createBlock([ for (Variable caseVariable in caseVariables) - extern.createVariableStatement(caseVariable), + extern.createVariableStatement( + extern.createVariableDeclaration(caseVariable), + ), caseBlock, if (breakStatement != null) // Coverage-ignore(suite): Not run. @@ -1374,15 +1399,16 @@ class ConstantsTransformer extends RemovingTransformer { ); innerLabeledStatement.body = casesBlock..parent = innerLabeledStatement; replacementStatements = [ - extern.createVariableStatement(matchResultVariable), + extern.createVariableStatement(matchResultVariableDeclaration), ...replacementStatements, - for (Variable declaration in matchingCache.declarations) + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), - for (Variable declaredVariableHelper in declaredVariableHelpers) + for (VariableDeclaration declaredVariableHelper + in declaredVariableHelpers) extern.createVariableStatement(declaredVariableHelper), innerLabeledStatement, extern.createSwitchStatement( - extern.createVariableGet(matchResultVariable), + extern.createVariableGet(matchResultVariableDeclaration.variable), replacementCases, isExplicitlyExhaustive: false, expressionType: scrutineeType, @@ -1392,9 +1418,10 @@ class ConstantsTransformer extends RemovingTransformer { } else { replacementStatements = [ ...replacementStatements, - for (Variable declaration in matchingCache.declarations) + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), - for (Variable declaredVariableHelper in declaredVariableHelpers) + for (VariableDeclaration declaredVariableHelper + in declaredVariableHelpers) extern.createVariableStatement(declaredVariableHelper), ...cases, ]; @@ -1633,18 +1660,20 @@ class ConstantsTransformer extends RemovingTransformer { } List cacheVariables = [ - for (Variable declaration in matchingCache.declarations) + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), ]; - Iterable declarations = + Iterable declaredVariables = node.patternGuard.pattern.declaredVariables; Statement ifStatement; - if (declarations.isNotEmpty) { + if (declaredVariables.isNotEmpty) { // If we need local declarations, create a new block to avoid naming // collision with declarations in the same parent block. ifStatement = extern.createBlock([ - for (Variable declaration in declarations) - extern.createVariableStatement(declaration), + for (Variable declaredVariable in declaredVariables) + extern.createVariableStatement( + extern.createVariableDeclaration(declaredVariable), + ), extern.createIfStatement( condition, then, @@ -1707,7 +1736,7 @@ class ConstantsTransformer extends RemovingTransformer { replacementStatements, ); replacementStatements = [ - for (Variable declaration in matchingCache.declarations) + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), ...replacementStatements, ]; @@ -1717,7 +1746,7 @@ class ConstantsTransformer extends RemovingTransformer { inCacheInitializer: false, ); replacementStatements = [ - for (Variable declaration in matchingCache.declarations) + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), // TODO(cstefantsova): Provide a better diagnostic message. extern.createIfStatement( @@ -1749,8 +1778,10 @@ class ConstantsTransformer extends RemovingTransformer { ]; } replacementStatements = [ - for (Variable declaredVariable in node.pattern.declaredVariables) - extern.createVariableStatement(declaredVariable), + for (Variable variable in node.pattern.declaredVariables) + extern.createVariableStatement( + extern.createVariableDeclaration(variable), + ), ...replacementStatements, ]; @@ -1800,11 +1831,13 @@ class ConstantsTransformer extends RemovingTransformer { effects: effects, ); replacementStatements = [ - for (Variable declaration in matchingCache.declarations) + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), for (Variable declaredVariable in node.pattern.declaredVariables) extern // Coverage-ignore(suite): Not run. - .createVariableStatement(declaredVariable), + .createVariableStatement( + extern.createVariableDeclaration(declaredVariable), + ), ...replacementStatements, ...effects, ]; @@ -1817,11 +1850,13 @@ class ConstantsTransformer extends RemovingTransformer { ); replacementStatements = [ - for (Variable declaration in matchingCache.declarations) + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), for (Variable declaredVariable in node.pattern.declaredVariables) extern // Coverage-ignore(suite): Not run. - .createVariableStatement(declaredVariable), + .createVariableStatement( + extern.createVariableDeclaration(declaredVariable), + ), // TODO(cstefantsova): Provide a better diagnostic message. extern.createIfStatement( extern.createNot(readMatchingExpression), @@ -1982,13 +2017,14 @@ class ConstantsTransformer extends RemovingTransformer { Expression replacement; if (primitiveEqualConstantsOnly) { - Variable valueVariable = extern.createUninitializedVariable( - node.staticType!, - // Avoid step debugging on the declarations of the value variable. - // TODO(johnniwinther): Find a more systematic way of omitting - // offsets for better step debugging. - fileOffset: TreeNode.noOffset, - ); + VariableDeclaration valueVariableDeclaration = extern + .createUninitializedVariableDeclaration( + type: node.staticType!, + // Avoid step debugging on the declarations of the value variable. + // TODO(johnniwinther): Find a more systematic way of omitting + // offsets for better step debugging. + fileOffset: TreeNode.noOffset, + ); LabeledStatement labeledStatement = extern.createLabeledStatement( dummyStatement, @@ -2016,7 +2052,7 @@ class ConstantsTransformer extends RemovingTransformer { extern.createBlock([ extern.createExpressionStatement( extern.createVariableSet( - valueVariable, + valueVariableDeclaration.variable, switchExpressionCase.expression, fileOffset: switchExpressionCase.expression.fileOffset, ), @@ -2041,10 +2077,10 @@ class ConstantsTransformer extends RemovingTransformer { )..parent = labeledStatement; replacement = extern.createBlockExpression( extern.createBlock([ - extern.createVariableStatement(valueVariable), + extern.createVariableStatement(valueVariableDeclaration), labeledStatement, ], fileOffset: node.fileOffset), - extern.createVariableGet(valueVariable), + extern.createVariableGet(valueVariableDeclaration.variable), fileOffset: node.fileOffset, ); } else { @@ -2064,14 +2100,15 @@ class ConstantsTransformer extends RemovingTransformer { fileOffset: node.fileOffset, ); - // valueVariable: `valueType` valueVariable; - Variable valueVariable = extern.createUninitializedVariable( - node.staticType!, - // Avoid step debugging on the declaration of the value variable. - // TODO(johnniwinther): Find a more systematic way of omitting - // offsets for better step debugging. - fileOffset: TreeNode.noOffset, - ); + // valueVariableDeclaration: `valueType` valueVariableDeclaration; + VariableDeclaration valueVariableDeclaration = extern + .createUninitializedVariableDeclaration( + type: node.staticType!, + // Avoid step debugging on the declaration of the value variable. + // TODO(johnniwinther): Find a more systematic way of omitting + // offsets for better step debugging. + fileOffset: TreeNode.noOffset, + ); List cases = []; @@ -2147,14 +2184,16 @@ class ConstantsTransformer extends RemovingTransformer { cases.add( extern.createBlock([ for (Variable declaredVariable in pattern.declaredVariables) - extern.createVariableStatement(declaredVariable), + extern.createVariableStatement( + extern.createVariableDeclaration(declaredVariable), + ), extern.createIfStatement( caseCondition, extern.createBlock([ ...?tailStatements, extern.createExpressionStatement( extern.createVariableSet( - valueVariable, + valueVariableDeclaration.variable, body, // Avoid step debugging on the assignment to the value // variable. @@ -2210,12 +2249,12 @@ class ConstantsTransformer extends RemovingTransformer { )..parent = labeledStatement; replacement = extern.createBlockExpression( extern.createBlock([ - extern.createVariableStatement(valueVariable), - for (Variable declaration in matchingCache.declarations) + extern.createVariableStatement(valueVariableDeclaration), + for (VariableDeclaration declaration in matchingCache.declarations) extern.createVariableStatement(declaration), labeledStatement, ], fileOffset: node.fileOffset), - extern.createVariableGet(valueVariable), + extern.createVariableGet(valueVariableDeclaration.variable), fileOffset: node.fileOffset, ); } @@ -2251,17 +2290,17 @@ class ConstantsTransformer extends RemovingTransformer { // the 'switch'. TreeNode? initializerParent = switch (variable) { LegacyVariable() => variable, - LocalVariable() => variable.variableInitialization, + LocalVariable() => variable.variableDeclaration, // Coverage-ignore(suite): Not run. - CatchVariable() => variable.variableInitialization, + CatchVariable() => variable.variableDeclaration, // Coverage-ignore(suite): Not run. - ThisVariable() => variable.variableInitialization, + ThisVariable() => variable.variableDeclaration, // Coverage-ignore(suite): Not run. - SyntheticVariable() => variable.variableInitialization, + SyntheticVariable() => variable.variableDeclaration, // Coverage-ignore(suite): Not run. - PositionalParameter() => variable.variableInitialization, + PositionalParameter() => variable.variableDeclaration, // Coverage-ignore(suite): Not run. - NamedParameter() => variable.variableInitialization, + NamedParameter() => variable.variableDeclaration, }; variable.initializer = evaluateAndTransformWithContext( variable, @@ -6201,10 +6240,14 @@ class StatementConstantEvaluator return const ProceedStatus(); } + ExecutionStatus visitVariableDeclaration(VariableDeclaration node) { + return node.variable.accept(this); + } + @override ExecutionStatus visitForStatement(ForStatement node) { - for (VariableStatement variable in node.variables) { - final ExecutionStatus status = variable.accept(this); + for (VariableDeclaration variable in node.variables) { + final ExecutionStatus status = visitVariableDeclaration(variable); if (status is! ProceedStatus) return status; } 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 1fdbf174477..e4da2090373 100644 --- a/pkg/front_end/lib/src/kernel/external_ast_helper.dart +++ b/pkg/front_end/lib/src/kernel/external_ast_helper.dart @@ -359,18 +359,16 @@ Field createImmutableField( /// Creates an initialized (but mutable) [Variable] of the static /// [type]. -Variable createInitializedVariable( - Expression expression, - DartType type, { +VariableDeclaration createInitializedVariableDeclaration({ + required Expression expression, + required DartType type, required int fileOffset, String? name, }) { - return new Variable( - name, - initializer: expression, - type: type, - isSynthesized: true, - )..fileOffset = fileOffset; + return createVariableDeclaration( + new Variable(name, initializer: expression, type: type, isSynthesized: true) + ..fileOffset = fileOffset, + ); } InstanceGet createInstanceGet( @@ -854,15 +852,33 @@ TypeParameter createTypeParameter(String? name, {required int fileOffset}) { } /// Creates an uninitialized [Variable] of the static [type]. -Variable createUninitializedVariable( - DartType type, { +Variable createUninitializedVariable({ + required DartType type, + String? name, required int fileOffset, bool isFinal = false, }) { - return new Variable(null, type: type, isSynthesized: true, isFinal: isFinal) + return new Variable(name, type: type, isSynthesized: true, isFinal: isFinal) ..fileOffset = fileOffset; } +/// Creates a declaration of an uninitialized [Variable] of the static [type]. +VariableDeclaration createUninitializedVariableDeclaration({ + required DartType type, + String? name, + required int fileOffset, + bool isFinal = false, +}) { + return createVariableDeclaration( + createUninitializedVariable( + type: type, + name: name, + fileOffset: fileOffset, + isFinal: isFinal, + ), + ); +} + /// Creates a [Variable] for [expression] with the static [type] /// using `expression.fileOffset` as the file offset for the declaration. // TODO(johnniwinther): Merge the use of this with [createVariableCache]. @@ -879,6 +895,10 @@ Variable createVariableCache(Expression expression, DartType type) { ..fileOffset = expression.fileOffset; } +VariableDeclaration createVariableDeclaration(Variable variable) { + return new VariableDeclaration(variable)..fileOffset = variable.fileOffset; +} + /// Creates a [VariableGet] of [variable] using `variable.fileOffset` as the /// file offset for the expression. VariableGet createVariableGet( @@ -913,6 +933,7 @@ Expression createVariableSet( } } -VariableStatement createVariableStatement(Variable variable) { - return new VariableStatement(variable)..fileOffset = variable.fileOffset; +VariableStatement createVariableStatement(VariableDeclaration declaration) { + return new VariableStatement(declaration) + ..fileOffset = declaration.fileOffset; } diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart index 6a540a4da99..c2ce9d8a935 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast.dart @@ -1125,11 +1125,11 @@ class InternalLocalVariable extends TreeNode @override List? get capturedContexts => - variableInitialization?.capturedContexts; + variableDeclaration?.capturedContexts; @override void set capturedContexts(List? value) { - variableInitialization!.capturedContexts = value; + variableDeclaration!.capturedContexts = value; } @override @@ -1655,12 +1655,12 @@ mixin DelegatingVariableMixin on InternalVariableMixin } @override - VariableInitialization? get variableInitialization => - astVariable.variableInitialization; + VariableDeclaration? get variableDeclaration => + astVariable.variableDeclaration; @override - void set variableInitialization(VariableInitialization? value) { - astVariable.variableInitialization = value; + void set variableDeclaration(VariableDeclaration? value) { + astVariable.variableDeclaration = value; } @override @@ -5709,7 +5709,7 @@ sealed class _BaseForInElement extends InternalForInElement { return new SyntheticVariable(type: type)..fileOffset = forOffset; } return extern.createUninitializedVariable( - type, + type: type, fileOffset: forOffset, isFinal: true, ); @@ -5747,21 +5747,25 @@ sealed class _BaseForInElement extends InternalForInElement { } } -/// Base implementation for declared variable for-in elements. -sealed class _VariableForInElement extends _BaseForInElement { +/// For-in element for a single declared variable. +class SingleVariableDeclarationForInElement extends _BaseForInElement { /// Error that must be emitted prior to the generated for-in statement. /// /// This is used for instance for constant loop variables. final InvalidExpression? error; - _VariableForInElement({required this.error}); - - Variable get _variableDeclaration; - - /// If the assignment to [variableDeclaration] needs additional steps, like + /// If the assignment to [_variable] needs additional steps, like /// a type coercion, this holds a synthetic variable declaration used as an /// intermediate step. - Variable? _variableForSideEffect; + VariableDeclaration? _variableForSideEffect; + + /// The declared variable. + final VariableDeclaration variableDeclaration; + + SingleVariableDeclarationForInElement({ + required this.variableDeclaration, + required this.error, + }); @override Variable _computeLoopVariable( @@ -5773,7 +5777,7 @@ sealed class _VariableForInElement extends _BaseForInElement { Variable loopVariable; DartType loopVariableType; bool checkAssignment = true; - if (_variableDeclaration.variable case InternalVariable variable) { + if (variableDeclaration.variable case InternalVariable variable) { loopVariable = variable.astVariable; if (variable.isImplicitlyTyped) { loopVariableType = variable.type = type; @@ -5783,8 +5787,8 @@ sealed class _VariableForInElement extends _BaseForInElement { } } else { // Coverage-ignore-block(suite): Not run. - loopVariable = _variableDeclaration; - loopVariableType = _variableDeclaration.type; + loopVariable = variableDeclaration.variable; + loopVariableType = variableDeclaration.variable.type; } if (checkAssignment) { Variable tempVariable = _createSyntheticVariableDeclaration( @@ -5817,7 +5821,7 @@ sealed class _VariableForInElement extends _BaseForInElement { new SharedTypeView(loopVariableType), initialized: true, ); - _variableForSideEffect = loopVariable; + _variableForSideEffect = extern.createVariableDeclaration(loopVariable); loopVariable = tempVariable; } } @@ -5836,78 +5840,27 @@ sealed class _VariableForInElement extends _BaseForInElement { : null, ); } -} - -/// For-in element for a single declared variable. -class VariableInitializationForInElement extends _VariableForInElement { - /// The variable declaration. - final VariableInitialization variableInitialization; - - VariableInitializationForInElement({ - required this.variableInitialization, - required super.error, - }); - - @override - Variable get _variableDeclaration => variableInitialization.variable; @override // Coverage-ignore(suite): Not run. void toTextInternal(AstPrinter printer) { printer.writeVariableInitialization( - variableInitialization.variable, + variableDeclaration.variable, includeInitializer: false, isImplicitlyTyped: - (variableInitialization.variable is InternalVariable) && - (variableInitialization.variable as InternalVariable) - .isImplicitlyTyped, + variableDeclaration.variable is InternalVariable && + (variableDeclaration.variable as InternalVariable).isImplicitlyTyped, ); } @override DartType _computeElementTypeContext(InferenceVisitorBase visitor) { - if (variableInitialization.variable case InternalVariable variable) { + if (variableDeclaration.variable case InternalVariable variable) { if (variable.isImplicitlyTyped) { return const UnknownType(); } } - return variableInitialization.variable.type; - } -} - -/// For-in element for a single declared variable. -class SingleVariableDeclarationForInElement extends _VariableForInElement { - /// The declared variable. - final LegacyVariableStatement variableStatement; - - SingleVariableDeclarationForInElement({ - required this.variableStatement, - required super.error, - }); - - @override - Variable get _variableDeclaration => variableStatement.variable; - - @override - // Coverage-ignore(suite): Not run. - void toTextInternal(AstPrinter printer) { - printer.writeVariableInitialization( - variableStatement.variable, - includeInitializer: false, - isImplicitlyTyped: - variableStatement.variable is InternalVariable && - (variableStatement.variable as InternalVariable).isImplicitlyTyped, - ); - } - - @override - DartType _computeElementTypeContext(InferenceVisitorBase visitor) { - if (variableStatement.variable case InternalVariable variable) { - if (variable.isImplicitlyTyped) { - return const UnknownType(); - } - } - return variableStatement.variable.type; + return variableDeclaration.variable.type; } } @@ -5915,7 +5868,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; @@ -5929,7 +5882,7 @@ class MultiVariableDeclarationForInElement extends _BaseForInElement { // Coverage-ignore(suite): Not run. void toTextInternal(AstPrinter printer) { for (int i = 0; i < variableDeclarations.length; i++) { - VariableStatement variableDeclaration = variableDeclarations[i]; + VariableDeclaration variableDeclaration = variableDeclarations[i]; if (i == 0) { printer.writeVariableInitialization( variableDeclaration.variable, @@ -5963,7 +5916,8 @@ class MultiVariableDeclarationForInElement extends _BaseForInElement { return new ForInEncoding( preLoopError: error, bodyPrologue: extern.createBlock([ - ...variableDeclarations, + for (VariableDeclaration variableDeclaration in variableDeclarations) + extern.createVariableStatement(variableDeclaration), ], fileOffset: TreeNode.noOffset), ); } 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 6e2a9829777..a688c0aed29 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast_helper.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast_helper.dart @@ -123,7 +123,9 @@ Block createBlock( Statement statement = statements[i]; if (statement is _VariablesDeclaration) { copy ??= new List.of(statements.getRange(0, i)); - copy.addAll(statement.declarations); + for (VariableDeclaration declaration in statement.declarations) { + copy.add(createVariableStatement(declaration)); + } } else if (copy != null) { copy.add(statement); } @@ -302,7 +304,7 @@ Statement createExpressionStatement( ForElement createForElement( int fileOffset, - List variables, + List variables, Expression? condition, List updates, Expression body, @@ -363,7 +365,7 @@ ForInStatement createForInStatement( ForMapEntry createForMapEntry( int fileOffset, - List variables, + List variables, Expression? condition, List updates, MapLiteralEntry body, @@ -375,7 +377,7 @@ ForMapEntry createForMapEntry( /// Return a representation of a for statement. Statement createForStatement( int fileOffset, - List? variables, + List? variables, Expression? condition, List updaters, Statement body, @@ -607,6 +609,7 @@ LocalVariable createLocalVariable({ bool isWildcard = false, required int fileOffset, Expression? initializer, + bool hasDeclaredInitializer = false, }) { return new LocalVariable( cosmeticName: cosmeticName, @@ -616,6 +619,7 @@ LocalVariable createLocalVariable({ isLate: isLate, isWildcard: isWildcard, initializer: initializer, + hasDeclaredInitializer: hasDeclaredInitializer, )..fileOffset = fileOffset; } @@ -811,8 +815,8 @@ PatternAssignment createPatternAssignment( PatternForElement createPatternForElement( int fileOffset, { required PatternVariableDeclaration patternVariableDeclaration, - required List intermediateVariables, - required List variables, + required List intermediateVariables, + required List variables, required Expression? condition, required List updates, required Expression body, @@ -830,8 +834,8 @@ PatternForElement createPatternForElement( PatternForMapEntry createPatternForMapEntry( int fileOffset, { required PatternVariableDeclaration patternVariableDeclaration, - required List intermediateVariables, - required List variableInitializations, + required List intermediateVariables, + required List variableInitializations, required Expression? condition, required List updates, required MapLiteralEntry body, @@ -1166,7 +1170,7 @@ UnaryExpression createUnary( /// Creates [Variable] for a variable named [name] at the given /// [functionNestingLevel]. -Variable createVariableDeclaration( +Variable createVariable( int fileOffset, String? name, { Expression? initializer, @@ -1195,6 +1199,14 @@ Variable createVariableDeclaration( ); } +VariableDeclaration createVariableDeclaration( + Variable variable, { + int? fileOffset, +}) { + return new VariableDeclaration(variable) + ..fileOffset = fileOffset ?? variable.fileOffset; +} + VariableDeclarationImpl createVariableDeclarationForValue( Expression initializer, { DartType type = const DynamicType(), @@ -1212,17 +1224,6 @@ InternalVariableGet createVariableGet( ..fileOffset = fileOffset; } -VariableInitialization createVariableInitialization({ - required Variable variable, - required bool hasDeclaredInitializer, - required int fileOffset, -}) { - return new VariableInitialization( - variable: variable, - hasDeclaredInitializer: hasDeclaredInitializer, - )..fileOffset = fileOffset; -} - VariablePattern createVariablePattern( int fileOffset, DartType? type, @@ -1240,8 +1241,12 @@ InternalVariableSet createVariableSet( ..fileOffset = fileOffset; } -VariableStatement createVariableStatement(Variable variable) { - return new VariableStatement(variable)..fileOffset = variable.fileOffset; +VariableStatement createVariableStatement( + VariableDeclaration declaration, { + int? fileOffset, +}) { + return new VariableStatement(declaration) + ..fileOffset = fileOffset ?? declaration.fileOffset; } /// Return a representation of a while statement at the given [fileOffset] @@ -1295,13 +1300,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; @@ -1312,7 +1317,7 @@ Statement wrapVariables(Statement statement) { return new Block( new List.generate( statement.declarations.length, - (int index) => statement.declarations[index], + (int index) => createVariableStatement(statement.declarations[index]), growable: true, ), )..fileOffset = statement.fileOffset; @@ -1324,7 +1329,7 @@ Statement wrapVariables(Statement statement) { } class _VariablesDeclaration extends AuxiliaryStatement { - final List declarations; + final List declarations; final Uri uri; _VariablesDeclaration(this.declarations, this.uri) { @@ -1355,8 +1360,8 @@ class _VariablesDeclaration extends AuxiliaryStatement { if (index > 0) { printer.write(', '); } - printer.writeVariableInitialization( - declarations[index].variable, + printer.writeVariableDeclaration( + declarations[index], 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 05de4a95547..3f754318234 100644 --- a/pkg/front_end/lib/src/kernel/late_lowering.dart +++ b/pkg/front_end/lib/src/kernel/late_lowering.dart @@ -156,7 +156,9 @@ Statement createGetterWithInitializerWithRecheck( new Not(createIsSetRead()..fileOffset = fileOffset) ..fileOffset = fileOffset, new Block([ - new VariableStatement(temp)..fileOffset = temp.fileOffset, + new VariableStatement( + new VariableDeclaration(temp)..fileOffset = temp.fileOffset, + )..fileOffset = temp.fileOffset, new IfStatement( createIsSetRead()..fileOffset = fileOffset, new ExpressionStatement(exception)..fileOffset = fileOffset, diff --git a/pkg/front_end/lib/src/type_inference/inference_results.dart b/pkg/front_end/lib/src/type_inference/inference_results.dart index f159aa15ac2..93fd1badb41 100644 --- a/pkg/front_end/lib/src/type_inference/inference_results.dart +++ b/pkg/front_end/lib/src/type_inference/inference_results.dart @@ -99,6 +99,68 @@ class MultipleStatementInferenceResult implements StatementInferenceResult { int get statementCount => statements.length; } +class VariableDeclarationInferenceResult { + const VariableDeclarationInferenceResult(); + + factory VariableDeclarationInferenceResult.effect([Expression? expression]) = + EffectVariableDeclarationInferenceResult; + + factory VariableDeclarationInferenceResult.late( + List variableDeclarations, + List functionDeclarations, { + required int fileOffset, + }) = LateVariableDeclarationInferenceResult; + + bool get hasChanged => false; + + StatementInferenceResult toStatementInferenceResult() => + const StatementInferenceResult(); +} + +class EffectVariableDeclarationInferenceResult + implements VariableDeclarationInferenceResult { + final Expression? expression; + + EffectVariableDeclarationInferenceResult([this.expression]); + + @override + // Coverage-ignore(suite): Not run. + bool get hasChanged => true; + + @override + StatementInferenceResult toStatementInferenceResult() => + new StatementInferenceResult.single( + expression != null + ? createExpressionStatement(expression!) + : createEmptyStatement(), + ); +} + +class LateVariableDeclarationInferenceResult + implements VariableDeclarationInferenceResult { + final int fileOffset; + final List variableDeclarations; + final List functionDeclarations; + + LateVariableDeclarationInferenceResult( + this.variableDeclarations, + this.functionDeclarations, { + required this.fileOffset, + }); + + @override + // Coverage-ignore(suite): Not run. + bool get hasChanged => true; + + @override + StatementInferenceResult toStatementInferenceResult() => + new StatementInferenceResult.multiple(fileOffset, [ + for (VariableDeclaration variableDeclaration in variableDeclarations) + createVariableStatement(variableDeclaration), + ...functionDeclarations, + ]); +} + /// Tells the inferred type and how the code should be transformed. /// /// It is intended for use by generalized inference methods, such as 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 fef5b369628..6aab8cedc19 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart @@ -121,8 +121,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ExpressionVisitor1ExperimentExclusionMixin< ExpressionInferenceResult, DartType - >, - StatementVisitorExperimentExclusionMixin + > implements ExpressionVisitor1, StatementVisitor, @@ -3326,7 +3325,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); Variable loopVariable = extern.createUninitializedVariable( - elementType, + type: elementType, fileOffset: node.fileOffset, isFinal: true, ); @@ -3424,10 +3423,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase scopeProviderInfoKind: ScopeProviderInfoKind.Loop, ); } - List? variables; for (int index = 0; index < node.variables.length; index++) { - VariableStatement variableStatement = node.variables[index]; - Variable variable = variableStatement.variable; + VariableDeclaration variableDeclaration = node.variables[index]; + Variable variable = variableDeclaration.variable; if (variable.name == null) { if (variable.initializer != null) { ExpressionInferenceResult result = inferExpression( @@ -3439,35 +3437,14 @@ class InferenceVisitorImpl extends InferenceVisitorBase variable.type = result.inferredType; } } else { - StatementInferenceResult variableResult = inferStatement( - variableStatement, + VariableDeclarationInferenceResult variableResult = + inferVariableDeclaration(variableDeclaration); + assert( + !variableResult.hasChanged, + "Unexpected variable declaration change.", ); - if (variableResult.hasChanged) { - // Coverage-ignore-block(suite): Not run. - if (variables == null) { - variables = []; - variables.addAll(node.variables.sublist(0, index)); - } - if (variableResult.statementCount == 1) { - variables.add(variableResult.statement as VariableStatement); - } else { - for (Statement variable in variableResult.statements) { - variables.add(variable as VariableStatement); - } - } - } - // Coverage-ignore(suite): Not run. - else if (variables != null) { - variables.add(variableStatement); - } } } - if (variables != null) { - // Coverage-ignore-block(suite): Not run. - node.variables.clear(); - node.variables.addAll(variables); - setParents(variables, node); - } flowAnalysis.for_conditionBegin(node); if (node.condition != null) { InterfaceType expectedType = coreTypes.boolRawType( @@ -4341,11 +4318,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase List declaredVariables = patternVariableDeclaration.pattern.declaredVariables; assert(declaredVariables.length == element.intermediateVariables.length); - assert(declaredVariables.length == element.variableInitializations.length); + assert(declaredVariables.length == element.variables.length); for (int i = 0; i < declaredVariables.length; i++) { DartType type = declaredVariables[i].type; - Variable intermediateVariable = element.intermediateVariables[i]; + Variable intermediateVariable = element.intermediateVariables[i].variable; intermediateVariable.initializer = inferExpression( intermediateVariable.initializer!, type, @@ -4353,7 +4330,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ).expression..parent = intermediateVariable; intermediateVariable.type = type; - element.variableInitializations[i].variable.type = type; + element.variables[i].variable.type = type; } return _inferForElementBase( @@ -4384,16 +4361,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase Map inferredSpreadTypes, Map inferredConditionTypes, ) { - // TODO(johnniwinther): Use _visitStatements instead. - List? variables; - for ( - int index = 0; - index < element.variableInitializations.length; - index++ - ) { - VariableStatement variableStatement = - element.variableInitializations[index]; - Variable variable = variableStatement.variable; + for (int index = 0; index < element.variables.length; index++) { + VariableDeclaration variableDeclaration = element.variables[index]; + Variable variable = variableDeclaration.variable; if (variable.name == null) { if (variable.initializer != null) { ExpressionInferenceResult initializerResult = inferExpression( @@ -4406,35 +4376,14 @@ class InferenceVisitorImpl extends InferenceVisitorBase variable.type = initializerResult.inferredType; } } else { - StatementInferenceResult variableResult = inferStatement( - variableStatement, + VariableDeclarationInferenceResult variableResult = + inferVariableDeclaration(variableDeclaration); + assert( + !variableResult.hasChanged, + "Unexpected variable declaration change.", ); - if (variableResult.hasChanged) { - // Coverage-ignore-block(suite): Not run. - if (variables == null) { - variables = []; - variables.addAll(element.variableInitializations.sublist(0, index)); - } - if (variableResult.statementCount == 1) { - variables.add(variableResult.statement as VariableStatement); - } else { - for (Statement variable in variableResult.statements) { - variables.add(variable as VariableStatement); - } - } - } - // Coverage-ignore(suite): Not run. - else if (variables != null) { - variables.add(variableStatement); - } } } - if (variables != null) { - // Coverage-ignore-block(suite): Not run. - element.variableInitializations.clear(); - element.variableInitializations.addAll(variables); - setParents(variables, element); - } flowAnalysis.for_conditionBegin(element); if (element.condition != null) { @@ -4988,7 +4937,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase )..fileOffset = node.fileOffset, receiverType, ); - body = [extern.createVariableStatement(result)]; + body = [ + extern.createVariableStatement( + extern.createVariableDeclaration(result), + ), + ]; // Add the elements up to the first non-expression. for (int j = 0; j < index; ++j) { _addExpressionElement( @@ -5013,7 +4966,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); } } - body ??= [extern.createVariableStatement(result)]; + body ??= [ + extern.createVariableStatement(extern.createVariableDeclaration(result)), + ]; // Translate the elements starting with the first non-expression. for (; index < elements.length; ++index) { _translateElement( @@ -5306,7 +5261,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase // Coverage-ignore(suite): Not run. ?.registerAlias(element, loop); body.add(element.patternVariableDeclaration); - for (Variable intermediateVariable in element.intermediateVariables) { + for (VariableDeclaration intermediateVariable + in element.intermediateVariables) { body.add(extern.createVariableStatement(intermediateVariable)); } body.add(loop); @@ -5385,7 +5341,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase value, typeSchemaEnvironment.iterableType(elementType, Nullability.nullable), ); - body.add(extern.createVariableStatement(temp)); + body.add( + extern.createVariableStatement( + extern.createVariableDeclaration(temp), + ), + ); value = _createNullCheckedVariableGet(temp); } @@ -5419,7 +5379,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase Nullability.nullable, ), ); - body.add(extern.createVariableStatement(temp)); + body.add( + extern.createVariableStatement( + extern.createVariableDeclaration(temp), + ), + ); value = _createNullCheckedVariableGet(temp); } @@ -5436,7 +5400,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase elementType, ); Statement loopBody = _createBlock([ - extern.createVariableStatement(castedVar), + extern.createVariableStatement( + extern.createVariableDeclaration(castedVar), + ), _createExpressionStatement( _createAdd( // Don't make a mess of jumping around (and make scope building @@ -5496,7 +5462,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase Nullability.nullable, ); Variable temp = _createVariable(value, nullableElementType); - body.add(extern.createVariableStatement(temp)); + body.add( + extern.createVariableStatement(extern.createVariableDeclaration(temp)), + ); Statement statement = _createIf( temp.fileOffset, @@ -5613,14 +5581,20 @@ class InferenceVisitorImpl extends InferenceVisitorBase _createMapLiteral(node.fileOffset, node.keyType, node.valueType, []), receiverType, ); - body = [extern.createVariableStatement(result)]; + body = [ + extern.createVariableStatement( + extern.createVariableDeclaration(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 ??= [extern.createVariableStatement(result)]; + body ??= [ + extern.createVariableStatement(extern.createVariableDeclaration(result)), + ]; // Translate the elements starting with the first non-expression. for (; index < node.entries.length; ++index) { @@ -5910,7 +5884,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase // Coverage-ignore(suite): Not run. ?.registerAlias(entry, loop); body.add(entry.patternVariableDeclaration); - for (Variable intermediateVariable in entry.intermediateVariables) { + for (VariableDeclaration intermediateVariable + in entry.intermediateVariables) { body.add(extern.createVariableStatement(intermediateVariable)); } body.add(loop); @@ -6000,7 +5975,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase Nullability.nullable, ), ); - body.add(extern.createVariableStatement(temp)); + body.add( + extern.createVariableStatement( + extern.createVariableDeclaration(temp), + ), + ); value = _createNullCheckedVariableGet(temp); } @@ -6034,7 +6013,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase Nullability.nullable, ), ); - body.add(extern.createVariableStatement(temp)); + body.add( + extern.createVariableStatement( + extern.createVariableDeclaration(temp), + ), + ); value = _createNullCheckedVariableGet(temp); } @@ -6069,8 +6052,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase valueType, ); Statement loopBody = _createBlock([ - extern.createVariableStatement(keyVar), - extern.createVariableStatement(valueVar), + extern.createVariableStatement( + extern.createVariableDeclaration(keyVar), + ), + extern.createVariableStatement( + extern.createVariableDeclaration(valueVar), + ), _createExpressionStatement( _createIndexSet( entry.expression.fileOffset, @@ -6157,7 +6144,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase addedEntryStatementParent ??= ifValueNotNullStatement; desugaredStatement = _createBlock([ - extern.createVariableStatement(valueTemp), + extern.createVariableStatement( + extern.createVariableDeclaration(valueTemp), + ), ifValueNotNullStatement, ])..fileOffset = entry.fileOffset; } @@ -6177,7 +6166,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase addedEntryStatementParent ??= ifKeyNotNullStatement; desugaredStatement = _createBlock([ - extern.createVariableStatement(keyTemp), + extern.createVariableStatement( + extern.createVariableDeclaration(keyTemp), + ), ifKeyNotNullStatement, ])..fileOffset = entry.fileOffset; } else if (entry.isValueNullAware) { @@ -6212,9 +6203,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase desugaredStatement.statements.insert( 0, - extern.createVariableStatement(keyTemp), + extern.createVariableStatement( + extern.createVariableDeclaration(keyTemp), + )..parent = desugaredStatement, ); - keyTemp.parent = desugaredStatement; } // Since either the key or the value is null-aware, [desugaredStatement] @@ -6867,7 +6859,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ForStatement _createForStatement( int fileOffset, - List variables, + List variables, Expression? condition, List updates, Statement body, @@ -7479,7 +7471,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase for (int i = 0; i < declaredVariables.length; i++) { DartType type = declaredVariables[i].type; - Variable intermediateVariable = entry.intermediateVariables[i]; + Variable intermediateVariable = entry.intermediateVariables[i].variable; intermediateVariable.initializer = inferExpression( intermediateVariable.initializer!, type, @@ -7542,11 +7534,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase Map inferredConditionTypes, _MapLiteralEntryOffsets offsets, ) { - // TODO(johnniwinther): Use _visitStatements instead. - List? variables; for (int index = 0; index < entry.variables.length; index++) { - VariableStatement variableStatement = entry.variables[index]; - Variable variable = variableStatement.variable; + VariableDeclaration variableDeclaration = entry.variables[index]; + Variable variable = variableDeclaration.variable; if (variable.name == null) { if (variable.initializer != null) { ExpressionInferenceResult result = inferExpression( @@ -7558,35 +7548,14 @@ class InferenceVisitorImpl extends InferenceVisitorBase variable.type = result.inferredType; } } else { - StatementInferenceResult variableResult = inferStatement( - variableStatement, + VariableDeclarationInferenceResult variableResult = + inferVariableDeclaration(variableDeclaration); + assert( + !variableResult.hasChanged, + "Unexpected variable declaration change.", ); - if (variableResult.hasChanged) { - // Coverage-ignore-block(suite): Not run. - if (variables == null) { - variables = []; - variables.addAll(entry.variables.sublist(0, index)); - } - if (variableResult.statementCount == 1) { - variables.add(variableResult.statement as VariableStatement); - } else { - for (Statement variable in variableResult.statements) { - variables.add(variable as VariableStatement); - } - } - } - // Coverage-ignore(suite): Not run. - else if (variables != null) { - variables.add(variableStatement); - } } } - if (variables != null) { - // Coverage-ignore-block(suite): Not run. - entry.variables.clear(); - entry.variables.addAll(variables); - setParents(variables, entry); - } flowAnalysis.for_conditionBegin(entry); if (entry.condition != null) { @@ -11887,8 +11856,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase ..fileOffset = node.fileOffset; return new BlockExpression( new Block([ - extern.createVariableStatement(node.variable), - extern.createVariableStatement(resultVar), + extern.createVariableStatement( + extern.createVariableDeclaration(node.variable), + ), + extern.createVariableStatement( + extern.createVariableDeclaration(resultVar), + ), new ExpressionStatement(new VariableSet(resultVar, body)) ..fileOffset = node.fileOffset, ]), @@ -12506,7 +12479,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); // Now create a list of all statements needed. - List statements = [extern.createVariableStatement(setVar)]; + List statements = [ + extern.createVariableStatement(extern.createVariableDeclaration(setVar)), + ]; for (int i = 0; i < node.expressions.length; i++) { Expression entry = node.expressions[i]; DartType functionType = Substitution.fromInterfaceType( @@ -13374,34 +13349,31 @@ class InferenceVisitorImpl extends InferenceVisitorBase return result; } - @override - StatementInferenceResult visitLegacyVariableStatement( - LegacyVariableStatement node, + VariableDeclarationInferenceResult inferVariableDeclaration( + VariableDeclaration node, ) { InternalVariable nodeVariable = node.variable as InternalVariable; - StatementInferenceResult statementInferenceResult = + VariableDeclarationInferenceResult variableDeclarationInferenceResult = _inferInternalExpressionVariableDeclaration( + node, 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; + return variableDeclarationInferenceResult; } @override - // Coverage-ignore(suite): Not run. - StatementInferenceResult visitVariable( - covariant VariableDeclarationImpl node, - ) { - return _inferInternalExpressionVariableDeclaration(node, node); + StatementInferenceResult visitVariableStatement(VariableStatement node) { + return inferVariableDeclaration( + node.declaration, + ).toStatementInferenceResult(); } @override @@ -16738,32 +16710,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase return capturedVariables; } - @override - StatementInferenceResult visitVariableInitialization( - VariableInitialization node, - ) { - InternalVariable nodeVariable = node.variable as InternalVariable; - StatementInferenceResult statementInferenceResult = - _inferInternalExpressionVariableDeclaration( - node.variable, - nodeVariable, - variableStatement: node, - ); - node.variable = nodeVariable.astVariable; - if (isClosureContextLoweringEnabled) { - _contextAllocationStrategy.handleDeclarationOfVariable( - node.variable, - captureKind: _captureKindForVariable(node.variable), - ); - } - return statementInferenceResult; - } - - StatementInferenceResult _inferInternalExpressionVariableDeclaration( + VariableDeclarationInferenceResult + _inferInternalExpressionVariableDeclaration( + VariableDeclaration variableDeclaration, Variable node, - InternalVariable nodeVariable, { - VariableStatement? variableStatement, - }) { + InternalVariable nodeVariable, + ) { DartType declaredType = nodeVariable.isImplicitlyTyped ? const UnknownType() : node.type; @@ -16778,17 +16730,15 @@ class InferenceVisitorImpl extends InferenceVisitorBase !node.isConst && node.parent?.parent is! ForStatement) { if (node.initializer case var initializer? when !node.isLate) { - return new StatementInferenceResult.single( - createExpressionStatement( - inferExpression( - initializer, - declaredType, - isVoidAllowed: true, - ).expression, - ), + return new VariableDeclarationInferenceResult.effect( + inferExpression( + initializer, + declaredType, + isVoidAllowed: true, + ).expression, ); } else { - return new StatementInferenceResult.single(new EmptyStatement()); + return new VariableDeclarationInferenceResult.effect(); } } if (node.initializer != null) { @@ -16860,11 +16810,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase )) { int fileOffset = node.fileOffset; - List result = []; - result.add( - variableStatement ?? // Coverage-ignore(suite): Not run. - extern.createVariableStatement(node), - ); + List variableDeclarations = []; + List functionDeclarations = []; + variableDeclarations.add(variableDeclaration); late_lowering.IsSetEncoding isSetEncoding = late_lowering .computeIsSetEncoding( @@ -16879,7 +16827,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase type: coreTypes.boolRawType(Nullability.nonNullable), isLowered: true, )..fileOffset = fileOffset; - result.add(extern.createVariableStatement(isSetVariable)); + variableDeclarations.add( + extern.createVariableDeclaration(isSetVariable), + ); } Expression createVariableRead({bool needsPromotion = false}) { @@ -16949,7 +16899,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase Nullability.nonNullable, ); nodeVariable.lateGetter = getVariable; - result.add(getter); + functionDeclarations.add(getter); if (!node.isFinal || node.initializer == null) { nodeVariable.isLateFinalWithoutInitializer = @@ -17002,7 +16952,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase Nullability.nonNullable, ); nodeVariable.lateSetter = setVariable; - result.add(setter); + functionDeclarations.add(setter); } node.isLate = false; nodeVariable.lateType = node.type; @@ -17022,9 +16972,13 @@ class InferenceVisitorImpl extends InferenceVisitorBase node.isLowered = true; node.name = late_lowering.computeLateLocalName(node.name!); - return new StatementInferenceResult.multiple(node.fileOffset, result); + return new VariableDeclarationInferenceResult.late( + variableDeclarations, + functionDeclarations, + fileOffset: node.fileOffset, + ); } - return const StatementInferenceResult(); + return const VariableDeclarationInferenceResult(); } @override 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 b876f4257b2..6ca32eead3e 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 @@ -4979,10 +4979,10 @@ abstract class InferenceVisitorBase implements InferenceVisitor { if (expression.body.statements.isEmpty) return false; Statement first = expression.body.statements.first; if (first is! VariableStatement) return false; - Expression? initializer = first.variable.initializer; + Expression? initializer = first.declaration.variable.initializer; if (initializer is! StaticInvocation) return false; if (initializer.target != engine.setFactory) return false; - return value.variable == first.variable; + return value.variable == first.declaration.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 813acbc7046..42f97a59509 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 = {}; @@ -98,7 +98,7 @@ class MatchingCache { // Coverage-ignore-block(suite): Not run. // Error case. This variable is only declared one of the branches and // therefore not joint. Include the variable in the declarations. - registerDeclaration(variable); + registerDeclaration(createVariableDeclaration(variable)); } } for (Variable variable in variables2) { @@ -108,7 +108,7 @@ class MatchingCache { } else { // Error case. This variable is only declared one of the branches and // therefore not joint. Include the variable in the declarations. - registerDeclaration(variable); + registerDeclaration(createVariableDeclaration(variable)); } } } @@ -166,7 +166,7 @@ class MatchingCache { /// Registers that the variable or local function [declaration] is need for /// the cached expressions. - void registerDeclaration(Variable 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; } @@ -184,12 +184,12 @@ class MatchingCache { /// Creates a [Variable] for a temporary variable of the given /// [type] and registers it with [registerDeclaration]. Variable createTemporaryVariable(DartType type, {required int fileOffset}) { - Variable variable = createUninitializedVariable( - type, + VariableDeclaration declaration = createUninitializedVariableDeclaration( + type: type, fileOffset: fileOffset, ); - registerDeclaration(variable); - return variable; + registerDeclaration(declaration); + return declaration.variable; } /// Creates the cacheable expression for the scrutinee [expression] of the @@ -1369,7 +1369,9 @@ class Cache { // offsets for better step debugging. variable.fileOffset = TreeNode.noOffset; } - _matchingCache.registerDeclaration(variable); + _matchingCache.registerDeclaration( + createVariableDeclaration(variable), + ); } result = createVariableGet(variable)..fileOffset = TreeNode.noOffset; } else { @@ -1387,24 +1389,31 @@ class Cache { break; } } - variable = _variable = - createUninitializedVariable(cacheType!, fileOffset: _fileOffset) - ..name = _name + + VariableDeclaration variableDeclaration = + createUninitializedVariableDeclaration( + type: cacheType!, + name: _name, // Avoid step debugging on the declaration of caching variables. // TODO(johnniwinther): Find a more systematic way of omitting // offsets for better step debugging. - ..fileOffset = TreeNode.noOffset; + fileOffset: TreeNode.noOffset, + ); + variable = _variable = variableDeclaration.variable; + _matchingCache.registerDeclaration(variableDeclaration); - _matchingCache.registerDeclaration(variable); - isSetVariable = _isSetVariable = createInitializedVariable( - createBoolLiteral(false, fileOffset: _fileOffset), - typeEnvironment.coreTypes.boolNonNullableRawType, - // Avoid step debugging on the declaration of caching variables. - // TODO(johnniwinther): Find a more systematic way of omitting - // offsets for better step debugging. - fileOffset: TreeNode.noOffset, - )..name = '$_name#isSet'; - _matchingCache.registerDeclaration(isSetVariable); + VariableDeclaration isSetVariableDeclaration = + createInitializedVariableDeclaration( + expression: createBoolLiteral(false, fileOffset: _fileOffset), + type: typeEnvironment.coreTypes.boolNonNullableRawType, + name: '$_name#isSet', + // Avoid step debugging on the declaration of caching variables. + // TODO(johnniwinther): Find a more systematic way of omitting + // offsets for better step debugging. + fileOffset: TreeNode.noOffset, + ); + isSetVariable = _isSetVariable = isSetVariableDeclaration.variable; + _matchingCache.registerDeclaration(isSetVariableDeclaration); } result = createConditionalExpression( createVariableGet(isSetVariable!), diff --git a/pkg/front_end/test/dart_scope_calculator_test.dart b/pkg/front_end/test/dart_scope_calculator_test.dart index 1dfbe8e4798..e1d731353d5 100644 --- a/pkg/front_end/test/dart_scope_calculator_test.dart +++ b/pkg/front_end/test/dart_scope_calculator_test.dart @@ -586,10 +586,10 @@ class ScopeTestingBinaryPrinter extends BinaryPrinter { } @override - void writeVariableDeclaration(Variable node) { + void writeVariable(Variable node) { bool oldCheckOffset = checkOffset; checkOffset = true; - super.writeVariableDeclaration(node); + super.writeVariable(node); checkOffset = oldCheckOffset; } } 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 9d022384db0..20a60369f8c 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 @@ -224,16 +224,18 @@ void main() { void _testVariableDeclarations() { testStatement( forest.variablesDeclaration([ - new VariableStatement(new Variable('a')), - new VariableStatement(new Variable('b')), + new VariableDeclaration(new Variable('a')), + new VariableDeclaration(new Variable('b')), ], dummyUri), ''' dynamic a, b;''', ); testStatement( forest.variablesDeclaration([ - new VariableStatement(new Variable('a', type: const VoidType())), - new VariableStatement(new Variable('b', initializer: new NullLiteral())), + new VariableDeclaration(new Variable('a', type: const VoidType())), + new VariableDeclaration( + new Variable('b', initializer: new NullLiteral()), + ), ], dummyUri), ''' void a, b = null;''', @@ -368,7 +370,7 @@ void _testInternalForInStatement() { testStatement( new InternalForInStatement( new SingleVariableDeclarationForInElement( - variableStatement: new LegacyVariableStatement( + variableDeclaration: new VariableDeclaration( new VariableDeclarationImpl('e', fileOffset: -1), ), error: null, @@ -386,7 +388,7 @@ for (var e in null) {}''', testStatement( new InternalForInStatement( new SingleVariableDeclarationForInElement( - variableStatement: new LegacyVariableStatement( + variableDeclaration: new VariableDeclaration( new VariableDeclarationImpl( 'e', type: const VoidType(), @@ -521,10 +523,10 @@ for (null in null) {}''', new InternalForInStatement( new MultiVariableDeclarationForInElement( variableDeclarations: [ - new VariableStatement( + new VariableDeclaration( new VariableDeclarationImpl('a', fileOffset: -1), ), - new VariableStatement( + new VariableDeclaration( new VariableDeclarationImpl('b', fileOffset: -1), ), ], @@ -544,14 +546,14 @@ for (var a, b in null) {}''', new InternalForInStatement( new MultiVariableDeclarationForInElement( variableDeclarations: [ - new VariableStatement( + new VariableDeclaration( new VariableDeclarationImpl( 'a', type: const VoidType(), fileOffset: -1, ), ), - new VariableStatement( + new VariableDeclaration( new VariableDeclarationImpl('b', fileOffset: -1), ), ], diff --git a/pkg/front_end/testcases/modular.status b/pkg/front_end/testcases/modular.status index 3d90f5db388..48ecef18bca 100644 --- a/pkg/front_end/testcases/modular.status +++ b/pkg/front_end/testcases/modular.status @@ -21,20 +21,19 @@ inference/mixin_inference_unification_1: TypeCheckError inference/mixin_inference_unification_2: TypeCheckError # Temporarily unimplemented binary serialization, see https://github.com/dart-lang/sdk/issues/61765 -closure_context_lowering/local_variables: Crash -closure_context_lowering/parameters: Crash -closure_context_lowering/this_variable: Crash -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: ExpectationFileMismatchSerialized -closure_context_lowering/synthetic_variables: Crash closure_context_lowering/assert_captured_variables: ExpectationFileMismatchSerialized +closure_context_lowering/catch_variables: ExpectationFileMismatchSerialized +closure_context_lowering/constant_local_variable: ExpectationFileMismatchSerialized closure_context_lowering/constructor_initializers: ExpectationFileMismatchSerialized -closure_context_lowering/super_initializing_formal: ExpectationFileMismatchSerialized +closure_context_lowering/foo42: ExpectationFileMismatchSerialized +closure_context_lowering/foo45: ExpectationFileMismatchSerialized +closure_context_lowering/foo48: ExpectationFileMismatchSerialized closure_context_lowering/late_field_initializers: Crash +closure_context_lowering/late_variable_initializers: ExpectationFileMismatchSerialized +closure_context_lowering/local_variables: ExpectationFileMismatchSerialized +closure_context_lowering/loop_depth_strategy: ExpectationFileMismatchSerialized +closure_context_lowering/parameters: Crash closure_context_lowering/redirecting_factories: ExpectationFileMismatchSerialized -closure_context_lowering/constant_local_variable: Crash \ No newline at end of file +closure_context_lowering/super_initializing_formal: ExpectationFileMismatchSerialized +closure_context_lowering/synthetic_variables: Crash +closure_context_lowering/this_variable: Crash diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status index 2657d760ea7..f8c9e221a1b 100644 --- a/pkg/front_end/testcases/strong.status +++ b/pkg/front_end/testcases/strong.status @@ -260,19 +260,19 @@ wildcard_variables/local_var_no_shadowing: semiFuzzFailureOnForceRebuildBodies # wildcard_variables/top_level_function_no_shadow: semiFuzzFailureOnForceRebuildBodies # Expected # Temporarily unimplemented binary serialization, see https://github.com/dart-lang/sdk/issues/61765 -closure_context_lowering/local_variables: Crash -closure_context_lowering/parameters: Crash -closure_context_lowering/this_variable: Crash -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/late_variable_initializers: Crash -closure_context_lowering/catch_variables: ExpectationFileMismatchSerialized -closure_context_lowering/synthetic_variables: Crash closure_context_lowering/assert_captured_variables: ExpectationFileMismatchSerialized +closure_context_lowering/catch_variables: ExpectationFileMismatchSerialized +closure_context_lowering/constant_local_variable: ExpectationFileMismatchSerialized closure_context_lowering/constructor_initializers: ExpectationFileMismatchSerialized -closure_context_lowering/super_initializing_formal: ExpectationFileMismatchSerialized +closure_context_lowering/foo42: ExpectationFileMismatchSerialized +closure_context_lowering/foo45: ExpectationFileMismatchSerialized +closure_context_lowering/foo48: ExpectationFileMismatchSerialized closure_context_lowering/late_field_initializers: Crash +closure_context_lowering/late_variable_initializers: ExpectationFileMismatchSerialized +closure_context_lowering/local_variables: ExpectationFileMismatchSerialized +closure_context_lowering/loop_depth_strategy: ExpectationFileMismatchSerialized +closure_context_lowering/parameters: Crash closure_context_lowering/redirecting_factories: ExpectationFileMismatchSerialized -closure_context_lowering/constant_local_variable: Crash \ No newline at end of file +closure_context_lowering/super_initializing_formal: ExpectationFileMismatchSerialized +closure_context_lowering/synthetic_variables: Crash +closure_context_lowering/this_variable: Crash diff --git a/pkg/front_end/tool/ast_model.dart b/pkg/front_end/tool/ast_model.dart index a0f303b4645..982d6f77c90 100644 --- a/pkg/front_end/tool/ast_model.dart +++ b/pkg/front_end/tool/ast_model.dart @@ -130,7 +130,7 @@ const Map> _fieldRuleMap = { 'VariableSet': {'variable': FieldRule(isDeclaration: false)}, 'LocalFunctionInvocation': {'variable': FieldRule(isDeclaration: false)}, 'LocalVariable': { - 'variableInitialization': FieldRule(isDeclaration: false), + 'variableDeclaration': FieldRule(isDeclaration: false), '_context': FieldRule(name: 'context'), }, 'CatchVariable': {'_context': FieldRule(name: 'context')}, @@ -156,7 +156,7 @@ const Map> _fieldRuleMap = { 'TypeParameterType': {'parameter': FieldRule(isDeclaration: false)}, 'StructuralParameterType': {'parameter': FieldRule(isDeclaration: false)}, 'SyntheticVariable': { - 'variableInitialization': FieldRule(isDeclaration: false), + 'variableDeclaration': FieldRule(isDeclaration: false), '_context': FieldRule(name: 'context'), }, 'LegacyVariable': {'_name': FieldRule(name: 'name')}, @@ -175,7 +175,6 @@ const Map> _fieldRuleMap = { 'thisVariable': FieldRule(isDeclaration: false), }, 'NominalParameter': {'_variance': FieldRule(name: 'variance')}, - 'VariableInitialization': {'variable': FieldRule(isDeclaration: false)}, }; /// Data that determines exceptions to how fields are used. diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 9c80e1039f1..5c92f36a175 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -2099,8 +2099,7 @@ class BinaryBuilder { Initializer _readLocalInitializer() { int offset = readOffset(); - return new LocalInitializer(readAndPushVariableDeclaration()) - ..fileOffset = offset; + return new LocalInitializer(readAndPushVariable())..fileOffset = offset; } Initializer _readAssertInitializer() { @@ -2124,8 +2123,8 @@ class BinaryBuilder { readUInt30(); // total parameter count. int requiredParameterCount = readUInt30(); int variableStackHeight = variableStack.length; - List positional = readAndPushVariableDeclarationList(); - List named = readAndPushVariableDeclarationList(); + List positional = readAndPushVariableList(); + List named = readAndPushVariableList(); DartType returnType = readDartType(); DartType? futureValueType = readDartTypeOption(); RedirectingFactoryTarget? redirectingFactoryTarget; @@ -3346,7 +3345,7 @@ class BinaryBuilder { InvalidPattern _readInvalidPattern() { int fileOffset = readOffset(); Expression invalidExpression = readExpression(); - List declaredVariables = readAndPushVariableDeclarationList(); + List declaredVariables = readAndPushVariableList(); return InvalidPattern( invalidExpression, declaredVariables: declaredVariables, @@ -3824,7 +3823,7 @@ class BinaryBuilder { Statement _readForStatement() { int variableStackHeight = variableStack.length; int offset = readOffset(); - List variables = readAndPushVariableStatementList(); + List variables = readAndPushVariableDeclarationList(); Expression? condition = readExpressionOption(); List updates = readExpressionList(); Statement body = readStatement(); @@ -3838,7 +3837,7 @@ class BinaryBuilder { int variableStackHeight = variableStack.length; int offset = readOffset(); int bodyOffset = readOffset(); - Variable variable = readAndPushVariableDeclaration(); + Variable variable = readAndPushVariable(); Expression iterable = readExpression(); Statement body = readStatement(); variableStack.length = variableStackHeight; @@ -3931,7 +3930,9 @@ class BinaryBuilder { VariableStatement _readVariableStatement() { Variable variable = _readVariableDeclaration(); - return new VariableStatement(variable)..fileOffset = variable.fileOffset; + return new VariableStatement( + VariableDeclaration(variable)..fileOffset = variable.fileOffset, + )..fileOffset = variable.fileOffset; } Variable _readVariableDeclaration() { @@ -3980,8 +3981,8 @@ class BinaryBuilder { int variableStackHeight = variableStack.length; int offset = readOffset(); DartType guard = readDartType(); - Variable? exception = readAndPushVariableDeclarationOption(); - Variable? stackTrace = readAndPushVariableDeclarationOption(); + Variable? exception = readAndPushVariableOption(); + Variable? stackTrace = readAndPushVariableOption(); Statement body = readStatement(); variableStack.length = variableStackHeight; return new Catch(exception, body, guard: guard, stackTrace: stackTrace) @@ -4430,17 +4431,17 @@ class BinaryBuilder { return new NamedExpression(readStringReference(), readExpression()); } - List readAndPushVariableStatementList() { - List list = readAndPushVariableDeclarationList(); + List readAndPushVariableDeclarationList() { + List list = readAndPushVariableList(); return new List.generate( list.length, (int index) => - new VariableStatement(list[index]) + new VariableDeclaration(list[index]) ..fileOffset = list[index].fileOffset, ); } - List readAndPushVariableDeclarationList() { + List readAndPushVariableList() { int length = readUInt30(); if (!useGrowableLists && length == 0) { // When lists don't have to be growable anyway, we might as well use an @@ -4449,16 +4450,16 @@ class BinaryBuilder { } return new List.generate( length, - (_) => readAndPushVariableDeclaration(), + (_) => readAndPushVariable(), growable: useGrowableLists, ); } - Variable? readAndPushVariableDeclarationOption() { - return readAndCheckOptionTag() ? readAndPushVariableDeclaration() : null; + Variable? readAndPushVariableOption() { + return readAndCheckOptionTag() ? readAndPushVariable() : null; } - Variable readAndPushVariableDeclaration() { + Variable readAndPushVariable() { Variable variable = readVariableDeclaration(); variableStack.add(variable); return variable; diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 534507b533f..0f330a753ed 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -1553,7 +1553,7 @@ class BinaryPrinter void visitLocalInitializer(LocalInitializer node) { writeByte(Tag.LocalInitializer); writeOffset(node.fileOffset); - writeVariableDeclaration(node.variable); + writeVariable(node.variable); } @override @@ -1579,8 +1579,8 @@ class BinaryPrinter writeNodeList(node.typeParameters); writeUInt30(node.positionalParameters.length + node.namedParameters.length); writeUInt30(node.requiredParameterCount); - writeVariableDeclarationList(node.positionalParameters); - writeVariableDeclarationList(node.namedParameters); + writeVariableList(node.positionalParameters); + writeVariableList(node.namedParameters); writeNode(node.returnType); writeOptionalNode(node.emittedValueType); RedirectingFactoryTarget? redirectingFactoryTarget = @@ -2214,7 +2214,7 @@ class BinaryPrinter VariableIndexer variableIndexer = _variableIndexer ??= _newVariableIndexer(); variableIndexer.pushScope(); - writeVariableDeclaration(node.variable); + writeVariable(node.variable); writeNode(node.body); variableIndexer.popScope(); } @@ -2359,7 +2359,7 @@ class BinaryPrinter variableIndexer.pushScope(); writeByte(Tag.ForStatement); writeOffset(node.fileOffset); - writeVariableStatementList(node.variables); + writeVariableDeclarationList(node.variables); writeOptionalNode(node.condition); writeNodeList(node.updates); writeNode(node.body); @@ -2374,7 +2374,7 @@ class BinaryPrinter writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); writeOffset(node.fileOffset); writeOffset(node.bodyOffset); - writeVariableDeclaration(node.variable); + writeVariable(node.variable); writeNode(node.iterable); writeNode(node.body); variableIndexer.popScope(); @@ -2453,8 +2453,8 @@ class BinaryPrinter variableIndexer.pushScope(); writeOffset(node.fileOffset); writeNode(node.guard); - writeOptionalVariableDeclaration(node.exception); - writeOptionalVariableDeclaration(node.stackTrace); + writeOptionalVariable(node.exception); + writeOptionalVariable(node.stackTrace); writeNode(node.body); variableIndexer.popScope(); } @@ -2478,14 +2478,23 @@ class BinaryPrinter @override void visitVariable(Variable node) { writeByte(Tag.VariableDeclaration); + writeVariable(node); + } + + @override + void visitVariableDeclaration(VariableDeclaration node) { writeVariableDeclaration(node); } void writeVariableStatement(VariableStatement node) { - writeVariableDeclaration(node.variable); + writeVariableDeclaration(node.declaration); } - void writeVariableDeclaration(Variable node) { + void writeVariableDeclaration(VariableDeclaration node) { + writeVariable(node.variable); + } + + void writeVariable(Variable node) { if (_metadataSubsections != null) { _writeNodeMetadata(node); } @@ -2502,20 +2511,20 @@ class BinaryPrinter (_variableIndexer ??= _newVariableIndexer()).declare(node); } - void writeVariableStatementList(List nodes) { - writeList(nodes, writeVariableStatement); - } - - void writeVariableDeclarationList(List nodes) { + void writeVariableDeclarationList(List nodes) { writeList(nodes, writeVariableDeclaration); } - void writeOptionalVariableDeclaration(Variable? node) { + void writeVariableList(List nodes) { + writeList(nodes, writeVariable); + } + + void writeOptionalVariable(Variable? node) { if (node == null) { writeByte(Tag.Nothing); } else { writeByte(Tag.Something); - writeVariableDeclaration(node); + writeVariable(node); } } @@ -2523,7 +2532,7 @@ class BinaryPrinter void visitFunctionDeclaration(FunctionDeclaration node) { writeByte(Tag.FunctionDeclaration); writeOffset(node.fileOffset); - writeVariableDeclaration(node.variable); + writeVariable(node.variable); writeUInt30(node.id.toInt()); writeFunctionNode(node.function); } @@ -2846,7 +2855,7 @@ class BinaryPrinter writeByte(Tag.InvalidPattern); writeOffset(node.fileOffset); writeNode(node.invalidExpression); - writeVariableDeclarationList(node.declaredVariables); + writeVariableList(node.declaredVariables); } @override @@ -2967,7 +2976,7 @@ class BinaryPrinter @override void visitPatternSwitchCase(PatternSwitchCase node) { - writeVariableDeclarationList(node.jointVariables); + writeVariableList(node.jointVariables); int length = node.patternGuards.length; writeUInt30(length); for (int i = 0; i < length; ++i) { @@ -3051,7 +3060,7 @@ class BinaryPrinter writeByte(Tag.VariablePattern); writeOffset(node.fileOffset); writeOptionalNode(node.type); - writeVariableDeclaration(node.variable); + writeVariable(node.variable); writeOptionalNode(node.matchedValueType); } diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart index d7d8bc0885c..aa80e2da5ce 100644 --- a/pkg/kernel/lib/clone.dart +++ b/pkg/kernel/lib/clone.dart @@ -603,7 +603,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), @@ -790,8 +790,14 @@ class CloneVisitorNotMembers } @override - TreeNode visitLegacyVariableStatement(VariableStatement node) { - return new LegacyVariableStatement(clone(node.variable)) + TreeNode visitVariableStatement(VariableStatement node) { + return new VariableStatement(clone(node.declaration)) + ..fileOffset = _cloneFileOffset(node.fileOffset); + } + + @override + TreeNode visitVariableDeclaration(VariableDeclaration node) { + return new VariableDeclaration(clone(node.variable)) ..fileOffset = _cloneFileOffset(node.fileOffset); } @@ -816,12 +822,6 @@ class CloneVisitorNotMembers : const []; } - @override - TreeNode visitVariableInitialization(VariableInitialization node) { - return new VariableInitialization(variable: clone(node.variable)) - ..flags = node.flags; - } - @override TreeNode visitFunctionDeclaration(FunctionDeclaration node) { Variable newVariable = clone(node.variable); diff --git a/pkg/kernel/lib/src/ast/components.dart b/pkg/kernel/lib/src/ast/components.dart index 49557bb614a..854186dd56b 100644 --- a/pkg/kernel/lib/src/ast/components.dart +++ b/pkg/kernel/lib/src/ast/components.dart @@ -369,7 +369,9 @@ abstract class MetadataRepository { return !(node is MapLiteralEntry || node is Catch || (node is Block && node.parent is BlockExpression) || - // TODO(johnniwinther): Support - node is LegacyVariableStatement); + // TODO(johnniwinther): Support [VariableStatement]. + node is VariableStatement || + // TODO(johnniwinther): Support [VariableDeclaration]. + node is VariableDeclaration); } } diff --git a/pkg/kernel/lib/src/ast/dummies.dart b/pkg/kernel/lib/src/ast/dummies.dart index 6207aa4b6c2..f8cc28f84ff 100644 --- a/pkg/kernel/lib/src/ast/dummies.dart +++ b/pkg/kernel/lib/src/ast/dummies.dart @@ -16,7 +16,7 @@ final List emptyListOfNamedExpression = List.filled( /// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828. final List emptyListOfVariableDeclaration = List.filled( 0, - dummyVariableDeclaration, + dummyVariable, growable: false, ); @@ -481,15 +481,21 @@ final VariableStatement dummyVariableStatement = new VariableStatement( dummyVariableDeclaration, ); +/// Non-nullable [VariableDeclaration] 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 VariableDeclaration dummyVariableDeclaration = new VariableDeclaration( + dummyVariable, +); + /// Non-nullable [Variable] 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 Variable dummyVariableDeclaration = new Variable( - null, - isSynthesized: true, -); +final Variable dummyVariable = new Variable(null, isSynthesized: true); /// Non-nullable [CatchVariable] dummy value. /// diff --git a/pkg/kernel/lib/src/ast/functions.dart b/pkg/kernel/lib/src/ast/functions.dart index 0cb22c3f0a3..729b21701db 100644 --- a/pkg/kernel/lib/src/ast/functions.dart +++ b/pkg/kernel/lib/src/ast/functions.dart @@ -275,8 +275,8 @@ class FunctionNode extends TreeNode implements ScopeProvider, ContextConsumer { @override void transformOrRemoveChildren(RemovingTransformer v) { v.transformTypeParameterList(typeParameters, this); - v.transformVariableDeclarationList(positionalParameters, this); - v.transformVariableDeclarationList(namedParameters, this); + v.transformVariableList(positionalParameters, this); + v.transformVariableList(namedParameters, this); returnType = v.visitDartType(returnType, cannotRemoveSentinel); if (emittedValueType != null) { emittedValueType = v.visitDartType( diff --git a/pkg/kernel/lib/src/ast/patterns.dart b/pkg/kernel/lib/src/ast/patterns.dart index 6de14f3f202..0ebddca6825 100644 --- a/pkg/kernel/lib/src/ast/patterns.dart +++ b/pkg/kernel/lib/src/ast/patterns.dart @@ -1465,7 +1465,7 @@ class InvalidPattern extends Pattern { @override void transformOrRemoveChildren(RemovingTransformer v) { invalidExpression = v.transform(invalidExpression)..parent = this; - v.transformVariableDeclarationList(declaredVariables, this); + v.transformVariableList(declaredVariables, this); } @override diff --git a/pkg/kernel/lib/src/ast/statements.dart b/pkg/kernel/lib/src/ast/statements.dart index 54a65006606..b31a005212e 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.transformStatementList(variables, this); + v.transformVariableDeclarationList(variables, this); if (condition != null) { condition = v.transformOrRemoveExpression(condition!); condition?.parent = this; @@ -1276,11 +1276,11 @@ class Catch extends TreeNode implements ScopeProvider { void transformOrRemoveChildren(RemovingTransformer v) { guard = v.visitDartType(guard, cannotRemoveSentinel); if (exception != null) { - exception = v.transformOrRemoveVariableDeclaration(exception!); + exception = v.transformOrRemoveVariable(exception!); exception?.parent = this; } if (stackTrace != null) { - stackTrace = v.transformOrRemoveVariableDeclaration(stackTrace!); + stackTrace = v.transformOrRemoveVariable(stackTrace!); stackTrace?.parent = this; } body = v.transform(body); @@ -1460,43 +1460,34 @@ class YieldStatement extends Statement { } /// Declaration of a local variable. -abstract class VariableStatement extends Statement { +class VariableStatement extends Statement { /// The declared variable. - abstract final Variable variable; + VariableDeclaration declaration; - factory VariableStatement(Variable variable) = LegacyVariableStatement; -} - -/// Declaration of a local variable. -class LegacyVariableStatement extends Statement implements VariableStatement { - /// The declared variable. - @override - Variable variable; - - LegacyVariableStatement(this.variable) { - variable.parent = this; + VariableStatement(this.declaration) { + declaration.parent = this; } @override - R accept(StatementVisitor v) => v.visitLegacyVariableStatement(this); + R accept(StatementVisitor v) => v.visitVariableStatement(this); @override R accept1(StatementVisitor1 v, A arg) => - v.visitLegacyVariableStatement(this, arg); + v.visitVariableStatement(this, arg); @override void visitChildren(Visitor v) { - variable.accept(v); + declaration.accept(v); } @override void transformChildren(Transformer v) { - variable = v.transform(variable)..parent = this; + declaration = v.transform(declaration)..parent = this; } @override void transformOrRemoveChildren(RemovingTransformer v) { - variable = v.transformOrRemove(variable, cannotRemoveSentinel)! + declaration = v.transformOrRemove(declaration, cannotRemoveSentinel)! ..parent = this; } @@ -1509,7 +1500,7 @@ class LegacyVariableStatement extends Statement implements VariableStatement { @override void toTextInternal(AstPrinter printer) { - printer.writeVariableInitialization(variable); + printer.writeVariableDeclaration(declaration); printer.write(';'); } } @@ -1576,82 +1567,3 @@ class FunctionDeclaration extends Statement implements LocalFunction { } } } - -class VariableInitialization extends Statement - implements VariableStatement, ContextConsumer { - @override - Variable variable; - - /// Contexts of the variables captured by the late variable initializer. - /// - /// If [variable] isn't `late`, [capturedContexts] should be `null`. - @override - List? capturedContexts; - - VariableInitialization({ - required this.variable, - bool hasDeclaredInitializer = false, - }) { - variable.variableInitialization = this; - this.hasDeclaredInitializer = hasDeclaredInitializer; - } - - static const int FlagHasDeclaredInitializer = 1 << 0; - static const int FlagErroneouslyInitialized = 1 << 1; - - int flags = 0; - - bool get hasDeclaredInitializer => flags & FlagHasDeclaredInitializer != 0; - - void set hasDeclaredInitializer(bool value) { - flags = value - ? (flags | FlagHasDeclaredInitializer) - : (flags & ~FlagHasDeclaredInitializer); - } - - bool get isErroneouslyInitialized => flags & FlagErroneouslyInitialized != 0; - - void set isErroneouslyInitialized(bool value) { - flags = value - ? (flags | FlagErroneouslyInitialized) - : (flags & ~FlagErroneouslyInitialized); - } - - @override - R accept(StatementVisitor v) => v.visitVariableInitialization(this); - - @override - R accept1(StatementVisitor1 v, A arg) => - v.visitVariableInitialization(this, arg); - - @override - void transformChildren(Transformer v) { - variable = v.transform(variable)..parent = this; - } - - @override - void transformOrRemoveChildren(RemovingTransformer v) { - variable = v.transformOrRemove(variable, cannotRemoveSentinel)! - ..parent = this; - } - - @override - void visitChildren(Visitor v) { - variable.accept(v); - } - - @override - String toString() { - return "VariableInitialization(${toStringInternal()})"; - } - - @override - void toTextInternal(AstPrinter printer) { - printer.write(printer.getVariableName(variable)); - if (variable.initializer case var initializer?) { - printer.write(' := '); - printer.writeExpression(initializer); - } - printer.write(';'); - } -} diff --git a/pkg/kernel/lib/src/ast/variables.dart b/pkg/kernel/lib/src/ast/variables.dart index 66a67fe9231..3f38f56d1a7 100644 --- a/pkg/kernel/lib/src/ast/variables.dart +++ b/pkg/kernel/lib/src/ast/variables.dart @@ -30,7 +30,7 @@ sealed class VariableBase extends TreeNode implements Annotatable { abstract interface class IVariable implements TreeNode, Annotatable { abstract DartType type; abstract String? cosmeticName; - abstract VariableInitialization? variableInitialization; + abstract VariableDeclaration? variableDeclaration; abstract Expression? initializer; abstract bool isFinal; abstract bool isConst; @@ -83,11 +83,11 @@ sealed class Variable extends VariableBase @override abstract DartType type; - /// Initialization node for the variable, if available. + /// Declaration node for the variable, if available. @override - abstract VariableInitialization? variableInitialization; + abstract VariableDeclaration? variableDeclaration; - /// Derived from [variableInitialization], if available. + /// Derived from [variableDeclaration], if available. @override abstract Expression? initializer; @@ -629,14 +629,12 @@ class LegacyVariable extends TreeNode implements Variable, Annotatable { } @override - VariableInitialization? get variableInitialization { - throw new UnsupportedError("${this.runtimeType}.variableInitialization"); + VariableDeclaration? get variableDeclaration { + throw new UnsupportedError("${this.runtimeType}.variableDeclaration"); } @override - void set variableInitialization(VariableInitialization? value) { - throw new UnsupportedError("${this.runtimeType}.variableInitialization"); - } + void set variableDeclaration(VariableDeclaration? value) {} @override // TODO(62620): Conforming to [Variable] interface. Remove this. @@ -716,7 +714,7 @@ class LocalVariable extends Variable { DartType type; @override - VariableInitialization? variableInitialization; + VariableDeclaration? variableDeclaration; @override List annotations = const []; @@ -734,6 +732,7 @@ class LocalVariable extends Variable { bool isConst = false, bool isLate = false, bool isWildcard = false, + bool hasDeclaredInitializer = false, this.initializer, }) : type = type ?? const DynamicType(), super.empty() { @@ -741,6 +740,7 @@ class LocalVariable extends Variable { this.isConst = isConst; this.isLate = isLate; this.isWildcard = isWildcard; + this.hasDeclaredInitializer = hasDeclaredInitializer; this.initializer?.parent = this; } @@ -773,6 +773,8 @@ class LocalVariable extends Variable { static const int FlagLate = 1 << 3; static const int FlagLowered = 1 << 4; static const int FlagHoisted = 1 << 5; + static const int FlagHasDeclaredInitializer = 1 << 6; + static const int FlagErroneouslyInitialized = 1 << 7; @override bool get isFinal => flags & FlagFinal != 0; @@ -843,22 +845,23 @@ class LocalVariable extends Variable { } @override - bool get isErroneouslyInitialized { - throw new UnsupportedError("${this.runtimeType}"); - } + bool get isErroneouslyInitialized => flags & FlagErroneouslyInitialized != 0; @override void set isErroneouslyInitialized(bool value) { - throw new UnsupportedError("${this.runtimeType}"); + flags = value + ? (flags | FlagErroneouslyInitialized) + : (flags & ~FlagErroneouslyInitialized); } @override - bool get hasDeclaredInitializer => - variableInitialization!.hasDeclaredInitializer; + bool get hasDeclaredInitializer => flags & FlagHasDeclaredInitializer != 0; @override void set hasDeclaredInitializer(bool value) { - throw new UnsupportedError("${this.runtimeType}"); + flags = value + ? (flags | FlagHasDeclaredInitializer) + : (flags & ~FlagHasDeclaredInitializer); } @override @@ -1086,12 +1089,12 @@ class CatchVariable extends Variable { } @override - VariableInitialization? get variableInitialization { + VariableDeclaration? get variableDeclaration { throw new UnsupportedError("${this.runtimeType}.variableInitialization"); } @override - void set variableInitialization(VariableInitialization? value) { + void set variableDeclaration(VariableDeclaration? value) { throw new UnsupportedError("${this.runtimeType}.variableInitialization="); } @@ -1394,10 +1397,10 @@ sealed class FunctionParameter extends Variable { /// Function parameters don't have initializers, only default values. @override - VariableInitialization? get variableInitialization => null; + VariableDeclaration? get variableDeclaration => null; @override - void set variableInitialization(VariableInitialization? value) {} + void set variableDeclaration(VariableDeclaration? value) {} @override Expression? get initializer => defaultValue; @@ -1896,10 +1899,10 @@ class ThisVariable extends Variable { void set cosmeticName(String? value) {} @override - VariableInitialization? get variableInitialization => null; + VariableDeclaration? get variableDeclaration => null; @override - void set variableInitialization(VariableInitialization? value) {} + void set variableDeclaration(VariableDeclaration? value) {} @override DartType type; @@ -2200,7 +2203,7 @@ class SyntheticVariable extends Variable { DartType type; @override - VariableInitialization? variableInitialization; + VariableDeclaration? variableDeclaration; // TODO(cstefantsova): Consider a throwing implementation instead. @override @@ -2580,3 +2583,54 @@ sealed class ContextConsumer implements TreeNode { /// Contexts the variables captured by [ContextConsumer] are from. abstract List? capturedContexts; } + +/// Declaration of a variable with an initial value. +class VariableDeclaration extends TreeNode implements ContextConsumer { + /// The declared variable. + Variable variable; + + /// Contexts of the variables captured by the late variable initializer. + /// + /// If [variable] isn't `late`, [capturedContexts] should be `null`. + @override + List? capturedContexts; + + VariableDeclaration(this.variable) { + variable.parent = this; + variable.variableDeclaration = this; + } + + /// The declared initializer, if any. + // TODO(johnniwinther): VariableDeclaration should own the initializer. + Expression? get initializer => variable.initializer; + + @override + R accept(TreeVisitor v) => v.visitVariableDeclaration(this); + + @override + R accept1(TreeVisitor1 v, A arg) => + v.visitVariableDeclaration(this, arg); + + @override + void toTextInternal(AstPrinter printer) { + variable.toTextInternal(printer); + } + + @override + void transformChildren(Transformer v) { + variable = v.transform(variable)..parent = this; + } + + @override + void transformOrRemoveChildren(RemovingTransformer v) { + variable = v.transform(variable)..parent = this; + } + + @override + void visitChildren(Visitor v) { + variable.accept(v); + } + + @override + String toString() => 'VariableDeclaration(${toStringInternal()}'; +} diff --git a/pkg/kernel/lib/src/coverage.dart b/pkg/kernel/lib/src/coverage.dart index 0d344e566fc..c9022427c74 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 visitLegacyVariableStatement(LegacyVariableStatement node) { - visited.add(StatementKind.LegacyVariableStatement); + void visitVariableStatement(VariableStatement node) { + visited.add(StatementKind.VariableStatement); node.visitChildren(this); } @@ -967,12 +967,6 @@ class CoverageVisitor implements Visitor { node.visitChildren(this); } - @override - void visitVariableInitialization(VariableInitialization node) { - visited.add(StatementKind.VariableInitialization); - node.visitChildren(this); - } - @override void visitSwitchExpressionCase(SwitchExpressionCase node) { visited.add(NodeKind.SwitchExpressionCase); @@ -1039,6 +1033,12 @@ class CoverageVisitor implements Visitor { node.visitChildren(this); } + @override + void visitVariableDeclaration(VariableDeclaration node) { + visited.add(NodeKind.VariableDeclaration); + node.visitChildren(this); + } + @override void visitName(Name node) { visited.add(NodeKind.Name); @@ -1349,6 +1349,7 @@ enum NodeKind { SwitchExpressionCase, TypeVariable, Typedef, + VariableDeclaration, } enum MemberKind { Constructor, Field, Procedure } @@ -1469,14 +1470,13 @@ enum StatementKind { IfCaseStatement, IfStatement, LabeledStatement, - LegacyVariableStatement, PatternSwitchStatement, PatternVariableDeclaration, ReturnStatement, SwitchStatement, TryCatch, TryFinally, - VariableInitialization, + VariableStatement, WhileStatement, YieldStatement, } diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart index e8d7e999837..84e8d915583 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 visitLegacyVariableStatement(LegacyVariableStatement node, Node other) { - return strategy.checkLegacyVariableStatement(this, node, other); + bool visitVariableStatement(VariableStatement node, Node other) { + return strategy.checkVariableStatement(this, node, other); } @override @@ -845,11 +845,6 @@ class EquivalenceVisitor implements Visitor1 { return strategy.checkFunctionDeclaration(this, node, other); } - @override - bool visitVariableInitialization(VariableInitialization node, Node other) { - return strategy.checkVariableInitialization(this, node, other); - } - @override bool visitSwitchExpressionCase(SwitchExpressionCase node, Node other) { return strategy.checkSwitchExpressionCase(this, node, other); @@ -905,6 +900,11 @@ class EquivalenceVisitor implements Visitor1 { return strategy.checkLegacyVariable(this, node, other); } + @override + bool visitVariableDeclaration(VariableDeclaration node, Node other) { + return strategy.checkVariableDeclaration(this, node, other); + } + @override bool visitName(Name node, Node other) { return strategy.checkName(this, node, other); @@ -5909,20 +5909,20 @@ class EquivalenceStrategy { return result; } - bool checkLegacyVariableStatement( + bool checkVariableStatement( EquivalenceVisitor visitor, - LegacyVariableStatement? node, + VariableStatement? node, Object? other, ) { if (identical(node, other)) return true; - if (node is! LegacyVariableStatement) return false; - if (other is! LegacyVariableStatement) return false; + if (node is! VariableStatement) return false; + if (other is! VariableStatement) return false; visitor.pushNodeState(node, other); bool result = true; - if (!checkLegacyVariableStatement_variable(visitor, node, other)) { + if (!checkVariableStatement_declaration(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkLegacyVariableStatement_fileOffset(visitor, node, other)) { + if (!checkVariableStatement_fileOffset(visitor, node, other)) { result = visitor.resultOnInequivalence; } visitor.popState(); @@ -5952,32 +5952,6 @@ class EquivalenceStrategy { return result; } - bool checkVariableInitialization( - EquivalenceVisitor visitor, - VariableInitialization? node, - Object? other, - ) { - if (identical(node, other)) return true; - if (node is! VariableInitialization) return false; - if (other is! VariableInitialization) return false; - visitor.pushNodeState(node, other); - bool result = true; - if (!checkVariableInitialization_variable(visitor, node, other)) { - result = visitor.resultOnInequivalence; - } - if (!checkVariableInitialization_capturedContexts(visitor, node, other)) { - result = visitor.resultOnInequivalence; - } - if (!checkVariableInitialization_flags(visitor, node, other)) { - result = visitor.resultOnInequivalence; - } - if (!checkVariableInitialization_fileOffset(visitor, node, other)) { - result = visitor.resultOnInequivalence; - } - visitor.popState(); - return result; - } - bool checkSwitchExpressionCase( EquivalenceVisitor visitor, SwitchExpressionCase? node, @@ -6112,7 +6086,7 @@ class EquivalenceStrategy { if (!checkLocalVariable_type(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkLocalVariable_variableInitialization(visitor, node, other)) { + if (!checkLocalVariable_variableDeclaration(visitor, node, other)) { result = visitor.resultOnInequivalence; } if (!checkLocalVariable_annotations(visitor, node, other)) { @@ -6311,7 +6285,7 @@ class EquivalenceStrategy { if (!checkSyntheticVariable_type(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkSyntheticVariable_variableInitialization(visitor, node, other)) { + if (!checkSyntheticVariable_variableDeclaration(visitor, node, other)) { result = visitor.resultOnInequivalence; } if (!checkSyntheticVariable_annotations(visitor, node, other)) { @@ -6380,6 +6354,29 @@ class EquivalenceStrategy { return result; } + bool checkVariableDeclaration( + EquivalenceVisitor visitor, + VariableDeclaration? node, + Object? other, + ) { + if (identical(node, other)) return true; + if (node is! VariableDeclaration) return false; + if (other is! VariableDeclaration) return false; + visitor.pushNodeState(node, other); + bool result = true; + if (!checkVariableDeclaration_variable(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkVariableDeclaration_capturedContexts(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkVariableDeclaration_fileOffset(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + visitor.popState(); + return result; + } + bool checkName(EquivalenceVisitor visitor, Name? node, Object? other) { if (identical(node, other)) return true; if (node is! Name) return false; @@ -13278,18 +13275,22 @@ class EquivalenceStrategy { return checkStatement_fileOffset(visitor, node, other); } - bool checkLegacyVariableStatement_variable( + bool checkVariableStatement_declaration( EquivalenceVisitor visitor, - LegacyVariableStatement node, - LegacyVariableStatement other, + VariableStatement node, + VariableStatement other, ) { - return visitor.checkNodes(node.variable, other.variable, 'variable'); + return visitor.checkNodes( + node.declaration, + other.declaration, + 'declaration', + ); } - bool checkLegacyVariableStatement_fileOffset( + bool checkVariableStatement_fileOffset( EquivalenceVisitor visitor, - LegacyVariableStatement node, - LegacyVariableStatement other, + VariableStatement node, + VariableStatement other, ) { return checkStatement_fileOffset(visitor, node, other); } @@ -13318,45 +13319,6 @@ class EquivalenceStrategy { return checkStatement_fileOffset(visitor, node, other); } - bool checkVariableInitialization_variable( - EquivalenceVisitor visitor, - VariableInitialization node, - VariableInitialization other, - ) { - return visitor.checkNodes(node.variable, other.variable, 'variable'); - } - - bool checkVariableInitialization_capturedContexts( - EquivalenceVisitor visitor, - VariableInitialization node, - VariableInitialization other, - ) { - return visitor.checkLists(node.capturedContexts, other.capturedContexts, ( - a, - b, - _, - ) { - if (identical(a, b)) return true; - return checkVariableContext(visitor, a, b); - }, 'capturedContexts'); - } - - bool checkVariableInitialization_flags( - EquivalenceVisitor visitor, - VariableInitialization node, - VariableInitialization other, - ) { - return visitor.checkValues(node.flags, other.flags, 'flags'); - } - - bool checkVariableInitialization_fileOffset( - EquivalenceVisitor visitor, - VariableInitialization node, - VariableInitialization other, - ) { - return checkStatement_fileOffset(visitor, node, other); - } - bool checkSwitchExpressionCase_patternGuard( EquivalenceVisitor visitor, SwitchExpressionCase node, @@ -13585,15 +13547,15 @@ class EquivalenceStrategy { return visitor.checkNodes(node.type, other.type, 'type'); } - bool checkLocalVariable_variableInitialization( + bool checkLocalVariable_variableDeclaration( EquivalenceVisitor visitor, LocalVariable node, LocalVariable other, ) { return visitor.checkNodes( - node.variableInitialization, - other.variableInitialization, - 'variableInitialization', + node.variableDeclaration, + other.variableDeclaration, + 'variableDeclaration', ); } @@ -14067,15 +14029,15 @@ class EquivalenceStrategy { return visitor.checkNodes(node.type, other.type, 'type'); } - bool checkSyntheticVariable_variableInitialization( + bool checkSyntheticVariable_variableDeclaration( EquivalenceVisitor visitor, SyntheticVariable node, SyntheticVariable other, ) { return visitor.checkNodes( - node.variableInitialization, - other.variableInitialization, - 'variableInitialization', + node.variableDeclaration, + other.variableDeclaration, + 'variableDeclaration', ); } @@ -14234,6 +14196,37 @@ class EquivalenceStrategy { return checkTreeNode_fileOffset(visitor, node, other); } + bool checkVariableDeclaration_variable( + EquivalenceVisitor visitor, + VariableDeclaration node, + VariableDeclaration other, + ) { + return visitor.checkNodes(node.variable, other.variable, 'variable'); + } + + bool checkVariableDeclaration_capturedContexts( + EquivalenceVisitor visitor, + VariableDeclaration node, + VariableDeclaration other, + ) { + return visitor.checkLists(node.capturedContexts, other.capturedContexts, ( + a, + b, + _, + ) { + if (identical(a, b)) return true; + return checkVariableContext(visitor, a, b); + }, 'capturedContexts'); + } + + bool checkVariableDeclaration_fileOffset( + EquivalenceVisitor visitor, + VariableDeclaration node, + VariableDeclaration other, + ) { + return checkTreeNode_fileOffset(visitor, node, other); + } + bool checkName_text(EquivalenceVisitor visitor, Name node, Name other) { return visitor.checkValues(node.text, other.text, 'text'); } diff --git a/pkg/kernel/lib/src/node_creator.dart b/pkg/kernel/lib/src/node_creator.dart index 9ac6b8b3281..cef3b04c304 100644 --- a/pkg/kernel/lib/src/node_creator.dart +++ b/pkg/kernel/lib/src/node_creator.dart @@ -82,9 +82,7 @@ class NodeCreator { Iterable variables = VariableKind.values, Iterable nodes = NodeKind.values, }) : _pendingExpressions = _createPending(expressions, {}), - _pendingStatements = _createPending(statements, { - StatementKind.VariableInitialization, - }), + _pendingStatements = _createPending(statements), _pendingDartTypes = _createPending(dartTypes, { DartTypeKind.FunctionTypeParameterType, DartTypeKind.ClassTypeParameterType, @@ -134,7 +132,7 @@ class NodeCreator { _neededLabeledStatements.clear(); statement = Block([ for (Variable neededVariable in _neededVariables) - VariableStatement(neededVariable), + VariableStatement(VariableDeclaration(neededVariable)), ..._neededFunctionDeclarations, statement, ]); @@ -385,6 +383,7 @@ class NodeCreator { case NodeKind.SwitchExpressionCase: case NodeKind.TypeVariable: case NodeKind.LegacyVariable: + case NodeKind.VariableDeclaration: throw new UnimplementedError('Expected in body node $kind.'); case NodeKind.Class: _needLibrary().addClass(node as Class); @@ -1468,15 +1467,15 @@ class NodeCreator { ForStatement([], null, [], _createStatement()) ..fileOffset = _needFileOffset(), () => ForStatement( - [VariableStatement(_createVariable())], + [VariableDeclaration(_createVariable())], _createExpression(), [_createExpression()], _createStatement(), )..fileOffset = _needFileOffset(), () => ForStatement( [ - VariableStatement(_createVariable()), - VariableStatement(_createVariable()), + VariableDeclaration(_createVariable()), + VariableDeclaration(_createVariable()), ], _createExpression(), [_createExpression(), _createExpression()], @@ -1536,18 +1535,23 @@ class NodeCreator { case StatementKind.TryFinally: return TryFinally(_createStatement(), _createStatement()) ..fileOffset = _needFileOffset(); - case StatementKind.LegacyVariableStatement: + case StatementKind.VariableStatement: return _createOneOf(_pendingStatements, kind, index, [ - () => - VariableStatement(Variable('foo')..fileOffset = _needFileOffset()) - ..fileOffset = _needFileOffset(), () => VariableStatement( - Variable('foo', initializer: _createExpression()) + VariableDeclaration(Variable('foo')..fileOffset = _needFileOffset()) ..fileOffset = _needFileOffset(), )..fileOffset = _needFileOffset(), () => VariableStatement( - Variable('foo', type: _createDartType()) - ..fileOffset = _needFileOffset(), + VariableDeclaration( + Variable('foo', initializer: _createExpression()) + ..fileOffset = _needFileOffset(), + )..fileOffset = _needFileOffset(), + )..fileOffset = _needFileOffset(), + () => VariableStatement( + VariableDeclaration( + Variable('foo', type: _createDartType()) + ..fileOffset = _needFileOffset(), + )..fileOffset = _needFileOffset(), )..fileOffset = _needFileOffset(), ]); case StatementKind.WhileStatement: @@ -1599,8 +1603,6 @@ class NodeCreator { isFinal: true, )..fileOffset = _needFileOffset(), ]); - case StatementKind.VariableInitialization: - throw new UnimplementedError("Unimplemented support for ${kind}."); } } @@ -2128,6 +2130,10 @@ class NodeCreator { _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard, _createExpression(), )..fileOffset = _needFileOffset(); + case NodeKind.VariableDeclaration: + return new VariableDeclaration( + _createNodeFromKind(NodeKind.LegacyVariable) as Variable, + ); case NodeKind.LegacyVariable: return _createOneOf(_pendingNodes, kind, index, [ () => Variable('foo')..fileOffset = _needFileOffset(), diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart index 5d5fe4d368f..5a21fa034be 100644 --- a/pkg/kernel/lib/src/printer.dart +++ b/pkg/kernel/lib/src/printer.dart @@ -509,6 +509,32 @@ class AstPrinter { node.toTextInternal(this, includeTypeArguments: includeTypeArguments); } + /// Writes the [VariableDeclaration] [node] to the printer buffer. + /// + /// If [includeModifiersAndType] is `true`, the declaration is prefixed by + /// the modifiers and declared type of the variable. Otherwise only the + /// name and the initializer, if present, are included. + /// + /// If [isLate] and [type] are provided, these values are used instead of + /// the corresponding properties on [node]. + void writeVariableDeclaration( + VariableDeclaration node, { + bool includeModifiersAndType = true, + bool? isLate, + DartType? type, + bool includeInitializer = true, + bool isImplicitlyTyped = false, + }) { + writeVariableInitialization( + node.variable, + includeModifiersAndType: includeModifiersAndType, + isLate: isLate, + type: type, + includeInitializer: includeInitializer, + isImplicitlyTyped: isImplicitlyTyped, + ); + } + /// Writes the [VariableInitialization] [node] to the printer buffer. /// /// If [includeModifiersAndType] is `true`, the declaration is prefixed by diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart index 7e9aff71511..e8a7fdb6541 100644 --- a/pkg/kernel/lib/text/ast_to_text.dart +++ b/pkg/kernel/lib/text/ast_to_text.dart @@ -984,19 +984,13 @@ class Printer extends VisitorDefault with VisitorVoidMixin { int requiredParameterCount, ) { writeSymbol('('); - writeList( - positional.take(requiredParameterCount), - writeVariableDeclaration, - ); + writeList(positional.take(requiredParameterCount), writeVariable); if (requiredParameterCount < positional.length) { if (requiredParameterCount > 0) { writeComma(); } writeSymbol('['); - writeList( - positional.skip(requiredParameterCount), - writeVariableDeclaration, - ); + writeList(positional.skip(requiredParameterCount), writeVariable); writeSymbol(']'); } if (named.isNotEmpty) { @@ -1004,7 +998,7 @@ class Printer extends VisitorDefault with VisitorVoidMixin { writeComma(); } writeSymbol('{'); - writeList(named, writeVariableDeclaration); + writeList(named, writeVariable); writeSymbol('}'); } writeSymbol(')'); @@ -1257,7 +1251,7 @@ class Printer extends VisitorDefault with VisitorVoidMixin { void writeExpressionVariable(Variable node) { // TODO(cstefantsova): Printer of the new variables is broken. if (node is LegacyVariable && node is! FunctionParameter) { - writeVariableDeclaration(node); + writeVariable(node); } else { if (showOffsets) writeWord("[${node.fileOffset}]"); if (showMetadata) writeMetadata(node); @@ -1277,8 +1271,6 @@ class Printer extends VisitorDefault with VisitorVoidMixin { writeWord('variable-declaration'); case CatchVariable(): writeWord('catch-variable'); - case VariableInitialization(): - writeWord('variable-initialization'); } // TODO(cstefantsova): Should [Variable]s have annotations? @@ -2197,7 +2189,7 @@ class Printer extends VisitorDefault with VisitorVoidMixin { @override void visitLet(Let node) { writeWord('let'); - writeVariableDeclaration(node.variable); + writeVariable(node.variable); writeSpaced('in'); writeExpression(node.body); } @@ -2586,7 +2578,7 @@ class Printer extends VisitorDefault with VisitorVoidMixin { ensureSpace(); } writeSymbol('('); - writeList(node.variables, writeVariableStatement); + writeList(node.variables, writeVariableDeclaration); writeComma(';'); Expression? condition = node.condition; if (condition != null) { @@ -2611,7 +2603,7 @@ class Printer extends VisitorDefault with VisitorVoidMixin { } writeSymbol('('); if (node.variable case LegacyVariable variable) { - writeVariableDeclaration(variable, useVarKeyword: true); + writeVariable(variable, useVarKeyword: true); } else { writeExpressionVariable(node.variable); } @@ -2757,20 +2749,12 @@ class Printer extends VisitorDefault with VisitorVoidMixin { } @override - void visitLegacyVariableStatement(LegacyVariableStatement node) { + void visitVariableStatement(VariableStatement node) { writeIndentation(); writeVariableStatement(node); endLine(';'); } - @override - void visitVariableInitialization(VariableInitialization node) { - writeIndentation(); - writeVariableStatement(node); - _writeContexts(node); - endLine(';'); - } - @override void visitFunctionDeclaration(FunctionDeclaration node) { writeAnnotationList(node.variable.annotations); @@ -2780,7 +2764,7 @@ class Printer extends VisitorDefault with VisitorVoidMixin { writeFunction(node.function, name: getVariableName(node.variable)); } - void writeVariableDeclaration(Variable node, {bool useVarKeyword = false}) { + void writeVariable(Variable node, {bool useVarKeyword = false}) { switch (node) { case LocalVariable(): case CatchVariable(): @@ -2841,12 +2825,17 @@ class Printer extends VisitorDefault with VisitorVoidMixin { } } - void writeVariableStatement(VariableStatement node) { + void writeVariableDeclaration(VariableDeclaration node) { Variable variable = node.variable; - if (node is VariableInitialization) { + if (variable is LegacyVariable) { + writeVariable(variable); + } else { if (showOffsets) writeWord("[${node.fileOffset}]"); if (showMetadata) writeMetadata(node); - writeModifier(node.isErroneouslyInitialized, 'erroneously-initialized'); + writeModifier( + variable.isErroneouslyInitialized, + 'erroneously-initialized', + ); bool hasImplicitInitializer = variable.initializer is NullLiteral || (variable.initializer is ConstantExpression && @@ -2872,11 +2861,14 @@ class Printer extends VisitorDefault with VisitorVoidMixin { writeSpaced(':='); writeExpression(initializer); } - } else { - writeVariableDeclaration(variable); + _writeContexts(node); } } + void writeVariableStatement(VariableStatement node) { + writeVariableDeclaration(node.declaration); + } + @override void visitArguments(Arguments node) { if (node.types.isNotEmpty) { @@ -2935,7 +2927,7 @@ class Printer extends VisitorDefault with VisitorVoidMixin { @override void visitLocalInitializer(LocalInitializer node) { - writeVariableDeclaration(node.variable); + writeVariable(node.variable); } @override diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart index 4c68972f2ec..8d91a04f874 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(_handleVariableStatement); + node.variables.forEach(_handleVariableDeclaration); if (node.condition != null) { node.condition = checkExpressionAndAssignability( node.condition!, @@ -1266,16 +1266,11 @@ class TypeCheckingVisitor } @override - void visitLegacyVariableStatement(LegacyVariableStatement node) { - _handleVariableStatement(node); + void visitVariableStatement(VariableStatement node) { + _handleVariableDeclaration(node.declaration); } - @override - void visitVariableInitialization(VariableInitialization node) { - _handleVariableStatement(node); - } - - void _handleVariableStatement(VariableStatement node) { + void _handleVariableDeclaration(VariableDeclaration node) { if (node.variable.initializer != null) { node.variable.initializer = checkExpressionAndAssignability( node.variable.initializer!, diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart index 4b2d8959761..3b555436105 100644 --- a/pkg/kernel/lib/verifier.dart +++ b/pkg/kernel/lib/verifier.dart @@ -1135,29 +1135,6 @@ class VerifyingVisitor extends RecursiveResultVisitor { } } - @override - void visitLegacyVariableStatement(LegacyVariableStatement node) { - _verifyVariableStatement(node); - super.visitLegacyVariableStatement(node); - } - - @override - void visitVariableInitialization(VariableInitialization node) { - _verifyVariableStatement(node); - super.visitVariableInitialization(node); - } - - void _verifyVariableStatement(VariableStatement node) { - TreeNode? parent = node.parent; - if (parent is! Block && !(parent is ForStatement && parent.body != node)) { - problem( - node, - "VariableStatement must be a direct child of a Block or ForStatement, " - "not ${parent.runtimeType}.", - ); - } - } - @override void defaultVariable(Variable node) { return _verifyVariableDeclaration(node); diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart index ea5983e62a9..dca844a0bdb 100644 --- a/pkg/kernel/lib/visitor.dart +++ b/pkg/kernel/lib/visitor.dart @@ -515,8 +515,6 @@ abstract class StatementVisitor { R visitLabeledStatement(LabeledStatement node); - R visitVariableInitialization(VariableInitialization node); - R visitBreakStatement(BreakStatement node); R visitWhileStatement(WhileStatement node); @@ -549,7 +547,7 @@ abstract class StatementVisitor { R visitFunctionDeclaration(FunctionDeclaration node); - R visitLegacyVariableStatement(LegacyVariableStatement node); + R visitVariableStatement(VariableStatement node); } /// Helper mixin for [StatementVisitor] that implements visit methods by @@ -573,9 +571,6 @@ mixin StatementVisitorDefaultMixin implements StatementVisitor { @override R visitLabeledStatement(LabeledStatement node) => defaultStatement(node); @override - R visitVariableInitialization(VariableInitialization node) => - defaultStatement(node); - @override R visitBreakStatement(BreakStatement node) => defaultStatement(node); @override R visitWhileStatement(WhileStatement node) => defaultStatement(node); @@ -612,8 +607,7 @@ mixin StatementVisitorDefaultMixin implements StatementVisitor { R visitFunctionDeclaration(FunctionDeclaration node) => defaultStatement(node); @override - R visitLegacyVariableStatement(LegacyVariableStatement node) => - defaultStatement(node); + R visitVariableStatement(VariableStatement node) => defaultStatement(node); } abstract class VariableVisitor { @@ -803,6 +797,7 @@ abstract class TreeVisitor R visitComponent(Component node); R visitTypeVariable(TypeVariable node); R visitNominalParameter(NominalParameter node); + R visitVariableDeclaration(VariableDeclaration node); } /// Helper mixin for [TreeVisitor] that implements visit methods by delegating @@ -860,6 +855,8 @@ mixin TreeVisitorDefaultMixin implements TreeVisitor { R visitTypeVariable(TypeVariable node) => defaultTreeNode(node); @override R visitNominalParameter(NominalParameter node) => visitTypeParameter(node); + @override + R visitVariableDeclaration(VariableDeclaration node) => defaultTreeNode(node); } /// Base class for implementing [TreeVisitor1] that implements visit methods @@ -926,6 +923,7 @@ abstract class TreeVisitor1 R visitComponent(Component node, A arg); R visitTypeVariable(TypeVariable node, A arg); R visitNominalParameter(NominalParameter node, A arg); + R visitVariableDeclaration(VariableDeclaration node, A arg); } /// Helper mixin for [TreeVisitor1] that implements visit methods by delegating @@ -990,6 +988,9 @@ mixin TreeVisitor1DefaultMixin implements TreeVisitor1 { @override R visitNominalParameter(NominalParameter node, A arg) => visitTypeParameter(node, arg); + @override + R visitVariableDeclaration(VariableDeclaration node, A arg) => + defaultTreeNode(node, arg); } /// Base class for implementing [TreeVisitor1] that implements visit methods @@ -2220,10 +2221,21 @@ class RemovingTransformer extends TreeVisitor1Default { /// /// This is convenience method for calling [transformOrRemove] with removal /// sentinel for [Variable] nodes. - Variable? transformOrRemoveVariableDeclaration(Variable node) { + VariableDeclaration? transformOrRemoveVariableDeclaration( + VariableDeclaration node, + ) { return transformOrRemove(node, dummyVariableDeclaration); } + /// Visits [node], returning the transformation result. Removal of [node] is + /// supported with `null` as the result. + /// + /// This is convenience method for calling [transformOrRemove] with removal + /// sentinel for [Variable] nodes. + Variable? transformOrRemoveVariable(Variable node) { + return transformOrRemove(node, dummyVariable); + } + /// Visits [node] using [removalSentinel] as the removal sentinel. /// /// If [removalSentinel] is the result of visiting [node], `null` is returned. @@ -2442,13 +2454,25 @@ class RemovingTransformer extends TreeVisitor1Default { transformList(nodes, parent, dummyTypeParameter); } + /// Transforms or removes [VariableDeclaration] nodes in [nodes] as children + /// of [parent]. + /// + /// This is convenience method for calling [transformList] with removal + /// sentinel for [VariableDeclaration] nodes. + void transformVariableDeclarationList( + List nodes, + TreeNode parent, + ) { + transformList(nodes, parent, dummyVariableDeclaration); + } + /// Transforms or removes [Variable] nodes in [nodes] as children /// of [parent]. /// /// This is convenience method for calling [transformList] with removal /// sentinel for [Variable] nodes. - void transformVariableDeclarationList(List nodes, TreeNode parent) { - transformList(nodes, parent, dummyVariableDeclaration); + void transformVariableList(List nodes, TreeNode parent) { + transformList(nodes, parent, dummyVariable); } /// Transforms or removes [T] nodes in [nodes] as children of [parent] by @@ -2844,7 +2868,6 @@ abstract class StatementVisitor1 { R visitEmptyStatement(EmptyStatement node, A arg); R visitAssertStatement(AssertStatement node, A arg); R visitLabeledStatement(LabeledStatement node, A arg); - R visitVariableInitialization(VariableInitialization node, A arg); R visitBreakStatement(BreakStatement node, A arg); R visitWhileStatement(WhileStatement node, A arg); R visitDoStatement(DoStatement node, A arg); @@ -2861,7 +2884,7 @@ abstract class StatementVisitor1 { R visitYieldStatement(YieldStatement node, A arg); R visitPatternVariableDeclaration(PatternVariableDeclaration node, A arg); R visitFunctionDeclaration(FunctionDeclaration node, A arg); - R visitLegacyVariableStatement(LegacyVariableStatement node, A arg); + R visitVariableStatement(VariableStatement node, A arg); } /// Helper mixin for [StatementVisitor1] that implements visit methods by @@ -2889,9 +2912,6 @@ mixin StatementVisitor1DefaultMixin implements StatementVisitor1 { R visitLabeledStatement(LabeledStatement node, A arg) => defaultStatement(node, arg); @override - R visitVariableInitialization(VariableInitialization node, A arg) => - defaultStatement(node, arg); - @override R visitBreakStatement(BreakStatement node, A arg) => defaultStatement(node, arg); @override @@ -2935,7 +2955,7 @@ mixin StatementVisitor1DefaultMixin implements StatementVisitor1 { R visitFunctionDeclaration(FunctionDeclaration node, A arg) => defaultStatement(node, arg); @override - R visitLegacyVariableStatement(LegacyVariableStatement node, A arg) => + R visitVariableStatement(VariableStatement node, A arg) => defaultStatement(node, arg); } @@ -3210,13 +3230,6 @@ mixin StatementVisitor1InternalNodeMixin /// aren't supported. mixin StatementVisitorExperimentExclusionMixin implements StatementVisitor { - @override - R visitVariableInitialization(VariableInitialization node) { - throw StateError( - "${runtimeType}.visitVariableInitialization isn't supported.", - ); - } - /// Since [Variable] is abstract due to an experiment, it doesn't /// have its own visit method in [StatementVisitor]. However, for the /// transitional period the backends would rely on having @@ -3229,8 +3242,8 @@ mixin StatementVisitorExperimentExclusionMixin R visitVariable(Variable node); @override - R visitLegacyVariableStatement(LegacyVariableStatement node) { - return visitVariable(node.variable); + R visitVariableStatement(VariableStatement node) { + return visitVariable(node.declaration.variable); } } @@ -3296,27 +3309,20 @@ mixin VariableVisitorExperimentExclusionMixin implements VariableVisitor { /// aren't supported. mixin StatementVisitor1ExperimentExclusionMixin implements StatementVisitor1 { - @override - R visitVariableInitialization(VariableInitialization node, A arg) { - throw StateError( - "${runtimeType}.visitVariableInitialization isn't supported.", - ); - } - /// Since [Variable] is abstract due to an experiment, it doesn't /// have its own visit method in [StatementVisitor1]. However, for the /// transitional period the backends would rely on having - /// [visitVariableDeclaration] and on needing to override it. Since the + /// [visitVariable] and on needing to override it. Since the /// statement visitors in the backends should mix in /// [StatementVisitor1ExperimentExclusionMixin], we can deliver the abstract - /// declaration of [visitVariableDeclaration] to them via the mixin. At the + /// declaration of [visitVariable] 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(Variable node, A arg); + R visitVariable(Variable node, A arg); @override - R visitLegacyVariableStatement(LegacyVariableStatement node, A arg) { - return visitVariableDeclaration(node.variable, arg); + R visitVariableStatement(VariableStatement node, A arg) { + return visitVariable(node.declaration.variable, arg); } } diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart index 859087aa066..546efed3d49 100644 --- a/pkg/kernel/test/verify_test.dart +++ b/pkg/kernel/test/verify_test.dart @@ -24,69 +24,49 @@ void main() { positiveTest('Test harness has no errors', (TestHarness test) { test.addNode(NullLiteral()); }); - negative1Test( - 'VariableGet out of scope', - (TestHarness test) { - Variable node = test.makeVariable(); - test.addNode(VariableGet(node)); - return node; - }, - (Node? node) => "${errorPrefix}Variable '$node' used out of scope.", - ); - negative1Test( - 'VariableSet out of scope', - (TestHarness test) { - Variable variable = test.makeVariable(); - test.addNode(VariableSet(variable, new NullLiteral())); - return variable; - }, - (Node? node) => "${errorPrefix}Variable '$node' used out of scope.", - ); - negative1Test( - 'Variable block scope', - (TestHarness test) { - Variable variable = test.makeVariable(); - test.addNode( - Block([ - new Block([new VariableStatement(variable)]), - new ReturnStatement(new VariableGet(variable)), - ]), - ); - return variable; - }, - (Node? node) => "${errorPrefix}Variable '$node' used out of scope.", - ); - negative1Test( - 'Variable let scope', - (TestHarness test) { - Variable variable = test.makeVariable(); - test.addNode( - LogicalExpression( - new Let(variable, new VariableGet(variable)), - LogicalExpressionOperator.AND, - new VariableGet(variable), - ), - ); - return variable; - }, - (Node? node) => "${errorPrefix}Variable '$node' used out of scope.", - ); - negative1Test( - 'Variable redeclared', - (TestHarness test) { - Variable variable = test.makeVariable(); - 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.", - ); + negative1Test('VariableGet out of scope', (TestHarness test) { + Variable node = test.makeVariable(); + test.addNode(VariableGet(node)); + return node; + }, (Node? node) => "${errorPrefix}Variable '$node' used out of scope."); + negative1Test('VariableSet out of scope', (TestHarness test) { + Variable variable = test.makeVariable(); + test.addNode(VariableSet(variable, new NullLiteral())); + return variable; + }, (Node? node) => "${errorPrefix}Variable '$node' used out of scope."); + negative1Test('Variable block scope', (TestHarness test) { + Variable variable = test.makeVariable(); + test.addNode( + Block([ + new Block([new VariableStatement(VariableDeclaration(variable))]), + new ReturnStatement(new VariableGet(variable)), + ]), + ); + return variable; + }, (Node? node) => "${errorPrefix}Variable '$node' used out of scope."); + negative1Test('Variable let scope', (TestHarness test) { + Variable variable = test.makeVariable(); + test.addNode( + LogicalExpression( + new Let(variable, new VariableGet(variable)), + LogicalExpressionOperator.AND, + new VariableGet(variable), + ), + ); + return variable; + }, (Node? node) => "${errorPrefix}Variable '$node' used out of scope."); + negative1Test('Variable redeclared', (TestHarness test) { + Variable variable = test.makeVariable(); + 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."); negative1Test( 'Member redeclared', (TestHarness test) { @@ -108,53 +88,39 @@ void main() { (Node? node) => "${errorPrefix}Member '$node' has been declared more than once.", ); - negative1Test( - 'Class redeclared', - (TestHarness test) { - Class otherClass = test.otherClass; - test.addNode( - otherClass, - ); // Test harness also adds otherClass to component. - return test.otherClass; - }, - (Node? node) => "${errorPrefix}Class '$node' declared more than once.", - ); - negative1Test( - 'Class type parameter redeclared', - (TestHarness test) { - TypeParameter parameter = test.makeTypeParameter(); - test.addNode( - Class( - name: 'Test', - supertype: test.objectClass.asRawSupertype, + negative1Test('Class redeclared', (TestHarness test) { + Class otherClass = test.otherClass; + test.addNode(otherClass); // Test harness also adds otherClass to component. + return test.otherClass; + }, (Node? node) => "${errorPrefix}Class '$node' declared more than once."); + negative1Test('Class type parameter redeclared', (TestHarness test) { + TypeParameter parameter = test.makeTypeParameter(); + test.addNode( + Class( + name: 'Test', + supertype: test.objectClass.asRawSupertype, + typeParameters: [parameter, parameter], + fileUri: dummyUri, + )..fileOffset = dummyFileOffset, + ); + return parameter; + }, (Node? node) => "${errorPrefix}Type parameter '$node' redeclared."); + negative1Test('Member type parameter redeclared', (TestHarness test) { + TypeParameter parameter = test.makeTypeParameter(); + test.addNode( + Procedure( + new Name('bar'), + ProcedureKind.Method, + new FunctionNode( + new ReturnStatement(new NullLiteral()), typeParameters: [parameter, parameter], - fileUri: dummyUri, - )..fileOffset = dummyFileOffset, - ); - return parameter; - }, - (Node? node) => "${errorPrefix}Type parameter '$node' redeclared.", - ); - negative1Test( - 'Member type parameter redeclared', - (TestHarness test) { - TypeParameter parameter = test.makeTypeParameter(); - test.addNode( - Procedure( - new Name('bar'), - ProcedureKind.Method, - new FunctionNode( - new ReturnStatement(new NullLiteral()), - typeParameters: [parameter, parameter], - ), - fileUri: dummyUri, - )..fileOffset = dummyFileOffset, - ); + ), + fileUri: dummyUri, + )..fileOffset = dummyFileOffset, + ); - return parameter; - }, - (Node? node) => "${errorPrefix}Type parameter '$node' redeclared.", - ); + return parameter; + }, (Node? node) => "${errorPrefix}Type parameter '$node' redeclared."); negative2Test( 'Type parameter out of scope', (TestHarness test) { @@ -537,113 +503,87 @@ void main() { test.enclosingLibrary.addTypedef(typedef_); test.enclosingLibrary.addField(field); }); - negative1Test( - 'Invalid typedef Foo = Foo', - (TestHarness test) { - var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - typedef_.type = new TypedefType(typedef_, Nullability.nonNullable); - test.addNode(typedef_); - return typedef_; - }, - (Node? node) => "${errorPrefix}The typedef '$node' refers to itself", - ); - negative1Test( - 'Invalid typedef Foo = `(Foo) => void`', - (TestHarness test) { - var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - typedef_.type = new FunctionType( - [new TypedefType(typedef_, Nullability.nonNullable)], - const VoidType(), - Nullability.nonNullable, - ); - test.addNode(typedef_); - return typedef_; - }, - (Node? node) => "${errorPrefix}The typedef '$node' refers to itself", - ); - negative1Test( - 'Invalid typedef Foo = `() => Foo`', - (TestHarness test) { - var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - typedef_.type = new FunctionType( - [], - new TypedefType(typedef_, Nullability.nonNullable), - Nullability.nonNullable, - ); - test.addNode(typedef_); - return typedef_; - }, - (Node? node) => "${errorPrefix}The typedef '$node' refers to itself", - ); - negative1Test( - 'Invalid typedef Foo = C', - (TestHarness test) { - var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - typedef_.type = new InterfaceType( - test.otherClass, - Nullability.nonNullable, - [new TypedefType(typedef_, Nullability.nonNullable)], - ); - test.addNode(typedef_); - return typedef_; - }, - (Node? node) => "${errorPrefix}The typedef '$node' refers to itself", - ); - negative1Test( - 'Invalid typedefs Foo = Bar, Bar = Foo', - (TestHarness test) { - var foo = new Typedef('Foo', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - var bar = new Typedef('Bar', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - foo.type = new TypedefType(bar, Nullability.nonNullable); - bar.type = new TypedefType(foo, Nullability.nonNullable); - test.enclosingLibrary.addTypedef(foo); - test.enclosingLibrary.addTypedef(bar); - return foo; - }, - (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself", - ); - negative1Test( - 'Invalid typedefs Foo = Bar, Bar = C', - (TestHarness test) { - var foo = new Typedef('Foo', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - var bar = new Typedef('Bar', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - foo.type = new TypedefType(bar, Nullability.nonNullable); - bar.type = new InterfaceType(test.otherClass, Nullability.nonNullable, [ - new TypedefType(foo, Nullability.nonNullable), - ]); - test.enclosingLibrary.addTypedef(foo); - test.enclosingLibrary.addTypedef(bar); - return foo; - }, - (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself", - ); - negative1Test( - 'Invalid typedefs Foo = C, Bar = C', - (TestHarness test) { - var foo = new Typedef('Foo', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - var bar = new Typedef('Bar', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - foo.type = new InterfaceType(test.otherClass, Nullability.nonNullable, [ - new TypedefType(bar, Nullability.nonNullable), - ]); - bar.type = new InterfaceType(test.otherClass, Nullability.nonNullable, [ - new TypedefType(foo, Nullability.nonNullable), - ]); - test.enclosingLibrary.addTypedef(foo); - test.enclosingLibrary.addTypedef(bar); - return foo; - }, - (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself", - ); + negative1Test('Invalid typedef Foo = Foo', (TestHarness test) { + var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + typedef_.type = new TypedefType(typedef_, Nullability.nonNullable); + test.addNode(typedef_); + return typedef_; + }, (Node? node) => "${errorPrefix}The typedef '$node' refers to itself"); + negative1Test('Invalid typedef Foo = `(Foo) => void`', (TestHarness test) { + var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + typedef_.type = new FunctionType( + [new TypedefType(typedef_, Nullability.nonNullable)], + const VoidType(), + Nullability.nonNullable, + ); + test.addNode(typedef_); + return typedef_; + }, (Node? node) => "${errorPrefix}The typedef '$node' refers to itself"); + negative1Test('Invalid typedef Foo = `() => Foo`', (TestHarness test) { + var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + typedef_.type = new FunctionType( + [], + new TypedefType(typedef_, Nullability.nonNullable), + Nullability.nonNullable, + ); + test.addNode(typedef_); + return typedef_; + }, (Node? node) => "${errorPrefix}The typedef '$node' refers to itself"); + negative1Test('Invalid typedef Foo = C', (TestHarness test) { + var typedef_ = new Typedef('Foo', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + typedef_.type = new InterfaceType( + test.otherClass, + Nullability.nonNullable, + [new TypedefType(typedef_, Nullability.nonNullable)], + ); + test.addNode(typedef_); + return typedef_; + }, (Node? node) => "${errorPrefix}The typedef '$node' refers to itself"); + negative1Test('Invalid typedefs Foo = Bar, Bar = Foo', (TestHarness test) { + var foo = new Typedef('Foo', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + var bar = new Typedef('Bar', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + foo.type = new TypedefType(bar, Nullability.nonNullable); + bar.type = new TypedefType(foo, Nullability.nonNullable); + test.enclosingLibrary.addTypedef(foo); + test.enclosingLibrary.addTypedef(bar); + return foo; + }, (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself"); + negative1Test('Invalid typedefs Foo = Bar, Bar = C', (TestHarness test) { + var foo = new Typedef('Foo', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + var bar = new Typedef('Bar', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + foo.type = new TypedefType(bar, Nullability.nonNullable); + bar.type = new InterfaceType(test.otherClass, Nullability.nonNullable, [ + new TypedefType(foo, Nullability.nonNullable), + ]); + test.enclosingLibrary.addTypedef(foo); + test.enclosingLibrary.addTypedef(bar); + return foo; + }, (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself"); + negative1Test('Invalid typedefs Foo = C, Bar = C', ( + TestHarness test, + ) { + var foo = new Typedef('Foo', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + var bar = new Typedef('Bar', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + foo.type = new InterfaceType(test.otherClass, Nullability.nonNullable, [ + new TypedefType(bar, Nullability.nonNullable), + ]); + bar.type = new InterfaceType(test.otherClass, Nullability.nonNullable, [ + new TypedefType(foo, Nullability.nonNullable), + ]); + test.enclosingLibrary.addTypedef(foo); + test.enclosingLibrary.addTypedef(bar); + return foo; + }, (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself"); positiveTest('Valid long typedefs C20 = C19 = ... = C1 = C0 = dynamic', ( TestHarness test, ) { @@ -659,27 +599,25 @@ void main() { test.enclosingLibrary.addTypedef(typedef_); } }); - negative1Test( - 'Invalid long typedefs C20 = C19 = ... = C1 = C0 = C20', - (TestHarness test) { - Typedef firstTypedef = new Typedef('C0', null, fileUri: dummyUri) - ..fileOffset = dummyFileOffset; - Typedef typedef_ = firstTypedef; + negative1Test('Invalid long typedefs C20 = C19 = ... = C1 = C0 = C20', ( + TestHarness test, + ) { + Typedef firstTypedef = new Typedef('C0', null, fileUri: dummyUri) + ..fileOffset = dummyFileOffset; + Typedef typedef_ = firstTypedef; + test.enclosingLibrary.addTypedef(typedef_); + var first = typedef_; + for (int i = 1; i < 20; ++i) { + typedef_ = new Typedef( + 'C$i', + new TypedefType(typedef_, Nullability.nonNullable), + fileUri: dummyUri, + )..fileOffset = dummyFileOffset; test.enclosingLibrary.addTypedef(typedef_); - var first = typedef_; - for (int i = 1; i < 20; ++i) { - typedef_ = new Typedef( - 'C$i', - new TypedefType(typedef_, Nullability.nonNullable), - fileUri: dummyUri, - )..fileOffset = dummyFileOffset; - test.enclosingLibrary.addTypedef(typedef_); - } - first.type = new TypedefType(typedef_, Nullability.nonNullable); - return firstTypedef; - }, - (Node? node) => "${errorPrefix}The typedef '$node' refers to itself", - ); + } + first.type = new TypedefType(typedef_, Nullability.nonNullable); + return firstTypedef; + }, (Node? node) => "${errorPrefix}The typedef '$node' refers to itself"); positiveTest('Valid typedef Foo = C', (TestHarness test) { var param = new TypeParameter('T', test.otherRawType, test.otherRawType); var foo = new Typedef( @@ -766,27 +704,25 @@ void main() { }, (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself", ); - negative1Test( - 'Invalid typedef Foo = C', - (TestHarness test) { - var param = new TypeParameter('T', null); - var foo = new Typedef( - 'Foo', - new InterfaceType(test.otherClass, Nullability.nonNullable, [ - new TypeParameterType(param, Nullability.nonNullable), - ]), - typeParameters: [param], - fileUri: dummyUri, - )..fileOffset = dummyFileOffset; - param.bound = new TypedefType(foo, Nullability.nonNullable, [ - const DynamicType(), - ]); - param.defaultType = const DynamicType(); - test.addNode(foo); - return foo; - }, - (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself", - ); + negative1Test('Invalid typedef Foo = C', ( + TestHarness test, + ) { + var param = new TypeParameter('T', null); + var foo = new Typedef( + 'Foo', + new InterfaceType(test.otherClass, Nullability.nonNullable, [ + new TypeParameterType(param, Nullability.nonNullable), + ]), + typeParameters: [param], + fileUri: dummyUri, + )..fileOffset = dummyFileOffset; + param.bound = new TypedefType(foo, Nullability.nonNullable, [ + const DynamicType(), + ]); + param.defaultType = const DynamicType(); + test.addNode(foo); + return foo; + }, (Node? foo) => "${errorPrefix}The typedef '$foo' refers to itself"); negative1Test( 'Typedef arity error', (TestHarness test) { @@ -891,29 +827,21 @@ void main() { test.enclosingLibrary.addClass(cls); return null; }, (Node? node) => "${errorPrefix}'Class' has no fileOffset"); - negative1Test( - 'Extension file offset', - (TestHarness test) { - var extension = new Extension(name: 'Extension', fileUri: dummyUri); - test.enclosingLibrary.addExtension(extension); - return null; - }, - (Node? node) => "${errorPrefix}'Extension' has no fileOffset", - ); - negative1Test( - 'Procedure file offset', - (TestHarness test) { - var method = new Procedure( - new Name('method'), - ProcedureKind.Method, - new FunctionNode(null), - fileUri: dummyUri, - ); - test.enclosingClass.addProcedure(method); - return null; - }, - (Node? node) => "${errorPrefix}'method' has no fileOffset", - ); + negative1Test('Extension file offset', (TestHarness test) { + var extension = new Extension(name: 'Extension', fileUri: dummyUri); + test.enclosingLibrary.addExtension(extension); + return null; + }, (Node? node) => "${errorPrefix}'Extension' has no fileOffset"); + negative1Test('Procedure file offset', (TestHarness test) { + var method = new Procedure( + new Name('method'), + ProcedureKind.Method, + new FunctionNode(null), + fileUri: dummyUri, + ); + test.enclosingClass.addProcedure(method); + return null; + }, (Node? node) => "${errorPrefix}'method' has no fileOffset"); negative1Test('Field file offset', (TestHarness test) { var field = new Field.mutable(new Name('field'), fileUri: dummyUri); test.enclosingClass.addField(field); diff --git a/pkg/vm/lib/modular/transformations/ffi/finalizable.dart b/pkg/vm/lib/modular/transformations/ffi/finalizable.dart index 62ae6676c3a..88087019084 100644 --- a/pkg/vm/lib/modular/transformations/ffi/finalizable.dart +++ b/pkg/vm/lib/modular/transformations/ffi/finalizable.dart @@ -79,9 +79,9 @@ mixin FinalizableTransformer on Transformer { final alwaysInitialized = entry.value; addPossiblyUninitializedTo!.statements.insert( addPossiblyUninitializedTo.statements.indexOf( - possiblyUninitialized.parent as VariableStatement, + possiblyUninitialized.parent?.parent as VariableStatement, ), - VariableStatement(alwaysInitialized), + VariableStatement(VariableDeclaration(alwaysInitialized)), ); } assert(_currentScope == scope); @@ -562,7 +562,7 @@ mixin FinalizableTransformer on Transformer { ); return BlockExpression( Block([ - VariableStatement(resultVariable), + VariableStatement(VariableDeclaration(resultVariable)), ..._reachabilityFences(declarations), ]), VariableGet(resultVariable), @@ -744,7 +744,7 @@ ${parent?.toStringIndented(indentation: indentation + 2)} Variable possiblyUninitialized, Variable nullableValue, ) { - assert(possiblyUninitialized.parent is VariableStatement); + assert(possiblyUninitialized.parent?.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 053a7a19b50..2999a0312b9 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([ - VariableStatement(pointerAddressVar), + VariableStatement(VariableDeclaration(pointerAddressVar)), IfStatement( InstanceInvocation( InstanceAccessKind.Instance, @@ -374,7 +374,9 @@ 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(VariableStatement(temporary)); + temporariesForArguments.add( + VariableStatement(VariableDeclaration(temporary)), + ); callArguments.add( _getTemporary( temporary, @@ -419,7 +421,7 @@ class FfiNativeTransformer extends FfiTransformer { final resultBlock = BlockExpression( Block([ ...temporariesForArguments, - VariableStatement(result), + VariableStatement(VariableDeclaration(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 88de750b20b..8c3d595aa10 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([ - VariableStatement(arrayVar), - VariableStatement(indexVar), + VariableStatement(VariableDeclaration(arrayVar)), + VariableStatement(VariableDeclaration(indexVar)), ExpressionStatement( InstanceInvocation( InstanceAccessKind.Instance, @@ -913,7 +913,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer { )..fileOffset = fileOffset; final result = BlockExpression( - Block([VariableStatement(pointerVar), closure]), + Block([VariableStatement(VariableDeclaration(pointerVar)), closure]), VariableGet(closure.variable), ); @@ -1206,7 +1206,10 @@ mixin _FfiUseSiteTransformer on FfiTransformer { // expression result: _callback; return BlockExpression( - Block([VariableStatement(nativeCallable), pointerSetter]), + Block([ + VariableStatement(VariableDeclaration(nativeCallable)), + pointerSetter, + ]), VariableGet(nativeCallable), ); } @@ -1504,7 +1507,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer { )..fileOffset = node.fileOffset; return BlockExpression( - Block([VariableStatement(sourceVar)]), + Block([VariableStatement(VariableDeclaration(sourceVar))]), referencedStruct.generateStore( sourceVar, dartType: node.arguments.types[0], @@ -1585,8 +1588,8 @@ mixin _FfiUseSiteTransformer on FfiTransformer { return BlockExpression( Block([ - VariableStatement(arrayVar), - VariableStatement(indexVar), + VariableStatement(VariableDeclaration(arrayVar)), + VariableStatement(VariableDeclaration(indexVar)), ExpressionStatement( InstanceInvocation( InstanceAccessKind.Instance, @@ -1855,8 +1858,8 @@ mixin _FfiUseSiteTransformer on FfiTransformer { )..fileOffset = node.fileOffset; final checkIndexAndLocalVars = [ - VariableStatement(arrayVar), - VariableStatement(indexVar), + VariableStatement(VariableDeclaration(arrayVar)), + VariableStatement(VariableDeclaration(indexVar)), ExpressionStatement( InstanceInvocation( InstanceAccessKind.Instance, @@ -1867,9 +1870,9 @@ mixin _FfiUseSiteTransformer on FfiTransformer { functionType: arrayCheckIndex.getterType as FunctionType, ), ), - VariableStatement(singleElementSizeVar), - VariableStatement(elementSizeVar), - VariableStatement(offsetVar), + VariableStatement(VariableDeclaration(singleElementSizeVar)), + VariableStatement(VariableDeclaration(elementSizeVar)), + VariableStatement(VariableDeclaration(offsetVar)), ]; if (!setter) { @@ -1927,7 +1930,10 @@ mixin _FfiUseSiteTransformer on FfiTransformer { isSynthesized: true, )..fileOffset = node.fileOffset; return BlockExpression( - Block([...checkIndexAndLocalVars, VariableStatement(valueVar)]), + Block([ + ...checkIndexAndLocalVars, + VariableStatement(VariableDeclaration(valueVar)), + ]), StaticInvocation( memCopy, Arguments([ @@ -2437,7 +2443,7 @@ mixin _FfiUseSiteTransformer on FfiTransformer { isSynthesized: true, )..fileOffset = fileOffset; final newArgument = BlockExpression( - Block([VariableStatement(valueVar)]), + Block([VariableStatement(VariableDeclaration(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 3259eb575ac..08afd1496e0 100644 --- a/pkg/vm/lib/modular/transformations/for_in_lowering.dart +++ b/pkg/vm/lib/modular/transformations/for_in_lowering.dart @@ -144,8 +144,10 @@ class ForInLowering { valueVariable.initializer!.parent = valueVariable; final whileBody = new Block([ - new VariableStatement(valueVariable) - ..fileOffset = valueVariable.fileOffset, + new VariableStatement( + VariableDeclaration(valueVariable) + ..fileOffset = valueVariable.fileOffset, + )..fileOffset = valueVariable.fileOffset, stmt.body, ]); final tryBody = new WhileStatement(whileCondition, whileBody) @@ -186,10 +188,14 @@ class ForInLowering { final tryFinally = new TryFinally(tryBody, tryFinalizer); final block = new Block([ - new VariableStatement(streamVariable) - ..fileOffset = streamVariable.fileOffset, - new VariableStatement(forIteratorVariable) - ..fileOffset = forIteratorVariable.fileOffset, + new VariableStatement( + VariableDeclaration(streamVariable) + ..fileOffset = streamVariable.fileOffset, + )..fileOffset = streamVariable.fileOffset, + new VariableStatement( + VariableDeclaration(forIteratorVariable) + ..fileOffset = forIteratorVariable.fileOffset, + )..fileOffset = forIteratorVariable.fileOffset, tryFinally, ]); return block; @@ -303,7 +309,9 @@ class ForInLowering { type: type, initializer: initializer, ); - final initialization = VariableInitialization(variable: variable); + final initialization = VariableStatement( + VariableDeclaration(variable)..fileOffset = fileOffset, + )..fileOffset = fileOffset; return (variable, initialization); } else { final variableAndInitialization = Variable( @@ -314,7 +322,10 @@ class ForInLowering { )..fileOffset = fileOffset; return ( variableAndInitialization, - VariableStatement(variableAndInitialization)..fileOffset = fileOffset, + VariableStatement( + VariableDeclaration(variableAndInitialization) + ..fileOffset = fileOffset, + )..fileOffset = fileOffset, ); } } @@ -326,10 +337,13 @@ class ForInLowering { initializer.parent = variable; variable..initializer = initializer; if (isClosureContextLoweringEnabled) { - return VariableInitialization(variable: variable) - ..fileOffset = variable.fileOffset; + return VariableStatement( + VariableDeclaration(variable)..fileOffset = variable.fileOffset, + )..fileOffset = variable.fileOffset; } else { - return VariableStatement(variable)..fileOffset = variable.fileOffset; + return VariableStatement( + VariableDeclaration(variable)..fileOffset = variable.fileOffset, + )..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 459013c6eb9..329e4b72237 100644 --- a/pkg/vm/lib/modular/transformations/late_var_init_transformer.dart +++ b/pkg/vm/lib/modular/transformations/late_var_init_transformer.dart @@ -11,14 +11,14 @@ class LateVarInitTransformer { bool _shouldApplyTransform(Statement s) { if (s is VariableStatement) { // This transform only applies to late variables. - if (!s.variable.isLate) return false; + if (!s.declaration.variable.isLate) return false; // Const variables are ignored. - if (s.variable.isConst) return false; + if (s.declaration.variable.isConst) return false; // Variables with no initializer or a trivial initializer are ignored. - if (s.variable.initializer == null) return false; - final Expression? init = s.variable.initializer; + if (s.declaration.variable.initializer == null) return false; + final Expression? init = s.declaration.variable.initializer; if (init is StringLiteral) return false; if (init is BoolLiteral) return false; if (init is IntLiteral) return false; @@ -38,25 +38,25 @@ class LateVarInitTransformer { LocalFunctionIdGenerator localFunctionIdGenerator, ) { final fnNode = FunctionNode( - ReturnStatement(node.variable.initializer), - returnType: node.variable.type, + ReturnStatement(node.declaration.variable.initializer), + returnType: node.declaration.variable.type, ); final functionType = fnNode.computeThisFunctionType( Nullability.nonNullable, ); final fn = FunctionDeclaration( Variable( - "#${node.variable.name}#initializer", + "#${node.declaration.variable.name}#initializer", type: functionType, isSynthesized: true, ), fnNode, )..id = localFunctionIdGenerator.allocateId(); - node.variable.initializer = LocalFunctionInvocation( + node.declaration.variable.initializer = LocalFunctionInvocation( fn.variable, Arguments([]), functionType: functionType, - )..parent = node.variable; + )..parent = node.declaration.variable; return [fn, node]; } diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart index a8a0e3bb838..f1714649e07 100644 --- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart +++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart @@ -2802,11 +2802,17 @@ class SummaryCollector extends RecursiveResultVisitor { } @override - TypeExpr? visitLegacyVariableStatement(LegacyVariableStatement node) { + TypeExpr? visitVariableDeclaration(VariableDeclaration node) { defaultVariable(node.variable); return null; } + @override + TypeExpr? visitVariableStatement(VariableStatement node) { + visitVariableDeclaration(node.declaration); + return null; + } + TypeExpr? defaultVariable(Variable node) { final variable = node.variable; variable.annotations.forEach(_visitAnnotation);