Record interfaceTargets for calls on dynamic receivers

When calling Object methods on dynamic receivers, record the
interfaceTarget it Kernel.  Back ends will use this to treat the call
as a statically typed one.  This is half of the problem in
https://github.com/dart-lang/sdk/issues/33293

Bug: https://github.com/dart-lang/sdk/issues/33293
Change-Id: I8d05903e5b85370a4e697ad3afc494cbc14bcc6a
Reviewed-on: https://dart-review.googlesource.com/57820
Commit-Queue: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index b19563b..e9b987e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -633,6 +633,11 @@
             return null;
           }
         }
+        if (instrumentation != null && !silent) {
+          instrumentation.record(uri, methodInvocation.fileOffset, 'target',
+              new InstrumentationValueForMember(interfaceMember));
+        }
+        methodInvocation.interfaceTarget = interfaceMember;
       } else if (strongMode && interfaceMember is Member) {
         methodInvocation.interfaceTarget = interfaceMember;
       }
@@ -665,9 +670,13 @@
           expression: propertyGet,
           receiver: propertyGet.receiver,
           silent: silent);
-      if (strongMode &&
-          receiverType != const DynamicType() &&
-          interfaceMember is Member) {
+      if (strongMode && interfaceMember is Member) {
+        if (instrumentation != null &&
+            !silent &&
+            receiverType == const DynamicType()) {
+          instrumentation.record(uri, propertyGet.fileOffset, 'target',
+              new InstrumentationValueForMember(interfaceMember));
+        }
         propertyGet.interfaceTarget = interfaceMember;
       }
       return interfaceMember;
@@ -698,9 +707,13 @@
           receiver: propertySet.receiver,
           setter: true,
           silent: silent);
-      if (strongMode &&
-          receiverType != const DynamicType() &&
-          interfaceMember is Member) {
+      if (strongMode && interfaceMember is Member) {
+        if (instrumentation != null &&
+            !silent &&
+            receiverType == const DynamicType()) {
+          instrumentation.record(uri, propertySet.fileOffset, 'target',
+              new InstrumentationValueForMember(interfaceMember));
+        }
         propertySet.interfaceTarget = interfaceMember;
       }
       return interfaceMember;
@@ -1379,9 +1392,11 @@
           errorTemplate: templateUndefinedGetter,
           expression: expression,
           receiver: receiver);
-      if (strongMode &&
-          receiverType != const DynamicType() &&
-          interfaceMember is Member) {
+      if (strongMode && interfaceMember is Member) {
+        if (instrumentation != null && receiverType == const DynamicType()) {
+          instrumentation.record(uri, desugaredGet.fileOffset, 'target',
+              new InstrumentationValueForMember(interfaceMember));
+        }
         desugaredGet.interfaceTarget = interfaceMember;
       }
     }
diff --git a/pkg/front_end/testcases/bug32414a.dart b/pkg/front_end/testcases/bug32414a.dart
index 825acca..06a517c 100644
--- a/pkg/front_end/testcases/bug32414a.dart
+++ b/pkg/front_end/testcases/bug32414a.dart
@@ -2,9 +2,11 @@
 // 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.
 
+/*@testedFeatures=inference*/
+
 void test() {
   dynamic a = 5;
-  var b = a.toString();
+  var /*@type=String*/ b = a. /*@target=Object::toString*/ toString();
   b = 42;
 }
 
