Handle ir constants in field analysis and impact tests

Include initial handling of unevaluated constants from environment.

Change-Id: Ibd330a14dfabad1dee95b64ce7015939412374d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97112
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 17c84a4..4888037 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -197,12 +197,14 @@
 
 class _Environment implements Environment {
   final Map<String, String> definitions;
+  Map<String, String> _completeMap;
   Set<String> supportedLibraries;
 
   _Environment(this.definitions);
 
   @override
   String valueOf(String name) {
+    if (_completeMap != null) return _completeMap[name];
     var result = definitions[name];
     if (result != null || definitions.containsKey(name)) return result;
     if (!name.startsWith(_dartLibraryEnvironmentPrefix)) return null;
@@ -214,6 +216,22 @@
     if (supportedLibraries.contains(libraryName)) return "true";
     return null;
   }
+
+  @override
+  Map<String, String> toMap() {
+    if (_completeMap == null) {
+      _completeMap = new Map<String, String>.from(definitions);
+      for (String libraryName in supportedLibraries) {
+        if (!libraryName.startsWith("_")) {
+          String key = '${_dartLibraryEnvironmentPrefix}${libraryName}';
+          if (!definitions.containsKey(key)) {
+            _completeMap[key] = "true";
+          }
+        }
+      }
+    }
+    return _completeMap;
+  }
 }
 
 /// For every 'dart:' library, a corresponding environment variable is set
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 2eb6455..39c73a8 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -981,6 +981,9 @@
 
   @override
   String valueOf(String key) => null;
+
+  @override
+  Map<String, String> toMap() => const {};
 }
 
 /// Interface for showing progress during compilation.
diff --git a/pkg/compiler/lib/src/environment.dart b/pkg/compiler/lib/src/environment.dart
index 29c9861..67db9ac 100644
--- a/pkg/compiler/lib/src/environment.dart
+++ b/pkg/compiler/lib/src/environment.dart
@@ -13,4 +13,7 @@
   /// Note that `bool.fromEnvironment` and `int.fromEnvironment` are also
   /// implemented in terms of `String.fromEnvironment`.
   String valueOf(String key);
+
+  /// Returns the full environment as map.
+  Map<String, String> toMap();
 }
diff --git a/pkg/compiler/lib/src/ir/constants.dart b/pkg/compiler/lib/src/ir/constants.dart
new file mode 100644
index 0000000..5783f3a
--- /dev/null
+++ b/pkg/compiler/lib/src/ir/constants.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
+import 'package:kernel/transformations/constants.dart' as ir;
+
+import '../kernel/dart2js_target.dart';
+
+class Dart2jsConstantEvaluator extends ir.ConstantEvaluator {
+  Dart2jsConstantEvaluator(ir.TypeEnvironment typeEnvironment,
+      {bool enableAsserts, Map<String, String> environment: const {}})
+      : super(const Dart2jsConstantsBackend(), environment, typeEnvironment,
+            enableAsserts, const DevNullErrorReporter());
+
+  @override
+  ir.Constant evaluate(ir.Expression node, {bool requireConstant: true}) {
+    if (node is ir.ConstantExpression) {
+      ir.Constant constant = node.constant;
+      if (constant is ir.UnevaluatedConstant) {
+        return node.constant = super.evaluate(constant.expression);
+      }
+      return constant;
+    }
+    if (requireConstant) {
+      // TODO(johnniwinther): Handle reporting of compile-time constant
+      // evaluation errors.
+      return super.evaluate(node);
+    } else {
+      try {
+        return super.evaluate(node);
+      } catch (e) {
+        return null;
+      }
+    }
+  }
+}
+
+class DevNullErrorReporter extends ir.SimpleErrorReporter {
+  const DevNullErrorReporter();
+
+  @override
+  String report(List<ir.TreeNode> context, String what, ir.TreeNode node) =>
+      what;
+}
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index cf3ab20..49bba79 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -968,6 +968,11 @@
             data.node, data.kind, data.receiverType, data.argumentType);
       }
     }
+    if (_constants != null) {
+      for (ir.ConstantExpression data in _constants) {
+        registry.registerConstant(data);
+      }
+    }
 
     // TODO(johnniwinther): Remove these when CFE provides constants.
     if (_constructorNodes != null) {
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index e084b4c..217ab9a 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -219,6 +219,13 @@
       _backendUsage.registerBackendFunctionUse(helper);
       impactBuilder
           .registerTypeUse(new TypeUse.instantiation(_commonElements.typeType));
+    } else if (constant.isConstructedObject) {
+      ConstructedConstantValue constructed = constant;
+      impactBuilder
+          .registerTypeUse(new TypeUse.instantiation(constructed.type));
+      constructed.fields.forEach((FieldEntity field, _) {
+        impactBuilder.registerStaticUse(new StaticUse.fieldInit(field));
+      });
     }
   }
 
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index cc810d1..0debe8b 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -10,7 +10,8 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/target/targets.dart';
-import 'package:kernel/transformations/constants.dart' show ConstantsBackend;
+import 'package:kernel/transformations/constants.dart'
+    show ConstantsBackend, NumberSemantics;
 import 'invocation_mirror_constants.dart';
 
 const Iterable<String> _allowedDartSchemePaths = const <String>[
@@ -147,10 +148,9 @@
     return new ir.InvalidExpression(null);
   }
 
-  // TODO(askesc): Return specialized dart2js constants backend.
   @override
   ConstantsBackend constantsBackend(CoreTypes coreTypes) =>
-      const ConstantsBackend();
+      const Dart2jsConstantsBackend();
 }
 
 // TODO(sigmund): this "extraRequiredLibraries" needs to be removed...
@@ -195,3 +195,10 @@
     'dart:mirrors',
   ]
 };
+
+class Dart2jsConstantsBackend extends ConstantsBackend {
+  const Dart2jsConstantsBackend();
+
+  @override
+  NumberSemantics get numberSemantics => NumberSemantics.js;
+}
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 6f2491d..8f4569d 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -11,6 +11,7 @@
 import 'package:kernel/core_types.dart' as ir;
 import 'package:kernel/type_algebra.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
+import 'package:kernel/transformations/constants.dart' as ir;
 
 import '../common.dart';
 import '../common/names.dart';
@@ -28,6 +29,7 @@
 import '../environment.dart';
 import '../frontend_strategy.dart';
 import '../ir/annotations.dart';
