[Kernel] Properly signal compilation errors for constants

Instead of simply printing a message, properly signal a Fasta problem for
constant errors.  This causes 68 tests (presumably missing compile-time
errors) to start passing with --enable-experiment=constant-update-2018.

Change-Id: Ia9f1809305bbef7b4652ce49acf6fb9c18408207
Reviewed-on: https://dart-review.googlesource.com/c/89580
Commit-Queue: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Peter von der Ahé <ahe@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 06cdc67..b26535f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
@@ -11,18 +11,166 @@
         EnvironmentBoolConstant,
         EnvironmentIntConstant,
         EnvironmentStringConstant,
+        IntConstant,
+        Library,
         ListConstant,
         MapConstant,
         NullConstant,
+        Procedure,
         StaticInvocation,
         StringConstant,
         TreeNode;
 
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
+
 import 'package:kernel/transformations/constants.dart'
     show ConstantsBackend, ErrorReporter;
 
+import '../fasta_codes.dart'
+    show
+        Message,
+        noLength,
+        messageConstEvalFailedAssertion,
+        templateConstEvalDeferredLibrary,
+        templateConstEvalDuplicateKey,
+        templateConstEvalFailedAssertionWithMessage,
+        templateConstEvalFreeTypeParameter,
+        templateConstEvalInvalidBinaryOperandType,
+        templateConstEvalInvalidMethodInvocation,
+        templateConstEvalInvalidStaticInvocation,
+        templateConstEvalInvalidStringInterpolationOperand,
+        templateConstEvalInvalidSymbolName,
+        templateConstEvalInvalidType,
+        templateConstEvalNegativeShift,
+        templateConstEvalNonConstantLiteral,
+        templateConstEvalNonConstantVariableGet,
+        templateConstEvalZeroDivisor;
+
+import '../loader.dart' show Loader;
+
 import '../problems.dart' show unexpected, unimplemented;
 