diff --git a/pkg/front_end/testcases/bug32414a.dart.strong.expect b/pkg/front_end/testcases/bug32414a.dart.strong.expect
index ec5a9ff..3e11c16 100644
--- a/pkg/front_end/testcases/bug32414a.dart.strong.expect
+++ b/pkg/front_end/testcases/bug32414a.dart.strong.expect
@@ -4,8 +4,8 @@
 
 static method test() → void {
   dynamic a = 5;
-  core::String b = a.toString();
-  b = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bug32414a.dart:8:7: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+  core::String b = a.{core::Object::toString}();
+  b = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bug32414a.dart:10:7: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
 Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
   b = 42;
       ^" in let final dynamic #t2 = 42 in null;
diff --git a/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect b/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect
index d4377bc..96b25c6 100644
--- a/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect
@@ -4,8 +4,8 @@
 
 static method test() → void {
   dynamic a = 5;
-  core::String b = a.toString();
-  b = let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bug32414a.dart:8:7: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+  core::String b = a.{core::Object::toString}();
+  b = let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bug32414a.dart:10:7: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
 Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
   b = 42;
       ^" in let final core::int #t2 = 42 in null;
diff --git a/pkg/front_end/testcases/bug32414b.dart b/pkg/front_end/testcases/bug32414b.dart
index 4f1ab51..a9a0a7e 100644
--- a/pkg/front_end/testcases/bug32414b.dart
+++ b/pkg/front_end/testcases/bug32414b.dart
@@ -2,9 +2,15 @@
 // 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.
 
+/*@testedFeatures=inference*/
+
 void test() {
-  List<dynamic> l = [1, "hello"];
-  List<String> l2 = l.map((dynamic element) => element.toString()).toList();
+  List<dynamic> l = /*@typeArgs=dynamic*/ [1, "hello"];
+  List<String> l2 = l
+      . /*@target=Iterable::map*/ /*@typeArgs=String*/ map(
+          /*@returnType=String*/ (dynamic element) =>
+              element. /*@target=Object::toString*/ toString())
+      . /*@target=Iterable::toList*/ toList();
 }
 
 void main() {}
diff --git a/pkg/front_end/testcases/bug32414b.dart.strong.expect b/pkg/front_end/testcases/bug32414b.dart.strong.expect
index b5242ff..6a5fde9 100644
--- a/pkg/front_end/testcases/bug32414b.dart.strong.expect
+++ b/pkg/front_end/testcases/bug32414b.dart.strong.expect
@@ -4,6 +4,6 @@
 
 static method test() → void {
   core::List<dynamic> l = <dynamic>[1, "hello"];
-  core::List<core::String> l2 = l.{core::Iterable::map}<core::String>((dynamic element) → core::String => element.toString()).{core::Iterable::toList}();
+  core::List<core::String> l2 = l.{core::Iterable::map}<core::String>((dynamic element) → core::String => element.{core::Object::toString}()).{core::Iterable::toList}();
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/bug32414b.dart.strong.transformed.expect b/pkg/front_end/testcases/bug32414b.dart.strong.transformed.expect
index b5242ff..6a5fde9 100644
--- a/pkg/front_end/testcases/bug32414b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug32414b.dart.strong.transformed.expect
@@ -4,6 +4,6 @@
 
 static method test() → void {
   core::List<dynamic> l = <dynamic>[1, "hello"];
-  core::List<core::String> l2 = l.{core::Iterable::map}<core::String>((dynamic element) → core::String => element.toString()).{core::Iterable::toList}();
+  core::List<core::String> l2 = l.{core::Iterable::map}<core::String>((dynamic element) → core::String => element.{core::Object::toString}()).{core::Iterable::toList}();
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart b/pkg/front_end/testcases/inference/dynamic_methods.dart
index 116b700..509a8f3 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart
@@ -11,21 +11,24 @@
 
 test() {
   dynamic d = new Foo();
-  var /*@type=int*/ get_hashCode = d.hashCode;
-  var /*@type=dynamic*/ call_hashCode = d.hashCode();
-  var /*@type=String*/ call_toString = d.toString();
+  var /*@type=int*/ get_hashCode = d. /*@target=Object::hashCode*/ hashCode;
+  var /*@type=dynamic*/ call_hashCode =
+      d. /*@target=Object::hashCode*/ hashCode();
+  var /*@type=String*/ call_toString =
+      d. /*@target=Object::toString*/ toString();
   var /*@type=dynamic*/ call_toStringArg = d.toString(color: "pink");
   var /*@type=dynamic*/ call_foo0 = d.foo();
   var /*@type=dynamic*/ call_foo1 = d.foo(1);
   var /*@type=dynamic*/ call_foo2 = d.foo(1, 2);
   var /*@type=dynamic*/ call_nsm0 = d.noSuchMethod();
-  var /*@type=dynamic*/ call_nsm1 = d.noSuchMethod(null);
+  var /*@type=dynamic*/ call_nsm1 =
+      d. /*@target=Object::noSuchMethod*/ noSuchMethod(null);
   var /*@type=dynamic*/ call_nsm2 = d.noSuchMethod(null, null);
-  var /*@type=bool*/ equals_self = d == d;
-  var /*@type=bool*/ equals_null = d == null;
+  var /*@type=bool*/ equals_self = d /*@target=Object::==*/ == d;
+  var /*@type=bool*/ equals_null = d /*@target=Object::==*/ == null;
   var /*@type=bool*/ null_equals = null /*@target=Object::==*/ == d;
-  var /*@type=bool*/ not_equals_self = d != d;
-  var /*@type=bool*/ not_equals_null = d != null;
+  var /*@type=bool*/ not_equals_self = d /*@target=Object::==*/ != d;
+  var /*@type=bool*/ not_equals_null = d /*@target=Object::==*/ != null;
   var /*@type=bool*/ null_not_equals = null /*@target=Object::==*/ != d;
 }
 
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
index fcc146a..452d130 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
@@ -11,21 +11,21 @@
 }
 static method test() → dynamic {
   dynamic d = new self::Foo::•();
-  core::int get_hashCode = d.hashCode;
-  dynamic call_hashCode = d.hashCode();
-  core::String call_toString = d.toString();
+  core::int get_hashCode = d.{core::Object::hashCode};
+  dynamic call_hashCode = d.{core::Object::hashCode}();
+  core::String call_toString = d.{core::Object::toString}();
   dynamic call_toStringArg = d.toString(color: "pink");
   dynamic call_foo0 = d.foo();
   dynamic call_foo1 = d.foo(1);
   dynamic call_foo2 = d.foo(1, 2);
   dynamic call_nsm0 = d.noSuchMethod();
-  dynamic call_nsm1 = d.noSuchMethod(null);
+  dynamic call_nsm1 = d.{core::Object::noSuchMethod}(null);
   dynamic call_nsm2 = d.noSuchMethod(null, null);
-  core::bool equals_self = d.==(d);
-  core::bool equals_null = d.==(null);
+  core::bool equals_self = d.{core::Object::==}(d);
+  core::bool equals_null = d.{core::Object::==}(null);
   core::bool null_equals = null.{core::Object::==}(d);
-  core::bool not_equals_self = !d.==(d);
-  core::bool not_equals_null = !d.==(null);
+  core::bool not_equals_self = !d.{core::Object::==}(d);
+  core::bool not_equals_null = !d.{core::Object::==}(null);
   core::bool null_not_equals = !null.{core::Object::==}(d);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
index fcc146a..452d130 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
@@ -11,21 +11,21 @@
 }
 static method test() → dynamic {
   dynamic d = new self::Foo::•();
-  core::int get_hashCode = d.hashCode;
-  dynamic call_hashCode = d.hashCode();
-  core::String call_toString = d.toString();
+  core::int get_hashCode = d.{core::Object::hashCode};
+  dynamic call_hashCode = d.{core::Object::hashCode}();
+  core::String call_toString = d.{core::Object::toString}();
   dynamic call_toStringArg = d.toString(color: "pink");
   dynamic call_foo0 = d.foo();
   dynamic call_foo1 = d.foo(1);
   dynamic call_foo2 = d.foo(1, 2);
   dynamic call_nsm0 = d.noSuchMethod();
-  dynamic call_nsm1 = d.noSuchMethod(null);
+  dynamic call_nsm1 = d.{core::Object::noSuchMethod}(null);
   dynamic call_nsm2 = d.noSuchMethod(null, null);
-  core::bool equals_self = d.==(d);
-  core::bool equals_null = d.==(null);
+  core::bool equals_self = d.{core::Object::==}(d);
+  core::bool equals_null = d.{core::Object::==}(null);
   core::bool null_equals = null.{core::Object::==}(d);
-  core::bool not_equals_self = !d.==(d);
-  core::bool not_equals_null = !d.==(null);
+  core::bool not_equals_self = !d.{core::Object::==}(d);
+  core::bool not_equals_null = !d.{core::Object::==}(null);
   core::bool null_not_equals = !null.{core::Object::==}(d);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/mixin_super_repeated.dart.strong.expect b/pkg/front_end/testcases/mixin_super_repeated.dart.strong.expect
index 4ece1f0..2050a52 100644
--- a/pkg/front_end/testcases/mixin_super_repeated.dart.strong.expect
+++ b/pkg/front_end/testcases/mixin_super_repeated.dart.strong.expect
@@ -36,10 +36,10 @@
   self::Named named = new self::Named::•();
   named.{self::M::m} = 42;
   named.{self::N::superM} = 87;
-  if(!named.{self::M::m}.==(42)) {
+  if(!named.{self::M::m}.{core::Object::==}(42)) {
     throw "Bad mixin translation of set:superM";
   }
-  if(!named.{self::N::superM}.==(87)) {
+  if(!named.{self::N::superM}.{core::Object::==}(87)) {
     throw "Bad mixin translation of get:superM";
   }
 }
diff --git a/pkg/front_end/testcases/mixin_super_repeated.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_super_repeated.dart.strong.transformed.expect
index 722cdb3..1bead45 100644
--- a/pkg/front_end/testcases/mixin_super_repeated.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/mixin_super_repeated.dart.strong.transformed.expect
@@ -49,10 +49,10 @@
   self::Named named = new self::Named::•();
   named.{self::M::m} = 42;
   named.{self::N::superM} = 87;
-  if(!named.{self::M::m}.==(42)) {
+  if(!named.{self::M::m}.{core::Object::==}(42)) {
     throw "Bad mixin translation of set:superM";
   }
-  if(!named.{self::N::superM}.==(87)) {
+  if(!named.{self::N::superM}.{core::Object::==}(87)) {
     throw "Bad mixin translation of get:superM";
   }
 }
diff --git a/pkg/front_end/testcases/rasta/super.dart.strong.expect b/pkg/front_end/testcases/rasta/super.dart.strong.expect
index a3c04bd..05c0a32 100644
--- a/pkg/front_end/testcases/rasta/super.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.strong.expect
@@ -215,30 +215,30 @@
     self::use(super.m = 42);
     super.{self::A::n} = 42;
     self::use(super.{self::A::n} = 42);
-    super.{self::A::a}.==(null) ?{dynamic} super.{self::A::a} = 42 : null;
-    self::use(let final dynamic #t46 = super.{self::A::a} in #t46.==(null) ?{dynamic} super.{self::A::a} = 42 : #t46);
-    super.{self::B::b}.==(null) ?{dynamic} super.{self::A::b} = 42 : null;
-    self::use(let final dynamic #t47 = super.{self::B::b} in #t47.==(null) ?{dynamic} super.{self::A::b} = 42 : #t47);
-    super.{self::A::c}.==(null) ?{dynamic} super.{self::B::c} = 42 : null;
-    self::use(let final dynamic #t48 = super.{self::A::c} in #t48.==(null) ?{dynamic} super.{self::B::c} = 42 : #t48);
-    super.{self::B::d}.==(null) ?{dynamic} super.{self::A::d} = 42 : null;
-    self::use(let final dynamic #t49 = super.{self::B::d} in #t49.==(null) ?{dynamic} super.{self::A::d} = 42 : #t49);
-    super.{self::A::e}.==(null) ?{dynamic} super.e = 42 : null;
-    self::use(let final dynamic #t50 = super.{self::A::e} in #t50.==(null) ?{dynamic} super.e = 42 : #t50);
-    super.{self::A::f}.==(null) ?{dynamic} super.f = 42 : null;
-    self::use(let final dynamic #t51 = super.{self::A::f} in #t51.==(null) ?{dynamic} super.f = 42 : #t51);
-    super.g.==(null) ?{dynamic} super.{self::A::g} = 42 : null;
-    self::use(let final dynamic #t52 = super.g in #t52.==(null) ?{dynamic} super.{self::A::g} = 42 : #t52);
-    super.{self::A::h}.==(null) ?{dynamic} super.{self::A::h} = 42 : null;
-    self::use(let final dynamic #t53 = super.{self::A::h} in #t53.==(null) ?{dynamic} super.{self::A::h} = 42 : #t53);
-    super.{self::A::i}.==(null) ?{dynamic} super.{self::B::i} = 42 : null;
-    self::use(let final dynamic #t54 = super.{self::A::i} in #t54.==(null) ?{dynamic} super.{self::B::i} = 42 : #t54);
-    let final core::int #t55 = 87 in super.{self::A::[]}(#t55).==(null) ?{dynamic} let final core::int #t56 = 42 in let final void #t57 = super.{self::A::[]=}(#t55, #t56) in #t56 : null;
-    self::use(let final core::int #t58 = 87 in let final dynamic #t59 = super.{self::A::[]}(#t58) in #t59.==(null) ?{dynamic} let final core::int #t60 = 42 in let final void #t61 = super.{self::A::[]=}(#t58, #t60) in #t60 : #t59);
-    super.{self::A::m}.==(null) ?{core::Object} super.m = 42 : null;
-    self::use(let final () → void #t62 = super.{self::A::m} in #t62.==(null) ?{core::Object} super.m = 42 : #t62);
-    super.{self::A::n}.==(null) ?{core::Object} super.{self::A::n} = 42 : null;
-    self::use(let final () → void #t63 = super.{self::A::n} in #t63.==(null) ?{core::Object} super.{self::A::n} = 42 : #t63);
+    super.{self::A::a}.{core::Object::==}(null) ?{dynamic} super.{self::A::a} = 42 : null;
+    self::use(let final dynamic #t46 = super.{self::A::a} in #t46.{core::Object::==}(null) ?{dynamic} super.{self::A::a} = 42 : #t46);
+    super.{self::B::b}.{core::Object::==}(null) ?{dynamic} super.{self::A::b} = 42 : null;
+    self::use(let final dynamic #t47 = super.{self::B::b} in #t47.{core::Object::==}(null) ?{dynamic} super.{self::A::b} = 42 : #t47);
+    super.{self::A::c}.{core::Object::==}(null) ?{dynamic} super.{self::B::c} = 42 : null;
+    self::use(let final dynamic #t48 = super.{self::A::c} in #t48.{core::Object::==}(null) ?{dynamic} super.{self::B::c} = 42 : #t48);
+    super.{self::B::d}.{core::Object::==}(null) ?{dynamic} super.{self::A::d} = 42 : null;
+    self::use(let final dynamic #t49 = super.{self::B::d} in #t49.{core::Object::==}(null) ?{dynamic} super.{self::A::d} = 42 : #t49);
+    super.{self::A::e}.{core::Object::==}(null) ?{dynamic} super.e = 42 : null;
+    self::use(let final dynamic #t50 = super.{self::A::e} in #t50.{core::Object::==}(null) ?{dynamic} super.e = 42 : #t50);
+    super.{self::A::f}.{core::Object::==}(null) ?{dynamic} super.f = 42 : null;
+    self::use(let final dynamic #t51 = super.{self::A::f} in #t51.{core::Object::==}(null) ?{dynamic} super.f = 42 : #t51);
+    super.g.{core::Object::==}(null) ?{dynamic} super.{self::A::g} = 42 : null;
+    self::use(let final dynamic #t52 = super.g in #t52.{core::Object::==}(null) ?{dynamic} super.{self::A::g} = 42 : #t52);
+    super.{self::A::h}.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : null;
+    self::use(let final dynamic #t53 = super.{self::A::h} in #t53.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : #t53);
+    super.{self::A::i}.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : null;
+    self::use(let final dynamic #t54 = super.{self::A::i} in #t54.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : #t54);
+    let final core::int #t55 = 87 in super.{self::A::[]}(#t55).{core::Object::==}(null) ?{dynamic} let final core::int #t56 = 42 in let final void #t57 = super.{self::A::[]=}(#t55, #t56) in #t56 : null;
+    self::use(let final core::int #t58 = 87 in let final dynamic #t59 = super.{self::A::[]}(#t58) in #t59.{core::Object::==}(null) ?{dynamic} let final core::int #t60 = 42 in let final void #t61 = super.{self::A::[]=}(#t58, #t60) in #t60 : #t59);
+    super.{self::A::m}.{core::Object::==}(null) ?{core::Object} super.m = 42 : null;
+    self::use(let final () → void #t62 = super.{self::A::m} in #t62.{core::Object::==}(null) ?{core::Object} super.m = 42 : #t62);
+    super.{self::A::n}.{core::Object::==}(null) ?{core::Object} super.{self::A::n} = 42 : null;
+    self::use(let final () → void #t63 = super.{self::A::n} in #t63.{core::Object::==}(null) ?{core::Object} super.{self::A::n} = 42 : #t63);
     super.{self::A::a} = super.{self::A::a}.+(42);
     self::use(super.{self::A::a} = super.{self::A::a}.+(42));
     super.{self::A::b} = super.{self::B::b}.+(42);
@@ -433,7 +433,7 @@
     use(super.n(87));
               ^"]/* from null */;
 static method use(dynamic x) → dynamic {
-  if(x.==(new core::DateTime::now().{core::DateTime::millisecondsSinceEpoch}))
+  if(x.{core::Object::==}(new core::DateTime::now().{core::DateTime::millisecondsSinceEpoch}))
     throw "Shouldn't happen";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.expect b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.expect
index 31007c6..47fe398 100644
--- a/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.expect
+++ b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.expect
@@ -5,6 +5,6 @@
 static method f(core::List<dynamic> x) → core::bool {
   return x.{core::Iterable::expand}<dynamic>((dynamic y) → core::Iterable<dynamic> {
     return y.split(",") as{TypeError} core::Iterable<dynamic>;
-  }).{core::Iterable::any}((dynamic y) → core::bool => y.==("z"));
+  }).{core::Iterable::any}((dynamic y) → core::bool => y.{core::Object::==}("z"));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.transformed.expect b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.transformed.expect
index 31007c6..47fe398 100644
--- a/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.transformed.expect
@@ -5,6 +5,6 @@
 static method f(core::List<dynamic> x) → core::bool {
   return x.{core::Iterable::expand}<dynamic>((dynamic y) → core::Iterable<dynamic> {
     return y.split(",") as{TypeError} core::Iterable<dynamic>;
-  }).{core::Iterable::any}((dynamic y) → core::bool => y.==("z"));
+  }).{core::Iterable::any}((dynamic y) → core::bool => y.{core::Object::==}("z"));
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/super_rasta_copy.dart.strong.expect b/pkg/front_end/testcases/super_rasta_copy.dart.strong.expect
index f5230259..cc2cd34 100644
--- a/pkg/front_end/testcases/super_rasta_copy.dart.strong.expect
+++ b/pkg/front_end/testcases/super_rasta_copy.dart.strong.expect
@@ -177,28 +177,28 @@
     self::use(let final core::int #t35 = 87 in let final core::int #t36 = 42 in let final void #t37 = super.{self::A::[]=}(#t35, #t36) in #t36);
     super.m = 42;
     self::use(super.m = 42);
-    super.{self::A::a}.==(null) ?{dynamic} super.{self::A::a} = 42 : null;
-    self::use(let final dynamic #t38 = super.{self::A::a} in #t38.==(null) ?{dynamic} super.{self::A::a} = 42 : #t38);
-    super.{self::B::b}.==(null) ?{dynamic} super.{self::A::b} = 42 : null;
-    self::use(let final dynamic #t39 = super.{self::B::b} in #t39.==(null) ?{dynamic} super.{self::A::b} = 42 : #t39);
-    super.{self::A::c}.==(null) ?{dynamic} super.{self::B::c} = 42 : null;
-    self::use(let final dynamic #t40 = super.{self::A::c} in #t40.==(null) ?{dynamic} super.{self::B::c} = 42 : #t40);
-    super.{self::B::d}.==(null) ?{dynamic} super.{self::A::d} = 42 : null;
-    self::use(let final dynamic #t41 = super.{self::B::d} in #t41.==(null) ?{dynamic} super.{self::A::d} = 42 : #t41);
-    super.{self::A::e}.==(null) ?{dynamic} super.e = 42 : null;
-    self::use(let final dynamic #t42 = super.{self::A::e} in #t42.==(null) ?{dynamic} super.e = 42 : #t42);
-    super.{self::A::f}.==(null) ?{dynamic} super.f = 42 : null;
-    self::use(let final dynamic #t43 = super.{self::A::f} in #t43.==(null) ?{dynamic} super.f = 42 : #t43);
-    super.g.==(null) ?{dynamic} super.{self::A::g} = 42 : null;
-    self::use(let final dynamic #t44 = super.g in #t44.==(null) ?{dynamic} super.{self::A::g} = 42 : #t44);
-    super.{self::A::h}.==(null) ?{dynamic} super.{self::A::h} = 42 : null;
-    self::use(let final dynamic #t45 = super.{self::A::h} in #t45.==(null) ?{dynamic} super.{self::A::h} = 42 : #t45);
-    super.{self::A::i}.==(null) ?{dynamic} super.{self::B::i} = 42 : null;
-    self::use(let final dynamic #t46 = super.{self::A::i} in #t46.==(null) ?{dynamic} super.{self::B::i} = 42 : #t46);
-    let final core::int #t47 = 87 in super.{self::A::[]}(#t47).==(null) ?{dynamic} let final core::int #t48 = 42 in let final void #t49 = super.{self::A::[]=}(#t47, #t48) in #t48 : null;
-    self::use(let final core::int #t50 = 87 in let final dynamic #t51 = super.{self::A::[]}(#t50) in #t51.==(null) ?{dynamic} let final core::int #t52 = 42 in let final void #t53 = super.{self::A::[]=}(#t50, #t52) in #t52 : #t51);
-    super.{self::A::m}.==(null) ?{core::Object} super.m = 42 : null;
-    self::use(let final () → void #t54 = super.{self::A::m} in #t54.==(null) ?{core::Object} super.m = 42 : #t54);
+    super.{self::A::a}.{core::Object::==}(null) ?{dynamic} super.{self::A::a} = 42 : null;
+    self::use(let final dynamic #t38 = super.{self::A::a} in #t38.{core::Object::==}(null) ?{dynamic} super.{self::A::a} = 42 : #t38);
+    super.{self::B::b}.{core::Object::==}(null) ?{dynamic} super.{self::A::b} = 42 : null;
+    self::use(let final dynamic #t39 = super.{self::B::b} in #t39.{core::Object::==}(null) ?{dynamic} super.{self::A::b} = 42 : #t39);
+    super.{self::A::c}.{core::Object::==}(null) ?{dynamic} super.{self::B::c} = 42 : null;
+    self::use(let final dynamic #t40 = super.{self::A::c} in #t40.{core::Object::==}(null) ?{dynamic} super.{self::B::c} = 42 : #t40);
+    super.{self::B::d}.{core::Object::==}(null) ?{dynamic} super.{self::A::d} = 42 : null;
+    self::use(let final dynamic #t41 = super.{self::B::d} in #t41.{core::Object::==}(null) ?{dynamic} super.{self::A::d} = 42 : #t41);
+    super.{self::A::e}.{core::Object::==}(null) ?{dynamic} super.e = 42 : null;
+    self::use(let final dynamic #t42 = super.{self::A::e} in #t42.{core::Object::==}(null) ?{dynamic} super.e = 42 : #t42);
+    super.{self::A::f}.{core::Object::==}(null) ?{dynamic} super.f = 42 : null;
+    self::use(let final dynamic #t43 = super.{self::A::f} in #t43.{core::Object::==}(null) ?{dynamic} super.f = 42 : #t43);
+    super.g.{core::Object::==}(null) ?{dynamic} super.{self::A::g} = 42 : null;
+    self::use(let final dynamic #t44 = super.g in #t44.{core::Object::==}(null) ?{dynamic} super.{self::A::g} = 42 : #t44);
+    super.{self::A::h}.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : null;
+    self::use(let final dynamic #t45 = super.{self::A::h} in #t45.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : #t45);
+    super.{self::A::i}.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : null;
+    self::use(let final dynamic #t46 = super.{self::A::i} in #t46.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : #t46);
+    let final core::int #t47 = 87 in super.{self::A::[]}(#t47).{core::Object::==}(null) ?{dynamic} let final core::int #t48 = 42 in let final void #t49 = super.{self::A::[]=}(#t47, #t48) in #t48 : null;
+    self::use(let final core::int #t50 = 87 in let final dynamic #t51 = super.{self::A::[]}(#t50) in #t51.{core::Object::==}(null) ?{dynamic} let final core::int #t52 = 42 in let final void #t53 = super.{self::A::[]=}(#t50, #t52) in #t52 : #t51);
+    super.{self::A::m}.{core::Object::==}(null) ?{core::Object} super.m = 42 : null;
+    self::use(let final () → void #t54 = super.{self::A::m} in #t54.{core::Object::==}(null) ?{core::Object} super.m = 42 : #t54);
     super.{self::A::a} = super.{self::A::a}.+(42);
     self::use(super.{self::A::a} = super.{self::A::a}.+(42));
     super.{self::A::b} = super.{self::B::b}.+(42);
@@ -363,7 +363,7 @@
     use(super.m(87));
               ^"]/* from null */;
 static method use(dynamic x) → dynamic {
-  if(x.==(new core::DateTime::now().{core::DateTime::millisecondsSinceEpoch}))
+  if(x.{core::Object::==}(new core::DateTime::now().{core::DateTime::millisecondsSinceEpoch}))
     throw "Shouldn't happen";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
index 052b332..661a043 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
@@ -17,6 +17,6 @@
   let final self::C #t3 = c in (let final dynamic #t4 = #t3 in let dynamic _ = null in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class '#lib1::C'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
   c. /*@error=UndefinedGetter*/ x ??= 1;
-                                ^").==(null) ?{dynamic} #t3.{self::C::x} = 1 : null;
+                                ^").{core::Object::==}(null) ?{dynamic} #t3.{self::C::x} = 1 : null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
index bb3271b..956e97e 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
@@ -17,6 +17,6 @@
   let final self::C #t3 = c in (let final self::C #t4 = #t3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class '#lib1::C'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
   c. /*@error=UndefinedGetter*/ x ??= 1;
-                                ^").==(null) ?{dynamic} #t3.{self::C::x} = 1 : null;
+                                ^").{core::Object::==}(null) ?{dynamic} #t3.{self::C::x} = 1 : null;
 }
 static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index 8d8c894..5ff4e07 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -472,7 +472,7 @@
   [9] = ICData target-name 'call', arg-desc CP#8
 }
 ]  static get platformScript() → dynamic {
-    if(self::VMLibraryHooks::_cachedScript.==(null) && !self::VMLibraryHooks::_computeScriptUri.==(null)) {
+    if(self::VMLibraryHooks::_cachedScript.{core::Object::==}(null) && !self::VMLibraryHooks::_computeScriptUri.{core::Object::==}(null)) {
       self::VMLibraryHooks::_cachedScript = self::VMLibraryHooks::_computeScriptUri.call();
     }
     return self::VMLibraryHooks::_cachedScript;
@@ -533,7 +533,7 @@
   [3] = Null
 }
 ]static method _print(dynamic arg) → void {
-  self::_printString(arg.toString());
+  self::_printString(arg.{core::Object::toString}());
 }
 [@vm.bytecode=
 Bytecode {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
index 21c932f..0e43e97 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -49,10 +49,10 @@
   [@vm.direct-call.metadata=#lib::C::foo??] aa.{self::A::foo}();
 }
 static method callerE1([@vm.inferred-type.metadata=!] dynamic x) → void {
-  x.toString();
+  [@vm.direct-call.metadata=dart.core::_StringBase::toString] x.{core::Object::toString}();
 }
 static method callerE2([@vm.inferred-type.metadata=#lib::E?] dynamic x) → void {
-  x.toString();
+  x.{core::Object::toString}();
 }
 static method main(core::List<core::String> args) → dynamic {
   self::callerA1(new self::B::•());
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index f5e7fe7..338163f 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -34,7 +34,6 @@
 bool_from_environment2_test/03: Crash
 int_modulo_arith_test/modPow: RuntimeError
 int_modulo_arith_test/none: RuntimeError
-null_test: RuntimeError # Issue 32194
 string_from_environment3_test/03: Crash
 
 [ $compiler == precompiler ]
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 13abf12..d534e75 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -290,7 +290,6 @@
 [ $compiler == dartdevk ]
 additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
 additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
-assert_with_message_test: RuntimeError # Issue 33293
 async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
 async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
 async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError
@@ -299,11 +298,9 @@
 bad_override_test/01: MissingCompileTimeError
 bad_override_test/02: MissingCompileTimeError
 bad_override_test/03: MissingCompileTimeError
-built_in_identifier_type_annotation_test/dynamic: RuntimeError # Issue 32194
 built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 32194
 built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 32194
 built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 32194
-built_in_identifier_type_annotation_test/none: RuntimeError # Issue 32194
 call_method_as_cast_test/06: RuntimeError # Kernel allows classes to subtype `Function` so DDK elides the explicit cast.
 call_method_implicit_tear_off_implements_function_test/05: RuntimeError # Kernel is missing the implicit `call` tearoff for assignment `Function`
 call_method_implicit_tear_off_implements_function_test/06: RuntimeError # Kernel is missing the implicit `call` tearoff for assignment `Function`
@@ -311,7 +308,6 @@
 call_method_must_not_be_getter_test/06: RuntimeError # Kernel does not distinguish `d()` from `d.call()`
 call_non_method_field_test/01: MissingCompileTimeError
 call_non_method_field_test/02: MissingCompileTimeError
-cast_test/none: RuntimeError # Issue 32194
 check_member_static_test/01: MissingCompileTimeError
 check_member_static_test/02: MissingCompileTimeError
 class_cycle_test/02: MissingCompileTimeError
@@ -343,7 +339,6 @@
 const_syntax_test/05: MissingCompileTimeError
 const_types_test/34: MissingCompileTimeError
 const_types_test/39: MissingCompileTimeError
-constant_string_interpolation2_test: RuntimeError # Issue 32194
 constants_test/05: MissingCompileTimeError
 constructor_redirect1_negative_test/01: MissingCompileTimeError
 constructor_redirect2_negative_test: MissingCompileTimeError
@@ -525,11 +520,7 @@
 named_constructor_test/01: MissingCompileTimeError
 named_parameters_default_eq_test/02: MissingCompileTimeError
 no_such_method_mock_test: RuntimeError # Issue 31426 - Kernel does not introduce nSM for implemented fields.
-null2_test: RuntimeError # Issue 32194
-null_method_test: RuntimeError # Issue 32194
 null_no_such_method_test: CompileTimeError # Issue 31533
-null_test/none: RuntimeError # Issue 32194
-null_to_string_test: RuntimeError # Issue 32194
 override_field_test/01: MissingCompileTimeError
 override_field_test/02: MissingCompileTimeError
 override_inheritance_field_test/04: CompileTimeError # Issue 31616
@@ -565,7 +556,6 @@
 setter_override_test/02: MissingCompileTimeError
 setter_override_test/03: MissingCompileTimeError
 string_interpolate_test: CompileTimeError # Issue 31533
-string_optimizations_test: RuntimeError # Issue 32194
 string_split_test: CompileTimeError # Issue 31616
 string_supertype_checked_test: CompileTimeError # Issue 31616
 super_bound_closure_test/none: CompileTimeError # Issue 31533
@@ -584,7 +574,6 @@
 switch_case_test/01: MissingCompileTimeError
 switch_case_test/02: MissingCompileTimeError
 syncstar_yield_test/copyParameters: RuntimeError # Expect.equals(expected: <2>, actual: <3>) fails.
-tearoff_dynamic_test: RuntimeError # Issue 32194
 try_catch_test/01: MissingCompileTimeError
 type_alias_equality_test/02: RuntimeError # Issue 32785
 type_literal_test: RuntimeError # Expect.equals(expected: <Func>, actual: <(bool) => int>) fails.