+import '../ir/constants.dart';
 import '../ir/debug.dart';
 import '../ir/element_map.dart';
 import '../ir/impact.dart';
@@ -67,6 +69,7 @@
   final CompilerOptions options;
   @override
   final DiagnosticReporter reporter;
+  final Environment _environment;
   CommonElementsImpl _commonElements;
   KernelElementEnvironment _elementEnvironment;
   DartTypeConverter _typeConverter;
@@ -74,6 +77,7 @@
   KernelDartTypes _types;
   ir.TypeEnvironment _typeEnvironment;
   ir.ClassHierarchy _classHierarchy;
+  ir.ConstantEvaluator _constantEvaluator;
 
   /// Library environment. Used for fast lookup.
   KProgramEnv env = new KProgramEnv();
@@ -115,11 +119,11 @@
 
   Map<KMember, Map<ir.Expression, TypeMap>> typeMapsForTesting;
 
-  KernelToElementMapImpl(this.reporter, Environment environment,
-      this._frontendStrategy, this.options) {
+  KernelToElementMapImpl(
+      this.reporter, this._environment, this._frontendStrategy, this.options) {
     _elementEnvironment = new KernelElementEnvironment(this);
     _commonElements = new CommonElementsImpl(_elementEnvironment);
-    _constantEnvironment = new KernelConstantEnvironment(this, environment);
+    _constantEnvironment = new KernelConstantEnvironment(this, _environment);
     _typeConverter = new DartTypeConverter(this);
     _types = new KernelDartTypes(this);
   }
@@ -742,19 +746,19 @@
 
   @override
   ir.TypeEnvironment get typeEnvironment {
-    if (_typeEnvironment == null) {
-      _typeEnvironment ??= new ir.TypeEnvironment(
-          new ir.CoreTypes(env.mainComponent), classHierarchy);
-    }
-    return _typeEnvironment;
+    return _typeEnvironment ??= new ir.TypeEnvironment(
+        new ir.CoreTypes(env.mainComponent), classHierarchy);
   }
 
   @override
   ir.ClassHierarchy get classHierarchy {
-    if (_classHierarchy == null) {
-      _classHierarchy ??= new ir.ClassHierarchy(env.mainComponent);
-    }
-    return _classHierarchy;
+    return _classHierarchy ??= new ir.ClassHierarchy(env.mainComponent);
+  }
+
+  Dart2jsConstantEvaluator get constantEvaluator {
+    return _constantEvaluator ??= new Dart2jsConstantEvaluator(typeEnvironment,
+        enableAsserts: options.enableUserAssertions,
+        environment: _environment.toMap());
   }
 
   @override
@@ -1021,7 +1025,17 @@
       bool implicitNull: false,
       bool checkCasts: true}) {
     if (node is ir.ConstantExpression) {
-      return node.constant.accept(new ConstantValuefier(this));
+      ir.Constant constant =
+          constantEvaluator.evaluate(node, requireConstant: requireConstant);
+      if (constant == null) {
+        if (requireConstant) {
+          throw new UnsupportedError(
+              'No constant for ${DebugPrinter.prettyPrint(node)}');
+        }
+        return null;
+      } else {
+        return constant.accept(new ConstantValuefier(this));
+      }
     }
 
     ConstantExpression constant;
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index ba5118a..75f2163 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -129,15 +129,12 @@
       .reportErrorMessage(spannable, MessageKind.GENERIC, {'text': message});
 }
 
-/// Display name used for compilation using the new common frontend.
-const String kernelName = 'kernel';
-
 /// Display name used for strong mode compilation using the new common frontend.
 const String strongName = 'strong mode';
 
 /// Display name used for strong mode compilation without implicit checks using
 /// the new common frontend.
-const String trustName = 'strong mode without implicit checks';
+const String omitName = 'strong mode without implicit checks';
 
 /// Compute actual data for all members defined in the program with the
 /// [entryPoint] and [memorySourceFiles].
@@ -421,21 +418,25 @@
         String expected = expectedValue?.toString() ?? '';
         String actual = dataValidator.getText(actualValue);
         int offset = getOffsetFromId(id, uri);
-        String value1 = '${expected}';
-        String value2 = IdValue.idToString(id, '${actual}');
-        annotations
-            .putIfAbsent(offset, () => [])
-            .add(colorizeDiff(value1, ' | ', value2));
+        if (offset != null) {
+          String value1 = '${expected}';
+          String value2 = IdValue.idToString(id, '${actual}');
+          annotations
+              .putIfAbsent(offset, () => [])
+              .add(colorizeDiff(value1, ' | ', value2));
+        }
       }
     });
     expectedMaps[uri].forEach((Id id, IdValue expected) {
       if (!actualMaps[uri].containsKey(id)) {
         int offset = getOffsetFromId(id, uri);
-        String value1 = '${expected}';
-        String value2 = '---';
-        annotations
-            .putIfAbsent(offset, () => [])
-            .add(colorizeDiff(value1, ' | ', value2));
+        if (offset != null) {
+          String value1 = '${expected}';
+          String value2 = '---';
+          annotations
+              .putIfAbsent(offset, () => [])
+              .add(colorizeDiff(value1, ' | ', value2));
+        }
       }
     });
     return withAnnotations(code[uri].sourceCode, annotations);
@@ -444,7 +445,7 @@
   int getOffsetFromId(Id id, Uri uri) {
     return compiler.reporter
         .spanFromSpannable(computeSpannable(elementEnvironment, uri, id))
-        .begin;
+        ?.begin;
   }
 }
 
@@ -530,6 +531,7 @@
     int shards: 1,
     int shardIndex: 0,
     bool testOmit: true,
