[dart2wasm] Minor refactoring in `ClassInfoCollector`

The interaction between `Translator` and other types like
`ClassInfoCollector` is quite complicated. This patch refactors a few
things to make it slightly simpler.

Changes:

- Add documentation to a few fields, minor rewording in a few other
  field documentation.

- Make `ClassInfoCollector`'s `nextClassId`, `computeRepresentation`,
  `addTypedDataFields` private.

- Initialize of `ClassInfo`'s `nullableType`, `nonNullableType` in
  constructor.

Change-Id: I48e55029844ff41d9f043aac004a1abad8df83dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/265281
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
diff --git a/pkg/dart2wasm/lib/class_info.dart b/pkg/dart2wasm/lib/class_info.dart
index ecdaf44..b217f05 100644
--- a/pkg/dart2wasm/lib/class_info.dart
+++ b/pkg/dart2wasm/lib/class_info.dart
@@ -104,15 +104,20 @@
   /// All classes which implement this class. This is used to compute `repr`.
   final List<ClassInfo> implementedBy = [];
 
-  late final w.RefType nullableType = w.RefType.def(struct, nullable: true);
-  late final w.RefType nonNullableType = w.RefType.def(struct, nullable: false);
+  /// Nullabe Wasm ref type for this class.
+  final w.RefType nullableType;
 
+  /// Non-nullable Wasm ref type for this class.
+  final w.RefType nonNullableType;
+
+  /// Get Wasm ref type for this class with given nullability.
   w.RefType typeWithNullability(bool nullable) =>
       nullable ? nullableType : nonNullableType;
 
   ClassInfo(this.cls, this.classId, this.depth, this.struct, this.superInfo,
-      ClassInfoCollector collector,
-      {this.typeParameterMatch = const {}}) {
+      {this.typeParameterMatch = const {}})
+      : nullableType = w.RefType.def(struct, nullable: true),
+        nonNullableType = w.RefType.def(struct, nullable: false) {
     implementedBy.add(this);
   }
 
@@ -146,9 +151,15 @@
 /// Constructs the Wasm type hierarchy.
 class ClassInfoCollector {
   final Translator translator;
-  int nextClassId = 0;
+  int _nextClassId = 0;
   late final ClassInfo topInfo;
 
+  /// Wasm field type for fields with type [_Type]. Fields of this type are
+  /// added to classes for type parameters.
+  ///
+  /// This field is initialized when a class with a type parameter is first
+  /// encountered. Initialization depends on [Translator] visiting the [_Type]
+  /// class first and creating a [ClassInfo] for it.
   late final w.FieldType typeType =
       w.FieldType(translator.classInfo[translator.typeClass]!.nullableType);
 
@@ -160,7 +171,7 @@
 
   void initializeTop() {
     final w.StructType struct = m.addStructType("#Top");
-    topInfo = ClassInfo(null, nextClassId++, 0, struct, null, this);
+    topInfo = ClassInfo(null, _nextClassId++, 0, struct, null);
     translator.classes.add(topInfo);
     translator.classForHeapType[struct] = topInfo;
   }
@@ -174,7 +185,7 @@
         final w.StructType struct =
             m.addStructType(cls.name, superType: superInfo.struct);
         info = ClassInfo(
-            cls, nextClassId++, superInfo.depth + 1, struct, superInfo, this);
+            cls, _nextClassId++, superInfo.depth + 1, struct, superInfo);
         // Mark Top type as implementing Object to force the representation
         // type of Object to be Top.
         info.implementedBy.add(topInfo);
@@ -235,7 +246,7 @@
             ? superInfo.struct
             : m.addStructType(cls.name, superType: superInfo.struct);
         info = ClassInfo(
-            cls, nextClassId++, superInfo.depth + 1, struct, superInfo, this,
+            cls, _nextClassId++, superInfo.depth + 1, struct, superInfo,
             typeParameterMatch: typeParameterMatch);
 
         // Mark all interfaces as being implemented by this class. This is
@@ -254,7 +265,7 @@
     }
   }
 
-  void computeRepresentation(ClassInfo info) {
+  void _computeRepresentation(ClassInfo info) {
     info.repr = upperBound(info.implementedBy);
   }
 
@@ -305,13 +316,20 @@
     }
   }
 