+class KernelConstantErrorReporter extends ErrorReporter {
+  final Loader<Library> loader;
+  final TypeEnvironment typeEnvironment;
+
+  KernelConstantErrorReporter(this.loader, this.typeEnvironment);
+
+  void addProblem(TreeNode node, Message message) {
+    loader.addProblem(message, getFileOffset(node), noLength, getFileUri(node));
+  }
+
+  @override
+  void freeTypeParameter(List<TreeNode> context, TreeNode node, DartType type) {
+    addProblem(node, templateConstEvalFreeTypeParameter.withArguments(type));
+  }
+
+  @override
+  void duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
+    addProblem(node, templateConstEvalDuplicateKey.withArguments(key));
+  }
+
+  @override
+  void invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
+      DartType expectedType) {
+    addProblem(
+        node,
+        templateConstEvalInvalidType.withArguments(
+            receiver, expectedType, receiver.getType(typeEnvironment)));
+  }
+
+  @override
+  void invalidBinaryOperandType(
+      List<TreeNode> context,
+      TreeNode node,
+      Constant receiver,
+      String op,
+      DartType expectedType,
+      DartType actualType) {
+    addProblem(
+        node,
+        templateConstEvalInvalidBinaryOperandType.withArguments(
+            op, receiver, expectedType, actualType));
+  }
+
+  @override
+  void invalidMethodInvocation(
+      List<TreeNode> context, TreeNode node, Constant receiver, String op) {
+    addProblem(node,
+        templateConstEvalInvalidMethodInvocation.withArguments(op, receiver));
+  }
+
+  @override
+  void invalidStaticInvocation(
+      List<TreeNode> context, TreeNode node, Procedure target) {
+    addProblem(
+        node,
+        templateConstEvalInvalidStaticInvocation
+            .withArguments(target.name.toString()));
+  }
+
+  @override
+  void invalidStringInterpolationOperand(
+      List<TreeNode> context, TreeNode node, Constant constant) {
+    addProblem(
+        node,
+        templateConstEvalInvalidStringInterpolationOperand
+            .withArguments(constant));
+  }
+
+  @override
+  void invalidSymbolName(
+      List<TreeNode> context, TreeNode node, Constant constant) {
+    addProblem(
+        node, templateConstEvalInvalidSymbolName.withArguments(constant));
+  }
+
+  @override
+  void zeroDivisor(
+      List<TreeNode> context, TreeNode node, IntConstant receiver, String op) {
+    addProblem(node,
+        templateConstEvalZeroDivisor.withArguments(op, '${receiver.value}'));
+  }
+
+  @override
+  void negativeShift(List<TreeNode> context, TreeNode node,
+      IntConstant receiver, String op, IntConstant argument) {
+    addProblem(
+        node,
+        templateConstEvalNegativeShift.withArguments(
+            op, '${receiver.value}', '${argument.value}'));
+  }
+
+  @override
+  void nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+    addProblem(node, templateConstEvalNonConstantLiteral.withArguments(klass));
+  }
+
+  @override
+  void failedAssertion(List<TreeNode> context, TreeNode node, String string) {
+    if (string == null) {
+      addProblem(node, messageConstEvalFailedAssertion);
+    } else {
+      addProblem(node,
+          templateConstEvalFailedAssertionWithMessage.withArguments(string));
+    }
+  }
+
+  @override
+  void nonConstantVariableGet(
+      List<TreeNode> context, TreeNode node, String variableName) {
+    addProblem(node,
+        templateConstEvalNonConstantVariableGet.withArguments(variableName));
+  }
+
+  @override
+  void deferredLibrary(
+      List<TreeNode> context, TreeNode node, String importName) {
+    addProblem(
+        node, templateConstEvalDeferredLibrary.withArguments(importName));
+  }
+}
+
 class KernelConstantsBackend extends ConstantsBackend {
   @override
   Constant lowerListConstant(ListConstant constant) => constant;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 75f57a8..8949eae 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -44,7 +44,7 @@
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
 
 import 'package:kernel/transformations/constants.dart' as constants
-    show SimpleErrorReporter, transformLibraries;
+    show transformLibraries;
 
 import '../../api_prototype/file_system.dart' show FileSystem;
 
@@ -98,7 +98,8 @@
         TypeBuilder,
         TypeDeclarationBuilder;
 
-import 'kernel_constants.dart' show KernelConstantsBackend;
+import 'kernel_constants.dart'
+    show KernelConstantErrorReporter, KernelConstantsBackend;
 
 import 'metadata_collector.dart' show MetadataCollector;
 
@@ -749,13 +750,15 @@
   /// libraries for the first time.
   void runBuildTransformations() {
     if (loader.target.enableConstantUpdate2018) {
+      TypeEnvironment environment = new TypeEnvironment(
+          loader.coreTypes, loader.hierarchy,
+          legacyMode: false);
       constants.transformLibraries(
           loader.libraries,
           new KernelConstantsBackend(),
           loader.coreTypes,
-          new TypeEnvironment(loader.coreTypes, loader.hierarchy,
-              legacyMode: false),
-          const constants.SimpleErrorReporter());
+          environment,
+          new KernelConstantErrorReporter(loader, environment));
       ticker.logMs("Evaluated constants");
     }
     backendTarget.performModularTransformationsOnLibraries(
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index 17bd047..5e96821 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -1173,7 +1173,6 @@
         final Constant right = positionalArguments[1];
         // Since we canonicalize constants during the evaluation, we can use
         // identical here.
-        assert(left == right);
         return identical(left, right) ? trueConstant : falseConstant;
       }
     }
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index b620f62..96999e6 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -56,7 +56,34 @@
 [ $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/*: Crash, Pass # Please triage these failures
+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
+LanguageFeatures/Constant_update2018/NewOperators_A02_t02: Crash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t03: Crash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t04: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t05: Crash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t06: Crash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t07: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t08: Crash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t09: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t02: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t05: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t02: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t05: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t03: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t04: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t06: Crash
+LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t01: Crash
+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