+    bool testCFEConstants: false,
     void onTest(Uri uri)}) async {
   dataComputer.setup();
 
@@ -579,6 +581,8 @@
     Map<String, MemberAnnotations<IdValue>> expectedMaps = {
       strongMarker: new MemberAnnotations<IdValue>(),
       omitMarker: new MemberAnnotations<IdValue>(),
+      strongConstMarker: new MemberAnnotations<IdValue>(),
+      omitConstMarker: new MemberAnnotations<IdValue>(),
     };
     computeExpectedMap(entryPoint, code[entryPoint], expectedMaps);
     Map<String, String> memorySourceFiles = {
@@ -607,51 +611,79 @@
 
     if (setUpFunction != null) setUpFunction();
 
-    if (skipForStrong.contains(name)) {
-      print('--skipped for kernel (strong mode)----------------------------');
-    } else {
-      print('--from kernel (strong mode)-----------------------------------');
-      List<String> options = new List<String>.from(testOptions);
-      MemberAnnotations<IdValue> annotations = expectedMaps[strongMarker];
-      CompiledData<T> compiledData2 = await computeData(
-          entryPoint, memorySourceFiles, dataComputer,
-          options: options,
-          verbose: verbose,
-          printCode: printCode,
-          testFrontend: testFrontend,
-          forUserLibrariesOnly: forUserLibrariesOnly,
-          globalIds: annotations.globalData.keys);
-      if (await checkCode(strongName, entity.uri, code, annotations,
-          compiledData2, dataComputer.dataValidator,
-          filterActualData: filterActualData,
-          fatalErrors: !testAfterFailures)) {
-        hasFailures = true;
-      }
-    }
-    if (testOmit) {
+    Future runTests({bool useCFEConstants: false}) async {
       if (skipForStrong.contains(name)) {
-        print('--skipped for kernel (strong mode, omit-implicit-checks)------');
+        print('--skipped for kernel (strong mode)----------------------------');
       } else {
-        print('--from kernel (strong mode, omit-implicit-checks)-------------');
-        List<String> options = [
-          Flags.omitImplicitChecks,
-          Flags.laxRuntimeTypeToString
-        ]..addAll(testOptions);
-        MemberAnnotations<IdValue> annotations = expectedMaps[omitMarker];
+        print('--from kernel (strong mode)-----------------------------------');
+        List<String> options = new List<String>.from(testOptions);
+        String marker = strongMarker;
+        if (useCFEConstants) {
+          marker = strongConstMarker;
+          options
+              .add('${Flags.enableLanguageExperiments}=constant-update-2018');
+        } else {
+          options.add(
+              '${Flags.enableLanguageExperiments}=no-constant-update-2018');
+        }
+        MemberAnnotations<IdValue> annotations = expectedMaps[marker];
         CompiledData<T> compiledData2 = await computeData(
             entryPoint, memorySourceFiles, dataComputer,
             options: options,
             verbose: verbose,
+            printCode: printCode,
             testFrontend: testFrontend,
             forUserLibrariesOnly: forUserLibrariesOnly,
             globalIds: annotations.globalData.keys);
-        if (await checkCode(trustName, entity.uri, code, annotations,
+        if (await checkCode(strongName, entity.uri, code, annotations,
             compiledData2, dataComputer.dataValidator,
             filterActualData: filterActualData,
             fatalErrors: !testAfterFailures)) {
           hasFailures = true;
         }
       }
+      if (testOmit) {
+        if (skipForStrong.contains(name)) {
+          print(
+              '--skipped for kernel (strong mode, omit-implicit-checks)------');
+        } else {
+          print(
+              '--from kernel (strong mode, omit-implicit-checks)-------------');
+          List<String> options = [
+            Flags.omitImplicitChecks,
+            Flags.laxRuntimeTypeToString
+          ]..addAll(testOptions);
+          String marker = omitMarker;
+          if (useCFEConstants) {
+            marker = omitConstMarker;
+            options
+                .add('${Flags.enableLanguageExperiments}=constant-update-2018');
+          } else {
+            options.add(
+                '${Flags.enableLanguageExperiments}=no-constant-update-2018');
+          }
+          MemberAnnotations<IdValue> annotations = expectedMaps[marker];
+          CompiledData<T> compiledData2 = await computeData(
+              entryPoint, memorySourceFiles, dataComputer,
+              options: options,
+              verbose: verbose,
+              testFrontend: testFrontend,
+              forUserLibrariesOnly: forUserLibrariesOnly,
+              globalIds: annotations.globalData.keys);
+          if (await checkCode(omitName, entity.uri, code, annotations,
+              compiledData2, dataComputer.dataValidator,
+              filterActualData: filterActualData,
+              fatalErrors: !testAfterFailures)) {
+            hasFailures = true;
+          }
+        }
+      }
+    }
+
+    await runTests();
+    if (testCFEConstants) {
+      print('--use cfe constants---------------------------------------------');
+      await runTests(useCFEConstants: true);
     }
   }
   Expect.isFalse(hasFailures, 'Errors found.');
@@ -926,10 +958,11 @@
     }
     LibraryEntity library = elementEnvironment.lookupLibrary(mainUri);
     if (id.className != null) {
-      ClassEntity cls =
-          elementEnvironment.lookupClass(library, id.className, required: true);
+      ClassEntity cls = elementEnvironment.lookupClass(library, id.className);
       if (cls == null) {
-        throw new ArgumentError("No class '${id.className}' in $mainUri.");
+        // Constant expression in CFE might remove inlined parts of sources.
+        print("No class '${id.className}' in $mainUri.");
+        return NO_LOCATION_SPANNABLE;
       }
       MemberEntity member = elementEnvironment
           .lookupClassMember(cls, memberName, setter: isSetter);
@@ -937,7 +970,9 @@
         ConstructorEntity constructor =
             elementEnvironment.lookupConstructor(cls, memberName);
         if (constructor == null) {
-          throw new ArgumentError("No class member '${memberName}' in $cls.");
+          // Constant expression in CFE might remove inlined parts of sources.
+          print("No class member '${memberName}' in $cls.");
+          return NO_LOCATION_SPANNABLE;
         }
         return constructor;
       }
@@ -946,16 +981,19 @@
       MemberEntity member = elementEnvironment
           .lookupLibraryMember(library, memberName, setter: isSetter);
       if (member == null) {
-        throw new ArgumentError("No member '${memberName}' in $mainUri.");
+        // Constant expression in CFE might remove inlined parts of sources.
+        print("No member '${memberName}' in $mainUri.");
+        return NO_LOCATION_SPANNABLE;
       }
       return member;
     }
   } else if (id is ClassId) {
     LibraryEntity library = elementEnvironment.lookupLibrary(mainUri);
-    ClassEntity cls =
-        elementEnvironment.lookupClass(library, id.className, required: true);
+    ClassEntity cls = elementEnvironment.lookupClass(library, id.className);
     if (cls == null) {
-      throw new ArgumentError("No class '${id.className}' in $mainUri.");
+      // Constant expression in CFE might remove inlined parts of sources.
+      print("No class '${id.className}' in $mainUri.");
+      return NO_LOCATION_SPANNABLE;
     }
     return cls;
   }
@@ -964,6 +1002,8 @@
 
 const String strongMarker = 'strong.';
 const String omitMarker = 'omit.';
+const String strongConstMarker = 'strongConst.';
+const String omitConstMarker = 'omitConst.';
 
 /// Compute three [MemberAnnotations] objects from [code] specifying the
 /// expected annotations we anticipate encountering; one corresponding to the
@@ -980,7 +1020,7 @@
 /// annotations without prefixes.
 void computeExpectedMap(Uri sourceUri, AnnotatedCode code,
     Map<String, MemberAnnotations<IdValue>> maps) {
-  List<String> mapKeys = [strongMarker, omitMarker];
+  List<String> mapKeys = maps.keys.toList();
   Map<String, AnnotatedCode> split = splitByPrefixes(code, mapKeys);
 
   split.forEach((String marker, AnnotatedCode code) {
diff --git a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
index b2eb74d..27a4a61 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
@@ -3,13 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 enum Enum {
-  /*element: Enum.a:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.a"),index=IntConstant(0)))*/
+  /*strong.element: Enum.a:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.a"),index=IntConstant(0)))*/
   a,
 
-  /*element: Enum.b:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.b"),index=IntConstant(1)))*/
+  /*strong.element: Enum.b:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.b"),index=IntConstant(1)))*/
   b,
 
-  /*element: Enum.c:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
+  /*strong.element: Enum.c:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
   c,
 }
 
diff --git a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
index f7fd886..a04f242 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
@@ -113,7 +113,7 @@
   use(c2.field13b);
 }
 
-/*element: const1:constant=BoolConstant(true)*/
+/*strong.element: const1:constant=BoolConstant(true)*/
 const bool const1 = true;
 
 class Class1 {
diff --git a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
index 4e0c97f..deb273c 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
@@ -134,7 +134,7 @@
 /*element: field4b:constant=IntConstant(5)*/
 var field4b = 2 + 3;
 
-/*element: field4c:constant=IntConstant(5)*/
+/*strong.element: field4c:constant=IntConstant(5)*/
 const field4c = 2 + 3;
 
 /*element: field5a:constant=FunctionConstant(method)*/
@@ -143,7 +143,7 @@
 /*element: field5b:constant=FunctionConstant(method)*/
 var field5b = method;
 
-/*element: field5c:constant=FunctionConstant(method)*/
+/*strong.element: field5c:constant=FunctionConstant(method)*/
 const field5c = method;
 
 /*element: field6a:constant=ConstructedConstant(Class())*/
diff --git a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
index 09870a6..79b4cb0 100644
--- a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
@@ -18,7 +18,7 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('jdata'));
     await checkTests(dataDir, const JAllocatorAnalysisDataComputer(),
-        args: args, testOmit: false);
+        args: args, testOmit: false, testCFEConstants: true);
   });
 }
 
diff --git a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
index 8bf8e47..f6bff5f 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
@@ -7,7 +7,7 @@
   new Class2();
 }
 