+  /// Create class info and Wasm struct for all classes.
   void collect() {
-    // Create class info and Wasm structs for all classes.
     initializeTop();
-    // Subclasses of the [_Function] class are generated on the fly as fields
-    // with function types are encountered. Therefore, this class must be early
-    // in the initialization order.
+
+    // Subclasses of the `_Function` class are generated on the fly as fields
+    // with function types are encountered. Therefore, `_Function` class must
+    // be early in the initialization order.
     initialize(translator.functionClass);
+
+    // Similarly `_Type` is needed for type parameter fields in classes and
+    // needs to be initialized before we encounter a class with type
+    // parameters.
+    initialize(translator.typeClass);
+
     for (Library library in translator.component.libraries) {
       for (Class cls in library.classes) {
         initialize(cls);
@@ -320,10 +338,10 @@
 
     // For each class, compute which Wasm struct should be used for the type of
     // variables bearing that class as their Dart type. This is the struct
-    // corresponding to the least common supertype of all Dart classes
-    // implementing this class.
+    // corresponding to the least common (most specific) supertype of all Dart
+    // classes implementing this class.
     for (ClassInfo info in translator.classes) {
-      computeRepresentation(info);
+      _computeRepresentation(info);
     }
 
     // Now that the representation types for all classes have been computed,
@@ -333,13 +351,13 @@
     }
 
     // Add hidden fields of typed_data classes.
-    addTypedDataFields();
+    _addTypedDataFields();
 
     // Validate that all internally used fields have the expected indices.
     FieldIndex.validate(translator);
   }
 
-  void addTypedDataFields() {
+  void _addTypedDataFields() {
     ClassInfo typedListBaseInfo =
         translator.classInfo[translator.typedListBaseClass]!;
     typedListBaseInfo.addField(w.FieldType(w.NumType.i32, mutable: false),
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
index 5c4edad..7a651c7 100644
--- a/pkg/dart2wasm/lib/translator.dart
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -153,8 +153,16 @@
   late final DynamicDispatcher dynamics;
 
   // Information about the program used and updated by the various phases.
+
+  /// [ClassInfo]s of classes in the compilation unit and the [ClassInfo] for
+  /// the `#Top` struct. Indexed by class ID. Entries added by
+  /// [ClassInfoCollector].
   final List<ClassInfo> classes = [];
+
+  /// [ClassInfo]s of classes in the compilation unit. Entries added by
+  /// [ClassInfoCollector].
   final Map<Class, ClassInfo> classInfo = {};
+
   final Map<w.HeapType, ClassInfo> classForHeapType = {};
   final Map<Field, int> fieldIndex = {};
   final Map<TypeParameter, int> typeParameterIndex = {};
diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart
index 9b15b86..e2484c1 100644
--- a/pkg/dart2wasm/lib/types.dart
+++ b/pkg/dart2wasm/lib/types.dart
@@ -136,8 +136,8 @@
 
   List<List<int>> _buildTypeRulesSupers() {
     List<List<int>> typeRulesSupers = [];
-    for (int i = 0; i < translator.classInfoCollector.nextClassId; i++) {
-      List<int>? superclassIds = typeRules[i]?.keys.toList();
+    for (int classId = 0; classId < translator.classes.length; classId++) {
+      List<int>? superclassIds = typeRules[classId]?.keys.toList();
       if (superclassIds == null) {
         typeRulesSupers.add(const []);
       } else {
@@ -150,12 +150,12 @@
 
   List<List<List<DartType>>> _buildTypeRulesSubstitutions() {
     List<List<List<DartType>>> typeRulesSubstitutions = [];
-    for (int i = 0; i < translator.classInfoCollector.nextClassId; i++) {
-      List<int> supers = typeRulesSupers[i];
+    for (int classId = 0; classId < translator.classes.length; classId++) {
+      List<int> supers = typeRulesSupers[classId];
       typeRulesSubstitutions.add(supers.isEmpty ? const [] : []);
       for (int j = 0; j < supers.length; j++) {
         int superId = supers[j];
-        typeRulesSubstitutions.last.add(typeRules[i]![superId]!);
+        typeRulesSubstitutions.last.add(typeRules[classId]![superId]!);
       }
     }
     return typeRulesSubstitutions;
diff --git a/pkg/wasm_builder/lib/src/types.dart b/pkg/wasm_builder/lib/src/types.dart
index 498978d..5a3360c 100644
--- a/pkg/wasm_builder/lib/src/types.dart
+++ b/pkg/wasm_builder/lib/src/types.dart
@@ -592,7 +592,7 @@
 
 /// A type for a struct field or an array element.
 ///
-/// It consists of a type and a mutability.
+/// It consists of a value type and a mutability.
 class FieldType extends _WithMutability<StorageType> {
   FieldType(super.type, {super.mutable = true});