[Kernel] Signal errors on static fields in constant contexts
Fasta allows some non-const static field access in constant contexts
which leads to the constant evaluator trying to evaluate them. Signal
an error instead of crashing. This will double-report errors for the
cases that Fasta already catches, and we should fix that
double-reporting.
Fix unbounded recursion in printing unevaluated constants (writeNode
called visitUnevaluatedConstant which called defaultConstant which
called writeNode...).
Fix a spurious trailing comma in printing of instance constants.
Change-Id: Idff3169a3a56432ad67c27ff9c267ef355c4c1dc
Reviewed-on: https://dart-review.googlesource.com/c/89514
Commit-Queue: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
index b26535f..5d76a5f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
@@ -15,8 +15,8 @@
Library,
ListConstant,
MapConstant,
+ Member,
NullConstant,
- Procedure,
StaticInvocation,
StringConstant,
TreeNode;
@@ -102,7 +102,7 @@
@override
void invalidStaticInvocation(
- List<TreeNode> context, TreeNode node, Procedure target) {
+ List<TreeNode> context, TreeNode node, Member target) {
addProblem(
node,
templateConstEvalInvalidStaticInvocation
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 328e40a..8899c8a 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1910,9 +1910,14 @@
sb.write('>');
}
sb.write(' {');
+ bool first = true;
node.fieldValues.forEach((Reference fieldRef, Constant constant) {
final String name = syntheticNames.nameConstant(constant);
- sb.write('${fieldRef.asField.name}: $name, ');
+ if (!first) {
+ first = false;
+ sb.write(', ');
+ }
+ sb.write('${fieldRef.asField.name}: $name');
});
sb.write('}');
endLine(sb.toString());
@@ -1936,6 +1941,13 @@
endLine(' $name = String.fromEnvironment(${node.name}, ${defaultValue})');
}
+ visitUnevaluatedConstant(UnevaluatedConstant node) {
+ final String name = syntheticNames.nameConstant(node);
+ write(' $name = ');
+ writeExpression(node.expression);
+ endLine();
+ }
+
defaultNode(Node node) {
write('<${node.runtimeType}>');
}
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index 5e96821..73f62ca 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -1107,10 +1107,14 @@
visitStaticGet(StaticGet node) {
return withNewEnvironment(() {
final Member target = node.target;
- if (target is Field && target.isConst) {
- return runInsideContext(target, () {
- return _evaluateSubexpression(target.initializer);
- });
+ if (target is Field) {
+ if (target.isConst) {
+ return runInsideContext(target, () {
+ return _evaluateSubexpression(target.initializer);
+ });
+ }
+ errorReporter.invalidStaticInvocation(contextChain, node, target);
+ throw new _AbortCurrentEvaluation();
} else if (target is Procedure) {
if (target.kind == ProcedureKind.Method) {
return canonicalize(new TearOffConstant(target));
@@ -1500,7 +1504,7 @@
void invalidMethodInvocation(
List<TreeNode> context, TreeNode node, Constant receiver, String op);
void invalidStaticInvocation(
- List<TreeNode> context, TreeNode node, Procedure target);
+ List<TreeNode> context, TreeNode node, Member target);
void invalidStringInterpolationOperand(
List<TreeNode> context, TreeNode node, Constant constant);
void invalidSymbolName(
@@ -1567,7 +1571,7 @@
@override
void invalidStaticInvocation(
- List<TreeNode> context, TreeNode node, Procedure target) {
+ List<TreeNode> context, TreeNode node, Member target) {
report(
context, 'Cannot invoke "$target" inside a constant expression', node);
}
diff --git a/pkg/vm/lib/constants_error_reporter.dart b/pkg/vm/lib/constants_error_reporter.dart
index cadbc0e..def7f4c 100644
--- a/pkg/vm/lib/constants_error_reporter.dart
+++ b/pkg/vm/lib/constants_error_reporter.dart
@@ -12,7 +12,7 @@
import 'package:front_end/src/api_unstable/vm.dart' as codes;
import 'package:kernel/ast.dart'
- show Constant, DartType, IntConstant, Procedure, TreeNode;
+ show Constant, DartType, IntConstant, Member, TreeNode;
import 'package:kernel/transformations/constants.dart' as constants;
import 'package:kernel/type_environment.dart' show TypeEnvironment;
@@ -69,7 +69,7 @@
@override
void invalidStaticInvocation(
- List<TreeNode> context, TreeNode node, Procedure target) {
+ List<TreeNode> context, TreeNode node, Member target) {
final message = codes.templateConstEvalInvalidStaticInvocation
.withArguments(target.name.toString());
reportIt(context, message, node);
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 96999e6..f98b2af 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -56,10 +56,7 @@
[ $compiler == fasta ]
Language/Statements/For/syntax_t13: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
Language/Statements/For/syntax_t20: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
-LanguageFeatures/Constant_update2018/CastOperator_A03_t02/01: Crash
LanguageFeatures/Constant_update2018/CastOperator_A04_t02: Crash
-LanguageFeatures/Constant_update2018/EqualityOperator_A01_t03: Crash
-LanguageFeatures/Constant_update2018/EqualityOperator_A01_t04: Crash
LanguageFeatures/Constant_update2018/NewOperators_A01_t01: Crash
LanguageFeatures/Constant_update2018/NewOperators_A01_t02: Crash
LanguageFeatures/Constant_update2018/NewOperators_A02_t01: CompileTimeError
@@ -82,8 +79,6 @@
LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t02: Crash
LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t01: Crash
LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t02: Crash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t03/01: Crash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t04/01: Crash
LanguageFeatures/Set-literals/constant_set_literals_A02_t01: Pass # CompileTimeError on $fasta
LanguageFeatures/Set-literals/constant_set_literals_A02_t02/01: MissingCompileTimeError # Issue 35608
LanguageFeatures/Set-literals/constant_set_literals_A02_t02/02: MissingCompileTimeError # Issue 35608
@@ -848,13 +843,7 @@
LanguageFeatures/Constant_update2018/CastOperator_A01_t01: DartkCrash
LanguageFeatures/Constant_update2018/CastOperator_A02_t01: DartkCrash
LanguageFeatures/Constant_update2018/CastOperator_A02_t02: DartkCrash
-LanguageFeatures/Constant_update2018/CastOperator_A03_t01/02: Pass
-LanguageFeatures/Constant_update2018/CastOperator_A03_t01/03: Pass
-LanguageFeatures/Constant_update2018/CastOperator_A03_t02/01: DartkCrash
-LanguageFeatures/Constant_update2018/CastOperator_A04_t01: Pass
LanguageFeatures/Constant_update2018/CastOperator_A04_t02: DartkCrash
-LanguageFeatures/Constant_update2018/EqualityOperator_A01_t03: DartkCrash
-LanguageFeatures/Constant_update2018/EqualityOperator_A01_t04: DartkCrash
LanguageFeatures/Constant_update2018/NewOperators_A01_t01: DartkCrash
LanguageFeatures/Constant_update2018/NewOperators_A01_t02: DartkCrash
LanguageFeatures/Constant_update2018/NewOperators_A02_t01: Fail
@@ -878,8 +867,6 @@
LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t02: DartkCrash
LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t01: Pass
LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t02: Pass
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t03/01: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t04/01: DartkCrash
LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t01: Pass
LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t02: Pass
LanguageFeatures/Set-literals/constant_set_literals_A02_t01: Pass