-/*element: const1:complexity=constant,initial=BoolConstant(true)*/
+/*strong.element: const1:complexity=constant,initial=BoolConstant(true)*/
 const bool const1 = true;
 
 class Class1 {
diff --git a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
index 6f393ef..4096f9e 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
@@ -65,7 +65,7 @@
 /*element: field1b:complexity=constant,initial=IntConstant(0)*/
 var field1b = 0;
 
-/*element: field1c:complexity=constant,initial=IntConstant(0)*/
+/*strong.element: field1c:complexity=constant,initial=IntConstant(0)*/
 const field1c = 0;
 
 /*element: field2a:complexity=constant,initial=ListConstant([])*/
@@ -74,7 +74,7 @@
 /*element: field2b:complexity=constant,initial=ListConstant([])*/
 var field2b = const [];
 
-/*element: field2c:complexity=constant,initial=ListConstant([])*/
+/*strong.element: field2c:complexity=constant,initial=ListConstant([])*/
 const field2c = const [];
 
 /*element: field3a:complexity=eager*/
@@ -125,7 +125,7 @@
 /*element: field4b:complexity=lazy,initial=IntConstant(5)*/
 var field4b = 2 + 3;
 
-/*element: field4c:complexity=lazy,initial=IntConstant(5)*/
+/*strong.element: field4c:complexity=lazy,initial=IntConstant(5)*/
 const field4c = 2 + 3;
 
 /*element: field5a:complexity=constant,initial=FunctionConstant(method)*/
@@ -134,7 +134,7 @@
 /*element: field5b:complexity=constant,initial=FunctionConstant(method)*/
 var field5b = method;
 
-/*element: field5c:complexity=constant,initial=FunctionConstant(method)*/
+/*strong.element: field5c:complexity=constant,initial=FunctionConstant(method)*/
 const field5c = method;
 
 /*element: field6a:complexity=constant,initial=ConstructedConstant(Class())*/
diff --git a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
index dbcfcfd..559810d 100644
--- a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
@@ -18,7 +18,10 @@
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('kdata'));
     await checkTests(dataDir, const KAllocatorAnalysisDataComputer(),
-        args: args, testOmit: false, testFrontend: true);
+        args: args,
+        testOmit: false,
+        testFrontend: true,
+        testCFEConstants: true);
   });
 }
 
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
index b8cb04a..69792ef 100644
--- a/tests/compiler/dart2js/impact/data/async.dart
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -64,7 +64,7 @@
 */
 testAsyncStar() async* {}
 
