Fix tracking of native classes needed for rti.

Closes #32286
Closes #33690

Change-Id: Ic62c145ca7bb5257d71c0d062b111b183258b7d0
Reviewed-on: https://dart-review.googlesource.com/64343
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 7154217..95682d0 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -511,13 +511,10 @@
     ArgumentCollector collector = new ArgumentCollector();
     for (ClassEntity target in checks.classes) {
       ClassChecks classChecks = checks[target];
-      if (classChecks.isNotEmpty) {
-        instantiated.add(target);
-        for (TypeCheck check in classChecks.checks) {
-          Substitution substitution = check.substitution;
-          if (substitution != null) {
-            collector.collectAll(substitution.arguments);
-          }
+      for (TypeCheck check in classChecks.checks) {
+        Substitution substitution = check.substitution;
+        if (substitution != null) {
+          collector.collectAll(substitution.arguments);
         }
       }
     }
@@ -1862,12 +1859,20 @@
 class _RuntimeTypesChecks implements RuntimeTypesChecks {
   final RuntimeTypesSubstitutions _substitutions;
   final TypeChecks requiredChecks;
+  final Iterable<ClassEntity> _typeLiterals;
+  final Iterable<ClassEntity> _typeArguments;
 
-  _RuntimeTypesChecks(this._substitutions, this.requiredChecks);
+  _RuntimeTypesChecks(this._substitutions, this.requiredChecks,
+      this._typeLiterals, this._typeArguments);
 
   @override
   Iterable<ClassEntity> get requiredClasses {
-    return _substitutions.getClassesUsedInSubstitutions(requiredChecks);
+    Set<ClassEntity> required = new Set<ClassEntity>();
+    required.addAll(_typeArguments);
+    required.addAll(_typeLiterals);
+    required
+        .addAll(_substitutions.getClassesUsedInSubstitutions(requiredChecks));
+    return required;
   }
 
   @override
@@ -1936,6 +1941,8 @@
     }
 
     Set<FunctionType> checkedFunctionTypes = new Set<FunctionType>();
+    Set<ClassEntity> typeLiterals = new Set<ClassEntity>();
+    Set<ClassEntity> typeArguments = new Set<ClassEntity>();
 
     TypeVisitor liveTypeVisitor =
         new TypeVisitor(onClass: (ClassEntity cls, {TypeVisitorState state}) {
@@ -1943,9 +1950,11 @@
       switch (state) {
         case TypeVisitorState.typeArgument:
           classUse.typeArgument = true;
+          typeArguments.add(cls);
           break;
         case TypeVisitorState.typeLiteral:
           classUse.typeLiteral = true;
+          typeLiterals.add(cls);
           break;
         case TypeVisitorState.direct:
           break;
@@ -1959,6 +1968,7 @@
         case TypeVisitorState.typeArgument:
           classUse.typeArgument = true;
           classUse.checkedTypeArgument = true;
+          typeArguments.add(cls);
           break;
         case TypeVisitorState.typeLiteral:
           break;
@@ -2086,7 +2096,8 @@
 
     cachedRequiredChecks = _computeChecks(classUseMap);
     rtiChecksBuilderClosed = true;
-    return new _RuntimeTypesChecks(this, cachedRequiredChecks);
+    return new _RuntimeTypesChecks(
+        this, cachedRequiredChecks, typeArguments, typeLiterals);
   }
 }
 
@@ -2883,8 +2894,6 @@
 
   Iterable<TypeCheck> get checks => _map.values;
 
-  bool get isNotEmpty => _map.isNotEmpty;
-
   String toString() {
     return 'ClassChecks($checks)';
   }
diff --git a/tests/compiler/dart2js/rti/emission/event_callback.dart b/tests/compiler/dart2js/rti/emission/event_callback.dart
index 37da4d1..bb6068f 100644
--- a/tests/compiler/dart2js/rti/emission/event_callback.dart
+++ b/tests/compiler/dart2js/rti/emission/event_callback.dart
@@ -9,11 +9,11 @@
 
 /*kernel.class: global#MouseEvent:checks=[$isMouseEvent],instance,typeArgument*/
 /*strong.class: global#MouseEvent:checks=[$isMouseEvent],instance,typeArgument*/
-/*omit.class: global#MouseEvent:checks=[],instance*/
+/*omit.class: global#MouseEvent:instance*/
 
 /*kernel.class: global#KeyboardEvent:checks=[$isKeyboardEvent],instance,typeArgument*/
 /*strong.class: global#KeyboardEvent:checks=[$isKeyboardEvent],instance,typeArgument*/
-/*omit.class: global#KeyboardEvent:checks=[],instance*/
+/*omit.class: global#KeyboardEvent:instance*/
 
 void main() {
   print('InputElement');
diff --git a/tests/compiler/dart2js/rti/emission/map_literal.dart b/tests/compiler/dart2js/rti/emission/map_literal.dart
index 2dbeda8..f9eb53b 100644
--- a/tests/compiler/dart2js/rti/emission/map_literal.dart
+++ b/tests/compiler/dart2js/rti/emission/map_literal.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /*kernel.class: global#Map:instance*/
-/*strong.class: global#Map:checkedInstance,checks=[],instance*/
+/*strong.class: global#Map:checkedInstance,instance*/
 
 /*class: global#LinkedHashMap:*/
 /*class: global#JsLinkedHashMap:checks=[],instance*/
diff --git a/tests/compiler/dart2js/rti/emission/map_literal_checked.dart b/tests/compiler/dart2js/rti/emission/map_literal_checked.dart
index 2f51833..a54e67f 100644
--- a/tests/compiler/dart2js/rti/emission/map_literal_checked.dart
+++ b/tests/compiler/dart2js/rti/emission/map_literal_checked.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*class: global#Map:checkedInstance,checks=[],instance*/
+/*class: global#Map:checkedInstance,instance*/
 /*class: global#LinkedHashMap:checkedInstance*/
 /*class: global#JsLinkedHashMap:checkedInstance,checks=[$isLinkedHashMap],instance*/
 /*class: global#double:checkedInstance,checks=[],instance,typeArgument*/
diff --git a/tests/compiler/dart2js/rti/rti_emission_test.dart b/tests/compiler/dart2js/rti/rti_emission_test.dart
index 36fefb6..d7f6b65 100644
--- a/tests/compiler/dart2js/rti/rti_emission_test.dart
+++ b/tests/compiler/dart2js/rti/rti_emission_test.dart
@@ -38,8 +38,6 @@
         'map_literal_checked.dart',
         // TODO(johnniwinther): Optimize local function type signature need.
         'subtype_named_args.dart',
-        // TODO(33690):
-        'native.dart',
       ],
     );
   });
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index 8ad400d..6273aa3 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -10,7 +10,6 @@
 *: Skip
 
 [ $compiler == dart2js && $checked && !$strong ]
-error_safeToString_test: RuntimeError # Fix for Issue 33627 disabled native class sharing
 native_method_inlining_test: RuntimeError
 
 [ $compiler == dart2js && $fasta ]
@@ -24,5 +23,4 @@
 optimization_hints_test: RuntimeError, OK # Test relies on unminified names.
 
 [ $compiler == dart2js && $strong ]
-error_safeToString_test: RuntimeError # Fix for Issue 33627 disabled native class sharing
 native_checked_fields_frog_test: RuntimeError
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 9016870..457d621 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -515,7 +515,6 @@
 [ $compiler == dart2js && $browser && $strong ]
 html/element_classes_svg_test: RuntimeError
 html/js_array_test: RuntimeError
-html/js_mock_test: RuntimeError
 html/typed_arrays_range_checks_test: RuntimeError
 
 [ $compiler == dart2js && $checked ]