From 960b2842e81da522d298c53c088fe2f5e1186090 Mon Sep 17 00:00:00 2001 From: Chloe Stefantsova Date: Mon, 9 Mar 2026 05:19:46 -0700 Subject: [PATCH] [cfe] Use AST node getters for the new variable model This CL migrates CFE to use the getters of the Kernel AST nodes with return types of the new variable model. Part of https://github.com/dart-lang/sdk/issues/61572 Change-Id: I0984d076b9b9591c62fb91238a4df08c4eb9b414 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486200 Reviewed-by: Johnni Winther Commit-Queue: Chloe Stefantsova --- .../lib/src/base/incremental_compiler.dart | 8 +++--- .../kernel/const_conditional_simplifier.dart | 3 ++- .../lib/src/kernel/constant_evaluator.dart | 27 ++++++++++--------- .../lib/src/kernel/internal_ast.dart | 8 +++--- .../lib/src/testing/id_extractor.dart | 8 +++--- .../lib/src/type_inference/for_in.dart | 2 +- .../src/type_inference/inference_visitor.dart | 2 +- .../inference_visitor_base.dart | 18 ++++++------- .../test/id_tests/nullability_test.dart | 2 +- .../catch_variables.dart.strong.expect | 2 +- ...catch_variables.dart.strong.modular.expect | 2 +- pkg/front_end/tool/unreachable_if_finder.dart | 10 +++---- 12 files changed, 48 insertions(+), 44 deletions(-) diff --git a/pkg/front_end/lib/src/base/incremental_compiler.dart b/pkg/front_end/lib/src/base/incremental_compiler.dart index c0f1aa343c2..ae51f3bee25 100644 --- a/pkg/front_end/lib/src/base/incremental_compiler.dart +++ b/pkg/front_end/lib/src/base/incremental_compiler.dart @@ -2561,10 +2561,10 @@ class ExpressionEvaluationHelperImpl implements ExpressionEvaluationHelper { CompilerContext compilerContext, Uri fileUri, ) { - if (knownButUnavailable.contains(node.variable)) { + if (knownButUnavailable.contains(node.expressionVariable)) { return _returnKnownVariableUnavailable( node, - node.variable, + node.expressionVariable, problemReporting, compilerContext, fileUri, @@ -2581,10 +2581,10 @@ class ExpressionEvaluationHelperImpl implements ExpressionEvaluationHelper { CompilerContext compilerContext, Uri fileUri, ) { - if (knownButUnavailable.contains(node.variable)) { + if (knownButUnavailable.contains(node.expressionVariable)) { return _returnKnownVariableUnavailable( node, - node.variable, + node.expressionVariable, problemReporting, compilerContext, fileUri, diff --git a/pkg/front_end/lib/src/kernel/const_conditional_simplifier.dart b/pkg/front_end/lib/src/kernel/const_conditional_simplifier.dart index 98e5556b61a..788085691e8 100644 --- a/pkg/front_end/lib/src/kernel/const_conditional_simplifier.dart +++ b/pkg/front_end/lib/src/kernel/const_conditional_simplifier.dart @@ -184,7 +184,8 @@ class _ConstantEvaluator extends TryConstantEvaluator { @override Constant visitVariableGet(VariableGet node) => - _lookupVariableGet(node.variable) ?? super.visitVariableGet(node); + _lookupVariableGet(node.expressionVariable) ?? + super.visitVariableGet(node); // Coverage-ignore(suite): Not run. Constant? _evaluateStaticFieldGet(Field field) { diff --git a/pkg/front_end/lib/src/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/kernel/constant_evaluator.dart index cfc1bae7b8e..171ce676684 100644 --- a/pkg/front_end/lib/src/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/kernel/constant_evaluator.dart @@ -583,11 +583,12 @@ class ConstantsTransformer extends RemovingTransformer { if (expression is StaticGet && expression.target.isConst) { // Handle [StaticGet] of constant fields also when these are not inlined. expression = (expression.target as Field).initializer!; - } else if (expression is VariableGet && expression.variable.isConst) { + } else if (expression is VariableGet && + expression.expressionVariable.isConst) { // Coverage-ignore-block(suite): Not run. // Handle [VariableGet] of constant locals also when these are not // inlined. - expression = expression.variable.initializer!; + expression = expression.expressionVariable.initializer!; } if (expression is ConstantExpression) { if (result.typeArguments.every(isInstantiated)) { @@ -4780,7 +4781,7 @@ class ConstantEvaluator // // TODO(kustermann): The heuristic of allowing all [VariableGet]s on [Let] // variables might allow more than it should. - final ExpressionVariable variable = node.variable; + final ExpressionVariable variable = node.expressionVariable; if (enableConstFunctions || inExtensionTypeConstConstructor) { return env.lookupVariable(variable) ?? // Coverage-ignore(suite): Not run. @@ -4794,7 +4795,7 @@ class ConstantEvaluator if (variable.parent is Let || variable.parent is LocalInitializer || _isFormalParameter(variable)) { - return env.lookupVariable(node.variable) ?? + return env.lookupVariable(node.expressionVariable) ?? createEvaluationErrorConstant( node, diag.constEvalNonConstantVariableGet.withArguments( @@ -4817,7 +4818,7 @@ class ConstantEvaluator @override Constant visitVariableSet(VariableSet node) { if (enableConstFunctions || inExtensionTypeConstConstructor) { - final ExpressionVariable variable = node.variable; + final ExpressionVariable variable = node.expressionVariable; Constant value = _evaluateSubexpression(node.value); if (value is AbortConstant) return value; Constant? result = env.updateVariableValue(variable, value); @@ -6216,11 +6217,11 @@ class StatementConstantEvaluator ) || catchClause.guard == defaultType) { return exprEvaluator.withNewEnvironment(() { - if (catchClause.exception != null) { + if (catchClause.exceptionCatchVariable != null) { // TODO(kallentu): Store non-constant exceptions. if (throwValue is Constant) { exprEvaluator.env.addVariableValue( - catchClause.exception!, + catchClause.exceptionCatchVariable!, throwValue, ); } @@ -6411,15 +6412,15 @@ class EvaluationEnvironment { {}; /// The references to values of the parameters/variables in scope. - final Map _variables = - {}; + final Map _variables = + {}; /// The variables that hold unevaluated constants. /// /// Variables are removed from this set when looked up, leaving only the /// unread variables at the end. - final Set _unreadUnevaluatedVariables = - new Set(); + final Set _unreadUnevaluatedVariables = + new Set(); final EvaluationEnvironment? _parent; @@ -6440,7 +6441,7 @@ class EvaluationEnvironment { _typeParameters[parameter] = value; } - void addVariableValue(VariableDeclaration variable, Constant value) { + void addVariableValue(ExpressionVariable variable, Constant value) { _variables[variable] = new EvaluationReference(value); if (value is UnevaluatedConstant) { _unreadUnevaluatedVariables.add(variable); @@ -6471,7 +6472,7 @@ class EvaluationEnvironment { if (_unreadUnevaluatedVariables.isEmpty) return const []; // Coverage-ignore(suite): Not run. return _unreadUnevaluatedVariables.map( - (VariableDeclaration variable) => + (ExpressionVariable variable) => _variables[variable]!.value as UnevaluatedConstant, ); } diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart index 6cfd7246dfe..4a22a4c9073 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast.dart @@ -1512,7 +1512,7 @@ mixin DelegatingVariableMixin on InternalExpressionVariableMixin @override void set type(DartType value) { - astVariable.type = type; + astVariable.type = value; } @override @@ -4773,11 +4773,11 @@ Expression clonePureExpression(Expression node) { return new ThisExpression()..fileOffset = node.fileOffset; } else if (node is VariableGet) { assert( - node.variable.isFinal && !node.variable.isLate, + node.expressionVariable.isFinal && !node.variable.isLate, "Trying to clone VariableGet of non-final variable" - " ${node.variable}.", + " ${node.expressionVariable}.", ); - return new VariableGet(node.variable, node.promotedType) + return new VariableGet(node.expressionVariable, node.promotedType) ..fileOffset = node.fileOffset; } // Coverage-ignore-block(suite): Not run. diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart index dc42fc9c076..f2e2e3e11f4 100644 --- a/pkg/front_end/lib/src/testing/id_extractor.dart +++ b/pkg/front_end/lib/src/testing/id_extractor.dart @@ -284,7 +284,8 @@ abstract class DataExtractor extends VisitorDefault @override void visitEqualsNull(EqualsNull node) { Expression receiver = node.expression; - if (receiver is VariableGet && receiver.variable.name == null) { + if (receiver is VariableGet && + receiver.expressionVariable.cosmeticName == null) { // This is a desugared `?.`. } else { _visitInvocation(node, Name.equalsName); @@ -372,7 +373,8 @@ abstract class DataExtractor extends VisitorDefault @override void visitVariableGet(VariableGet node) { - if (node.variable.name != null && !node.variable.isInitializingFormal) { + if (node.expressionVariable.cosmeticName != null && + !node.expressionVariable.isInitializingFormal) { // Skip use of synthetic variables. computeForNode( node, @@ -400,7 +402,7 @@ abstract class DataExtractor extends VisitorDefault @override void visitVariableSet(VariableSet node) { - if (node.variable.name != null) { + if (node.expressionVariable.cosmeticName != null) { // Skip use of synthetic variables. computeForNode(node, createUpdateId(node)); } diff --git a/pkg/front_end/lib/src/type_inference/for_in.dart b/pkg/front_end/lib/src/type_inference/for_in.dart index 49c15d68e2e..9b078f1034a 100644 --- a/pkg/front_end/lib/src/type_inference/for_in.dart +++ b/pkg/front_end/lib/src/type_inference/for_in.dart @@ -93,7 +93,7 @@ class PatternVariableDeclarationForInVariable implements ForInVariable { // Coverage-ignore(suite): Not run. DartType computeElementType(InferenceVisitorBase visitor) { return (patternVariableDeclaration.initializer as VariableGet) - .variable + .expressionVariable .type; } 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 0abfd0cc20f..05c0fb72277 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart @@ -1399,7 +1399,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase PropertyTarget computePropertyTarget(Expression target) { if (_enclosingCascade case Cascade( :var variable, - ) when target is VariableGet && target.variable == variable) { + ) when target is VariableGet && target.expressionVariable == variable) { // `target` is an implicit reference to the target of a cascade // expression; flow analysis uses `CascadePropertyTarget` to represent // this situation. 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 e92b7780d34..8e8bf0855a5 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 @@ -252,13 +252,13 @@ abstract class InferenceVisitorBase implements InferenceVisitor { } TreeNode origNode = node; while (origNode is VariableGet && - origNode.variable.name == null && - origNode.variable.initializer != null) { + origNode.expressionVariable.cosmeticName == null && + origNode.expressionVariable.initializer != null) { // This is a read of a synthetic variable, presumably from a "let". // Find the original expression. // TODO(johnniwinther): add a general solution for getting the // original node for testing. - origNode = origNode.variable.initializer!; + origNode = origNode.expressionVariable.initializer!; } dataForTesting!.flowAnalysisResult.nonPromotionReasons[origNode] = nonPromotionReasonText; @@ -2879,7 +2879,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { functionType: null, )..fileOffset = fileOffset; } else if (receiver is VariableGet) { - ExpressionVariable variable = receiver.variable; + ExpressionVariable variable = receiver.expressionVariable; TreeNode? parent = variable.parent; if (parent is FunctionDeclaration) { assert( @@ -4428,11 +4428,11 @@ abstract class InferenceVisitorBase implements InferenceVisitor { compilerContext: compilerContext, expression: resultExpression, message: diag.lateDefinitelyAssignedError.withArguments( - variableName: node.variable.name!, + variableName: node.expressionVariable.cosmeticName!, ), fileUri: fileUri, fileOffset: node.fileOffset, - length: node.variable.name!.length, + length: node.expressionVariable.cosmeticName!.length, ), ); } @@ -4444,11 +4444,11 @@ abstract class InferenceVisitorBase implements InferenceVisitor { compilerContext: compilerContext, expression: resultExpression, message: diag.finalPossiblyAssignedError.withArguments( - variableName: node.variable.name!, + variableName: node.expressionVariable.cosmeticName!, ), fileUri: fileUri, fileOffset: node.fileOffset, - length: node.variable.name!.length, + length: node.expressionVariable.cosmeticName!.length, ), ); } @@ -4792,7 +4792,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { Expression? initializer = first.initializer; if (initializer is! StaticInvocation) return false; if (initializer.target != engine.setFactory) return false; - return value.variable == first; + return value.expressionVariable == first; } /// Determines if the given [expression]'s type is precisely known at compile diff --git a/pkg/front_end/test/id_tests/nullability_test.dart b/pkg/front_end/test/id_tests/nullability_test.dart index 78d9fe434e1..9f8369f4598 100644 --- a/pkg/front_end/test/id_tests/nullability_test.dart +++ b/pkg/front_end/test/id_tests/nullability_test.dart @@ -55,7 +55,7 @@ class NullabilityDataExtractor extends CfeDataExtractor { @override String? computeNodeValue(Id id, TreeNode node) { if (node is VariableGet && node.promotedType != null) { - if (node.variable.type.nullability != Nullability.nonNullable && + if (node.expressionVariable.type.nullability != Nullability.nonNullable && node.promotedType!.nullability == Nullability.nonNullable) { return 'nonNullable'; } diff --git a/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.expect b/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.expect index 0a7e7f66c72..56f1a6e4d92 100644 --- a/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.expect +++ b/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.expect @@ -70,7 +70,7 @@ static method testDirectCaptured() → dynamic { catch-variable s; ]), ] */ { - return () /* #ctx4 */ → core::List => [e, s]; + return () /* #ctx4 */ → core::List => [e, s]; } } static method testAssertCaptured() → dynamic { diff --git a/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.modular.expect b/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.modular.expect index 0a7e7f66c72..56f1a6e4d92 100644 --- a/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.modular.expect +++ b/pkg/front_end/testcases/closure_context_lowering/catch_variables.dart.strong.modular.expect @@ -70,7 +70,7 @@ static method testDirectCaptured() → dynamic { catch-variable s; ]), ] */ { - return () /* #ctx4 */ → core::List => [e, s]; + return () /* #ctx4 */ → core::List => [e, s]; } } static method testAssertCaptured() → dynamic { diff --git a/pkg/front_end/tool/unreachable_if_finder.dart b/pkg/front_end/tool/unreachable_if_finder.dart index aaf62f41b1d..defcf825f15 100644 --- a/pkg/front_end/tool/unreachable_if_finder.dart +++ b/pkg/front_end/tool/unreachable_if_finder.dart @@ -84,7 +84,7 @@ class UnreachableIfFinder extends RecursiveVisitor { } if (condition is VariableGet) { - bool? knownValue = knownValues[condition.variable]; + bool? knownValue = knownValues[condition.expressionVariable]; if (knownValue != null) { if (conditionNegated) knownValue = !knownValue; String? hint; @@ -102,9 +102,9 @@ class UnreachableIfFinder extends RecursiveVisitor { ), ); } else { - if (condition.variable.isFinal || - unwritten.contains(condition.variable)) { - newKnownValueHere = condition.variable; + if (condition.expressionVariable.isFinal || + unwritten.contains(condition.expressionVariable)) { + newKnownValueHere = condition.expressionVariable; } } } @@ -135,7 +135,7 @@ class EffectivelyFinal extends RecursiveVisitor { @override void visitVariableSet(VariableSet node) { - unwritten.remove(node.variable); + unwritten.remove(node.expressionVariable); super.visitVariableSet(node); } }