-/*strong.element: testLocalSyncStar:
+/*element: testLocalSyncStar:
  static=[
   _IterationMarker.endOfIteration(0),
   _IterationMarker.uncaughtError(1),
@@ -88,7 +88,7 @@
   return local;
 }
 
-/*strong.element: testLocalAsync:
+/*element: testLocalAsync:
  static=[
   StreamIterator.(1),
   _asyncAwait(2),
@@ -115,7 +115,7 @@
   return local;
 }
 
-/*strong.element: testLocalAsyncStar:
+/*element: testLocalAsyncStar:
  static=[
   StreamIterator.(1),
   _IterationMarker.yieldSingle(1),
@@ -142,7 +142,7 @@
   return local;
 }
 
-/*strong.element: testAnonymousSyncStar:
+/*element: testAnonymousSyncStar:
  static=[
   _IterationMarker.endOfIteration(0),
   _IterationMarker.uncaughtError(1),
@@ -165,7 +165,7 @@
   return () sync* {};
 }
 
-/*strong.element: testAnonymousAsync:
+/*element: testAnonymousAsync:
  static=[
   StreamIterator.(1),
   _asyncAwait(2),
@@ -191,7 +191,7 @@
   return () async {};
 }
 
-/*strong.element: testAnonymousAsyncStar:
+/*element: testAnonymousAsyncStar:
  static=[
   StreamIterator.(1),
   _IterationMarker.yieldSingle(1),
@@ -217,7 +217,7 @@
   return () async* {};
 }
 
-/*strong.element: testAsyncForIn:
+/*element: testAsyncForIn:
  dynamic=[
   cancel(0),
   current,
@@ -241,7 +241,7 @@
   await for (var e in o) {}
 }
 
-/*strong.element: testAsyncForInTyped:
+/*element: testAsyncForInTyped:
  dynamic=[
   cancel(0),
   current,
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index ca5fc71..05ee3e1 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -137,7 +137,7 @@
 testForwardingConstructor() => new ForwardingConstructorClass(null);
 
 class ForwardingConstructorTypedSuperClass {
-  /*strong.element: ForwardingConstructorTypedSuperClass.:
+  /*element: ForwardingConstructorTypedSuperClass.:
    static=[Object.(0)],
    type=[inst:JSBool,param:int]
   */
@@ -154,7 +154,7 @@
 testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
 
 class ForwardingConstructorGenericSuperClass<T> {
-  /*strong.element: ForwardingConstructorGenericSuperClass.:
+  /*element: ForwardingConstructorGenericSuperClass.:
    static=[
     Object.(0),
     checkSubtype(4),
@@ -206,10 +206,11 @@
   A
 }
 
-/*element: testEnum:static=[Enum.A]*/
+/*strong.element: testEnum:static=[Enum.A]*/
+/*strongConst.element: testEnum:constant=[Enum(_name="Enum.A",index=0)]*/
 testEnum() => Enum.A;
 
-/*strong.element: staticGenericMethod:
+/*element: staticGenericMethod:
  static=[
   checkSubtype(4),
   checkSubtypeOfRuntimeType(2),
@@ -231,7 +232,7 @@
 */
 List<T> staticGenericMethod<T>(T arg) => [arg];
 
-/*strong.element: testStaticGenericMethod:
+/*element: testStaticGenericMethod:
   static=[staticGenericMethod<bool>(1)],
   type=[inst:JSBool]
 */
@@ -239,7 +240,7 @@
   staticGenericMethod<bool>(true);
 }
 
-/*strong.element: testInstanceGenericMethod:
+/*element: testInstanceGenericMethod:
  dynamic=[exact:GenericClass.genericMethod<bool>(1)],
  static=[
   GenericClass.generative(0),
@@ -255,7 +256,7 @@
   // ignore: UNUSED_FIELD
   final _field;
 
-  /*strong.element: AbstractClass.:type=[inst:JSNull]*/
+  /*element: AbstractClass.:type=[inst:JSNull]*/
   factory AbstractClass() => null;
 }
 
