From eb00d038c7a468fe4653efeb4487794fbc29abd9 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Tue, 20 Sep 2022 20:32:55 +0000 Subject: [PATCH] Update Expression.inConstantContext to support RecordLiteral(s). Change-Id: I02c3692c359e65822d30a4e931b14dec5963fef0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/260065 Reviewed-by: Brian Wilkerson Reviewed-by: Samuel Rawlins Commit-Queue: Konstantin Shcheglov --- pkg/analyzer/lib/src/dart/ast/ast.dart | 5 +- .../lib/src/dart/constant/evaluation.dart | 7 -- pkg/analyzer/test/src/dart/ast/ast_test.dart | 28 ++++++++ .../non_constant_default_value_test.dart | 70 +++++++++++++++++++ 4 files changed, 101 insertions(+), 9 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 5bcb33c0325..2b85c1cbd36 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -4150,8 +4150,7 @@ abstract class ExpressionImpl extends AstNodeImpl child is MapLiteralEntry || child is SpreadElement || child is IfElement || - child is ForElement || - child is RecordLiteral) { + child is ForElement) { var parent = child.parent; if (parent is ConstantContextForExpressionImpl) { return true; @@ -4167,6 +4166,8 @@ abstract class ExpressionImpl extends AstNodeImpl } else if (parent is Annotation) { // Inside an annotation. return true; + } else if (parent is RecordLiteral && parent.constKeyword != null) { + return true; } else if (parent is VariableDeclaration) { var grandParent = parent.parent; // Inside the initializer for a `const` variable declaration. diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart index c863476f91e..4804b104cc9 100644 --- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart +++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart @@ -1015,13 +1015,6 @@ class ConstantVisitor extends UnifyingAstVisitor { @override DartObjectImpl? visitRecordLiteral(RecordLiteral node) { - if (!node.isConst) { - // TODO(brianwilkerson) Merge the error codes into a single error code or - // declare a new error code specific to records. - _errorReporter.reportErrorForNode( - CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL, node); - return null; - } var nodeType = node.staticType; if (nodeType == null) { return null; diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart index e3fa25c0324..1ad82b52374 100644 --- a/pkg/analyzer/test/src/dart/ast/ast_test.dart +++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart @@ -431,6 +431,34 @@ f() { assertInContext("[]", true); } + test_inConstantContext_listLiteral_namedFields_recordLiteral_false() { + parse(''' +final x = (0, foo: [1]); +'''); + assertInContext('[1]', false); + } + + test_inConstantContext_listLiteral_namedFields_recordLiteral_true() { + parse(''' +final x = const (0, foo: [1]); +'''); + assertInContext('[1]', true); + } + + test_inConstantContext_listLiteral_positionalFields_recordLiteral_false() { + parse(''' +final x = (0, [1]); +'''); + assertInContext('[1]', false); + } + + test_inConstantContext_listLiteral_positionalFields_recordLiteral_true() { + parse(''' +final x = const (0, [1]); +'''); + assertInContext('[1]', true); + } + test_inConstantContext_listLiteral_switch_true() { parse(''' f(v) { diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart index 98e12eca60f..db15623d601 100644 --- a/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart +++ b/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart @@ -126,6 +126,76 @@ f({x: y}) {} ]); } + test_function_named_constList() async { + await assertNoErrorsInCode(r''' +void f({x: const [0, 1]}) {} +'''); + } + + test_function_named_constList_elements_listLiteral() async { + await assertNoErrorsInCode(r''' +void f({x: const [0, [1]]}) {} +'''); + } + + test_function_named_constRecord() async { + await assertNoErrorsInCode(r''' +void f({x: const (0, 1)}) {} +'''); + } + + test_function_named_constRecord_namedFields_listLiteral() async { + await assertNoErrorsInCode(r''' +void f({x: const (0, foo: [1])}) {} +'''); + } + + test_function_named_constRecord_positionalFields_listLiteral() async { + await assertNoErrorsInCode(r''' +void f({x: const (0, [1])}) {} +'''); + } + + test_function_named_record_namedFields_integerLiteral() async { + await assertNoErrorsInCode(r''' +void f({x: (a: 0, b: 1)}) {} +'''); + } + + test_function_named_record_namedFields_listLiteral() async { + await assertErrorsInCode(r''' +void f({x: (a: 0, b: [1])}) {} +''', [ + error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 21, 3), + ]); + } + + test_function_named_record_namedFields_listLiteral_const() async { + await assertNoErrorsInCode(r''' +void f({x: (a: 0, b: const [1])}) {} +'''); + } + + test_function_named_record_positionalFields_integerLiteral() async { + await assertNoErrorsInCode(r''' +void f({x: (0, 1)}) {} +'''); + } + + test_function_named_record_positionalFields_listLiteral() async { + await assertErrorsInCode(r''' +void f({x: (0, [1])}) {} +''', [ + error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 15, 3), + ]); + } + + test_function_named_record_positionalFields_listLiteral_const() async { + await assertNoErrorsInCode(r''' +void f({x: (0, const [1])}) {} +'''); + } + test_function_positional() async { await assertErrorsInCode(r''' int y = 0;