@@ -292,7 +293,7 @@
 class GenericClass<X, Y> {
   const GenericClass.generative();
 
-  /*strong.element: GenericClass.genericMethod:
+  /*element: GenericClass.genericMethod:
    static=[
     checkSubtype(4),
     checkSubtypeOfRuntimeType(2),
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index 60fb2ae..78631c3 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -104,22 +104,26 @@
   new GenericClass<dynamic, dynamic>.redirect();
 }
 
-/*element: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+/*strong.element: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+/*strongConst.element: testConstRedirectingFactoryInvoke:constant=[Class()]*/
 testConstRedirectingFactoryInvoke() {
   const Class.redirect();
 }
 
-/*element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*strong.element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*strongConst.element: testConstRedirectingFactoryInvokeGeneric:constant=[GenericClass<int, String>()]*/
 testConstRedirectingFactoryInvokeGeneric() {
   const GenericClass<int, String>.redirect();
 }
 
-/*element: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*strong.element: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*strongConst.element: testConstRedirectingFactoryInvokeGenericRaw:constant=[GenericClass()]*/
 testConstRedirectingFactoryInvokeGenericRaw() {
   const GenericClass.redirect();
 }
 
-/*element: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*strong.element: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*strongConst.element: testConstRedirectingFactoryInvokeGenericDynamic:constant=[GenericClass()]*/
 testConstRedirectingFactoryInvokeGenericDynamic() {
   const GenericClass<dynamic, dynamic>.redirect();
 }
@@ -131,7 +135,7 @@
 testImplicitConstructor() => new ClassImplicitConstructor();
 
 class ClassFactoryConstructor {
-  /*strong.element: ClassFactoryConstructor.:type=[inst:JSNull]*/
+  /*element: ClassFactoryConstructor.:type=[inst:JSNull]*/
   factory ClassFactoryConstructor() => null;
 }
 
@@ -142,7 +146,7 @@
   /*element: Class.generative:static=[Object.(0)]*/
   const Class.generative();
 
-  /*strong.element: Class.fact:type=[inst:JSNull]*/
+  /*element: Class.fact:type=[inst:JSNull]*/
   factory Class.fact() => null;
 
   const factory Class.redirect() = Class.generative;
@@ -152,7 +156,7 @@
   /*element: GenericClass.generative:static=[Object.(0)]*/
   const GenericClass.generative();
 
-  /*strong.element: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
+  /*element: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
   factory GenericClass.fact() => null;
 
   const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index d8e2fd5..b27ae7c 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -29,9 +29,11 @@
 }
 
 /*strong.element: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
+/*strongConst.element: testDefaultValuesPositional:constant=[false],type=[inst:JSBool,param:bool]*/
 testDefaultValuesPositional([bool value = false]) {}
 
 /*strong.element: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
+/*strongConst.element: testDefaultValuesNamed:constant=[false],type=[inst:JSBool,param:bool]*/
 testDefaultValuesNamed({bool value: false}) {}
 
 class ClassFieldInitializer1 {
@@ -84,7 +86,7 @@
 
 /*element: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
 class ClassInstanceFieldWithInitializer {
-  /*strong.element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
+  /*element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
   var field = false;
 }
 
@@ -93,7 +95,7 @@
 
 /*element: ClassInstanceFieldTyped.:static=[Object.(0)]*/
 class ClassInstanceFieldTyped {
-  /*strong.element: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
+  /*element: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
   int field;
 }
 
@@ -120,7 +122,7 @@
 testSuperInitializer() => new ClassSuperInitializer();
 
 class ClassGeneric<T> {
-  /*strong.element: ClassGeneric.:
+  /*element: ClassGeneric.:
    static=[
     Object.(0),
     checkSubtype(4),
diff --git a/tests/compiler/dart2js/impact/data/injected_cast.dart b/tests/compiler/dart2js/impact/data/injected_cast.dart
index 526414c..d1f6e23 100644
--- a/tests/compiler/dart2js/impact/data/injected_cast.dart
+++ b/tests/compiler/dart2js/impact/data/injected_cast.dart
@@ -54,7 +54,8 @@
 
 /*element: Class3.:static=[Object.(0)]*/
 class Class3 {
-  /*element: Class3.method3:type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+  /*strong.element: Class3.method3:type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+  /*strongConst.element: Class3.method3:constant=[null],type=[inst:JSBool,param:A,param:B,param:C]*/
   method3(A a, [B b, C c]) {}
 }
 
@@ -74,9 +75,13 @@
 
 /*element: Class4.:static=[Object.(0)]*/
 class Class4 {
-  /*element: Class4.method4:
+  /*strong.element: Class4.method4:
    type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]
   */
+  /*strongConst.element: Class4.method4:
+    constant=[null],
+    type=[inst:JSBool,param:A,param:B,param:C]
+  */
   method4(A a, {B b, C c}) {}
 }
 
@@ -96,7 +101,19 @@
 
 /*element: Class5.:static=[Object.(0)]*/
 class Class5<T1, T2> {
-  /*element: Class5.method5:
+  /*strong.element: Class5.method5:
+   static=*,
+   type=[
+    inst:*,
+    param:C,
+    param:Class5.T1,
+    param:Class5.T2,
+    param:Object,
+    param:method5.S1,
+    param:method5.S2]
+  */
+  /*strongConst.element: Class5.method5:
+   constant=[null],
    static=*,
    type=[
     inst:*,
@@ -129,7 +146,19 @@
 
 /*element: Class6.:static=[Object.(0)]*/
 class Class6<T1, T2> {
-  /*element: Class6.method6:
+  /*strong.element: Class6.method6:
+   static=*,
+   type=[
+    inst:*,
+    param:C,
+    param:Class6.T1,
+    param:Class6.T2,
+    param:Object,
+    param:method6.S1,
+    param:method6.S2]
+  */
+  /*strongConst.element: Class6.method6:
+   constant=[null],
    static=*,
    type=[
     inst:*,
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index aa2b472..3a3d115 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -78,10 +78,12 @@
 /*element: topLevelFunction1:*/
 topLevelFunction1(a) {}
 
-/*element: topLevelFunction2:type=[inst:JSNull]*/
+/*strong.element: topLevelFunction2:type=[inst:JSNull]*/
+/*strongConst.element: topLevelFunction2:constant=[null]*/
 topLevelFunction2(a, [b, c]) {}
 
-/*element: topLevelFunction3:type=[inst:JSNull]*/
+/*strong.element: topLevelFunction3:type=[inst:JSNull]*/
+/*strongConst.element: topLevelFunction3:constant=[null]*/
 topLevelFunction3(a, {b, c}) {}
 
 /*element: testTopLevelInvoke:
@@ -115,7 +117,7 @@
   topLevelFunction3(15, c: 16, b: 17);
 }
 
-/*strong.element: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
+/*element: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
 void topLevelFunction1Typed(int a) {}
 
 /*strong.element: topLevelFunction2Typed:
@@ -126,6 +128,15 @@
   param:double,
   param:num]
 */
+/*strongConst.element: topLevelFunction2Typed:
+ constant=[null],
+ type=[
+  inst:JSBool,
+  inst:JSNull,
+  param:String,
+  param:double,
+  param:num]
+*/
 int topLevelFunction2Typed(String a, [num b, double c]) => null;
 
 /*strong.element: topLevelFunction3Typed:
@@ -148,11 +159,32 @@
   param:Map<String,bool>,
   param:bool]
 */
+/*strongConst.element: topLevelFunction3Typed:
+ constant=[null],
+ static=[
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
+ type=[
+  inst:JSArray<dynamic>,
+  inst:JSBool,
+  inst:JSExtendableArray<dynamic>,
+  inst:JSFixedArray<dynamic>,
+  inst:JSMutableArray<dynamic>,
+  inst:JSNull,
+  inst:JSUnmodifiableArray<dynamic>,
+  param:List<int>,
+  param:Map<String,bool>,
+  param:bool]
+*/
 double topLevelFunction3Typed(bool a, {List<int> b, Map<String, bool> c}) {
   return null;
 }
 
-/*strong.element: testTopLevelInvokeTyped:
+/*element: testTopLevelInvokeTyped:
  static=[
   topLevelFunction1Typed(1),
   topLevelFunction2Typed(1),
@@ -188,7 +220,7 @@
   topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
 }
 
-/*strong.element: topLevelFunctionTyped1:
+/*element: topLevelFunctionTyped1:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -207,7 +239,7 @@
 */
 topLevelFunctionTyped1(void a(num b)) {}
 
-/*strong.element: topLevelFunctionTyped2:
+/*element: topLevelFunctionTyped2:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -226,7 +258,7 @@
 */
 topLevelFunctionTyped2(void a(num b, [String c])) {}
 
-/*strong.element: topLevelFunctionTyped3:
+/*element: topLevelFunctionTyped3:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -245,7 +277,7 @@
 */
 topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
 
-/*strong.element: topLevelFunctionTyped4:
+/*element: topLevelFunctionTyped4:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -279,7 +311,8 @@
   topLevelFunctionTyped4(null);
 }
 
-/*element: testTopLevelFunctionGet:static=[topLevelFunction1]*/
+/*strong.element: testTopLevelFunctionGet:static=[topLevelFunction1]*/
+/*strongConst.element: testTopLevelFunctionGet:constant=[topLevelFunction1]*/
 testTopLevelFunctionGet() => topLevelFunction1;
 
 /*element: topLevelGetter:type=[inst:JSNull]*/
@@ -288,7 +321,7 @@
 /*element: testTopLevelGetterGet:static=[topLevelGetter]*/
 testTopLevelGetterGet() => topLevelGetter;
 
-/*strong.element: topLevelGetterTyped:type=[inst:JSNull]*/
+/*element: topLevelGetterTyped:type=[inst:JSNull]*/
 int get topLevelGetterTyped => null;
 
 /*element: testTopLevelGetterGetTyped:static=[topLevelGetterTyped]*/
@@ -300,7 +333,7 @@
 /*element: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
 testTopLevelSetterSet() => topLevelSetter = null;
 
-/*strong.element: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
+/*element: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
 void set topLevelSetterTyped(int value) {}
 
 /*element: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
@@ -318,10 +351,11 @@
 /*element: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
 testTopLevelFieldLazy() => topLevelFieldLazy;
 
-/*element: topLevelFieldConst:type=[inst:JSNull]*/
+/*strong.element: topLevelFieldConst:type=[inst:JSNull]*/
 const topLevelFieldConst = null;
 
-/*element: testTopLevelFieldConst:static=[topLevelFieldConst]*/
+/*strong.element: testTopLevelFieldConst:static=[topLevelFieldConst]*/
+/*strongConst.element: testTopLevelFieldConst:constant=[null]*/
 testTopLevelFieldConst() => topLevelFieldConst;
 
 /*element: topLevelFieldFinal:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
@@ -330,25 +364,25 @@
 /*element: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
 testTopLevelFieldFinal() => topLevelFieldFinal;
 
-/*strong.element: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
+/*element: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
 int topLevelFieldTyped;
 
 /*element: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
 testTopLevelFieldTyped() => topLevelFieldTyped;
 
-/*strong.element: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*element: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
 GenericClass topLevelFieldGeneric1;
 
 /*element: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
 testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
 
-/*strong.element: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*element: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
 GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
 
 /*element: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
 testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
 
-/*strong.element: topLevelFieldGeneric3:
+/*element: topLevelFieldGeneric3:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -379,7 +413,8 @@
   static foo() {}
 }
 
-/*element: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
+/*strong.element: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
+/*strongConst.element: testStaticFunctionGet:constant=[StaticFunctionGetClass.foo]*/
 testStaticFunctionGet() => StaticFunctionGetClass.foo;
 
 /*element: testDynamicInvoke:
@@ -456,7 +491,7 @@
   var l = 42;
 }
 
-/*strong.element: testLocalWithInitializerTyped:
+/*element: testLocalWithInitializerTyped:
  type=[
   inst:JSDouble,
   inst:JSInt,
@@ -470,7 +505,7 @@
   int l = 42;
 }
 
-/*strong.element: testLocalFunction:
+/*element: testLocalFunction:
  static=[
   computeSignature(3),
   def:localFunction,
@@ -490,7 +525,7 @@
   localFunction() {}
 }
 
-/*strong.element: testLocalFunctionTyped:
+/*element: testLocalFunctionTyped:
  static=[
   computeSignature(3),
   def:localFunction,
@@ -511,7 +546,7 @@
   int localFunction(String a) => null;
 }
 
-/*strong.element: testLocalFunctionInvoke:
+/*element: testLocalFunctionInvoke:
  dynamic=[call(0)],
  static=[computeSignature(3),
   def:localFunction,
@@ -530,7 +565,7 @@
   localFunction();
 }
 
-/*strong.element: testLocalFunctionGet:static=[computeSignature(3),
+/*element: testLocalFunctionGet:static=[computeSignature(3),
   def:localFunction,
   getRuntimeTypeArguments(3),
   getRuntimeTypeInfo(1),
@@ -546,7 +581,7 @@
   localFunction;
 }
 
-/*strong.element: testClosure:static=[computeSignature(3),
+/*element: testClosure:static=[computeSignature(3),
   def:<anonymous>,
   getRuntimeTypeArguments(3),
   getRuntimeTypeInfo(1),
@@ -561,7 +596,7 @@
   () {};
 }
 
-/*strong.element: testClosureInvoke:
+/*element: testClosureInvoke:
  dynamic=[call(0)],
  static=[computeSignature(3),
   def:<anonymous>,
@@ -602,10 +637,14 @@
 */
 testInvokeIndexSet(o) => o[42] = null;
 
-/*element: testDynamicPrivateMethodInvoke:
+/*strong.element: testDynamicPrivateMethodInvoke:
  dynamic=[_privateMethod(0),call(0)],
  type=[inst:JSNull]
 */
+/*strongConst.element: testDynamicPrivateMethodInvoke:
+ constant=[null],
+ dynamic=[_privateMethod(0),call(0)]
+*/
 testDynamicPrivateMethodInvoke([o]) => o._privateMethod();
 
 class GenericClass<X, Y> {}
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index 8e77d6ac..e6e9adf 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -7,14 +7,19 @@
 
 import 'package:js/js.dart';
 
-/*element: main:static=[testJsInteropClass(0),testJsInteropMethod(0),testOptionalGenericFunctionTypeArgument(0)]*/
+/*element: main:
+ static=[
+  testJsInteropClass(0),
+  testJsInteropMethod(0),
+  testOptionalGenericFunctionTypeArgument(0)]
+*/
 main() {
   testOptionalGenericFunctionTypeArgument();
   testJsInteropMethod();
   testJsInteropClass();
 }
 
-/*strong.element: testJsInteropMethod:*/
+/*element: testJsInteropMethod:*/
 @JS()
 external int testJsInteropMethod();
 
@@ -23,7 +28,7 @@
   /*element: JsInteropClass.:static=[JavaScriptObject.(0)]*/
   external JsInteropClass();
 
-  /*strong.element: JsInteropClass.method:
+  /*element: JsInteropClass.method:
    type=[
     native:ApplicationCacheErrorEvent,
     native:DomError,
@@ -43,7 +48,7 @@
   external double method();
 }
 
-/*strong.element: testJsInteropClass:
+/*element: testJsInteropClass:
  dynamic=[JavaScriptObject.method(0)],
  static=[JsInteropClass.(0)]
 */
@@ -72,10 +77,28 @@
     inst:JSUnmodifiableArray<dynamic>,
     param:void Function(GenericClass.T)]
   */
+  /*strongConst.element: GenericClass.method:
+   constant=[null],
+   static=[
+    checkSubtype(4),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    setRuntimeTypeInfo(2)],
+   type=[
+    inst:JSArray<dynamic>,
+    inst:JSBool,
+    inst:JSExtendableArray<dynamic>,
+    inst:JSFixedArray<dynamic>,
+    inst:JSMutableArray<dynamic>,
+    inst:JSUnmodifiableArray<dynamic>,
+    param:void Function(GenericClass.T)]
+  */
   external GenericClass method([Callback<T> callback]);
 }
 
-/*strong.element: testOptionalGenericFunctionTypeArgument:
+/*element: testOptionalGenericFunctionTypeArgument:
  dynamic=[JavaScriptObject.method(0)],
  static=[GenericClass.(0)]
 */
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index 925896a0..0c1710d 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -86,10 +86,11 @@
 */
 testStringInterpolation() => '${true}';
 
-/*element: testStringInterpolationConst:
+/*strong.element: testStringInterpolationConst:
  dynamic=[toString(0)],
  static=[S(1)],type=[inst:JSBool,inst:JSString]
 */
+/*strongConst.element: testStringInterpolationConst:constant=["true"]*/
 testStringInterpolationConst() {
   const b = '${true}';
   return b;
@@ -102,13 +103,15 @@
 */
 testStringJuxtaposition() => 'a' 'b';
 
-/*element: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.element: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.element: testSymbol:constant=[Symbol(_name="main")]*/
 testSymbol() => #main;
 
-/*element: testConstSymbol:
+/*strong.element: testConstSymbol:
  static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
  type=[inst:JSString,inst:Symbol]
 */
+/*strongConst.element: testConstSymbol:constant=[Symbol(_name="main")]*/
 testConstSymbol() => const Symbol('main');
 
 /*strong.element: complexSymbolField1:
@@ -190,13 +193,15 @@
  static=[Symbol.(1),Symbol.(1),Symbol.validated(1),complexSymbolField],
  type=[impl:String,inst:JSBool,inst:Symbol]
 */
+/*strongConst.element: testComplexConstSymbol:constant=[Symbol(_name="truefalsetruenull")]*/
 testComplexConstSymbol() => const Symbol(complexSymbolField);
 
-/*element: testIfNullConstSymbol:
+/*strong.element: testIfNullConstSymbol:
  dynamic=[Null.==],
  static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
  type=[inst:JSNull,inst:JSString,inst:Symbol]
 */
+/*strongConst.element: testIfNullConstSymbol:constant=[Symbol(_name="foo")]*/
 testIfNullConstSymbol() => const Symbol(null ?? 'foo');
 
 /*element: testTypeLiteral:
@@ -205,7 +210,8 @@
 */
 testTypeLiteral() => Object;
 
-/*element: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
+/*strong.element: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
+/*strongConst.element: testBoolFromEnvironment:constant=[false]*/
 testBoolFromEnvironment() => const bool.fromEnvironment('FOO');
 
 /*element: testEmptyListLiteral:type=[inst:List<dynamic>]*/
@@ -214,13 +220,14 @@
 /*element: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
 testEmptyListLiteralDynamic() => <dynamic>[];
 
-/*strong.element: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+/*element: testEmptyListLiteralTyped:type=[inst:List<String>]*/
 testEmptyListLiteralTyped() => <String>[];
 
-/*element: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
+/*strong.element: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
+/*strongConst.element: testEmptyListLiteralConstant:constant=[[]]*/
 testEmptyListLiteralConstant() => const [];
 
-/*strong.element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
 testNonEmptyListLiteral() => [true];
 
 /*element: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
@@ -229,21 +236,22 @@
 /*element: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
 testEmptyMapLiteralDynamic() => <dynamic, dynamic>{};
 
-/*strong.element: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+/*element: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
 testEmptyMapLiteralTyped() => <String, int>{};
 
-/*element: testEmptyMapLiteralConstant:
+/*strong.element: testEmptyMapLiteralConstant:
 type=[
  inst:ConstantMap<dynamic,dynamic>,
  inst:ConstantProtoMap<dynamic,dynamic>,
  inst:ConstantStringMap<dynamic,dynamic>,
  inst:GeneralConstantMap<dynamic,dynamic>]*/
+/*strongConst.element: testEmptyMapLiteralConstant:constant=[{}]*/
 testEmptyMapLiteralConstant() => const {};
 
-/*strong.element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+/*element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
 testNonEmptyMapLiteral() => {null: true};
 
 class GenericClass<X, Y> {
-  /*element: GenericClass.generative:static=[Object.(0)]*/
+  /*strong.element: GenericClass.generative:static=[Object.(0)]*/
   const GenericClass.generative();
 }
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index b314794..2e67bb6 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -22,7 +22,7 @@
   testNativeMethodReturns();
 }
 
-/*strong.element: testJSCall:
+/*element: testJSCall:
  static=[JS<dynamic>(3)],
  type=[inst:JSNull,inst:JSString,native:bool,native:int]
 */
@@ -68,6 +68,10 @@
     native:int,
     param:Object]
   */
+  // TODO(johnniwinther): The metadata is defined in dart:html_common and
+  // therefore derived from platform.dill which doesn't currently include IR
+  // constants.
+  /*strongConst.element: NativeClass.field:type=[inst:JSBool,inst:JSNull,param:Object]*/
   @annotation_Creates_SerializedScriptValue
   final Object field;
 
@@ -76,7 +80,7 @@
   }
 }
 
-/*strong.element: testNativeField:
+/*element: testNativeField:
  dynamic=[NativeClass.field],
  static=[defineProperty(3)],
  type=[inst:JSBool,param:NativeClass]
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
index 4603006..5385f1c 100644
--- a/tests/compiler/dart2js/impact/data/statements.dart
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -65,7 +65,7 @@
     return 1;
 }
 
-/*strong.element: testForIn:
+/*element: testForIn:
  dynamic=[
   current,
   iterator,
@@ -82,7 +82,7 @@
   for (var e in o) {}
 }
 
-/*strong.element: testForInTyped:
+/*element: testForInTyped:
  dynamic=[
   current,
   iterator,
@@ -142,7 +142,21 @@
   try {} finally {}
 }
 
-/*element: testSwitchWithoutFallthrough:
+/*strong.element: testSwitchWithoutFallthrough:
+ static=[
+  throwExpression(1),
+  wrapException(1)],
+ type=[
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
+/*strongConst.element: testSwitchWithoutFallthrough:
+ constant=[0,1,2,3,4],
  static=[
   throwExpression(1),
   wrapException(1)],
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index 1237e4c..54694cd 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -30,7 +30,10 @@
     print('==================================================================');
     useImpactDataForTesting = true;
     await checkTests(dataDir, const ImpactDataComputer(),
-        args: args, testOmit: false, testFrontend: true);
+        args: args,
+        testOmit: false,
+        testFrontend: true,
+        testCFEConstants: true);
   });
 }