[dart2js] Filling out kernel dump-info for libraries and classes.

Change-Id: Ic74e1d90c50587399b50cbbd6a01ab512a8e42d4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239006
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 77d8144..0101783 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -121,7 +121,7 @@
   AbstractValue _resultOfParameter(Local e) =>
       _globalInferenceResults.resultOfParameter(e);
 
-  FieldInfo visitField(FieldEntity field, {ClassEntity containingClass}) {
+  FieldInfo visitField(FieldEntity field) {
     AbstractValue inferredType = _resultOfMember(field).type;
     // If a field has an empty inferred type it is never used.
     if (inferredType == null ||
@@ -201,7 +201,7 @@
           }
         }
       } else if (member.isField) {
-        FieldInfo fieldInfo = visitField(member, containingClass: clazz);
+        FieldInfo fieldInfo = visitField(member);
         if (fieldInfo != null) {
           classInfo.fields.add(fieldInfo);
           fieldInfo.parent = classInfo;
@@ -436,7 +436,7 @@
       _constantToInfo[constant] = info;
       result.constants.add(info);
     });
-    environment.libraries.forEach(visitLibrary);
+    component.libraries.forEach(visitLibrary);
   }
 
   /// Whether to emit information about [entity].
@@ -449,24 +449,32 @@
         dumpInfoTask.inlineCount.containsKey(entity);
   }
 
-  LibraryInfo visitLibrary(LibraryEntity lib) {
-    String libname = environment.getLibraryName(lib);
-    if (libname.isEmpty) {
+  LibraryInfo visitLibrary(ir.Library lib) {
+    final libEntity = environment.lookupLibrary(lib.importUri);
+    if (libEntity == null) return null;
+
+    String libname = lib.name;
+    if (libname == null || libname.isEmpty) {
       libname = '<unnamed>';
     }
-    int size = dumpInfoTask.sizeOf(lib);
-    LibraryInfo info = LibraryInfo(libname, lib.canonicalUri, null, size);
-    _entityToInfo[lib] = info;
 
-    environment.forEachLibraryMember(lib, (MemberEntity member) {
-      if (member.isFunction || member.isGetter || member.isSetter) {
-        FunctionInfo functionInfo = visitFunction(member);
+    int size = dumpInfoTask.sizeOf(libEntity);
+    LibraryInfo info = LibraryInfo(libname, lib.importUri, null, size);
+    _entityToInfo[libEntity] = info;
+
+    lib.members.forEach((ir.Member member) {
+      final memberEntity =
+          environment.lookupLibraryMember(libEntity, member.name.text);
+      if (memberEntity == null) return;
+
+      if (member.function != null) {
+        FunctionInfo functionInfo = visitFunction(memberEntity);
         if (functionInfo != null) {
           info.topLevelFunctions.add(functionInfo);
           functionInfo.parent = info;
         }
-      } else if (member.isField) {
-        FieldInfo fieldInfo = visitField(member);
+      } else {
+        FieldInfo fieldInfo = visitField(member, fieldEntity: memberEntity);
         if (fieldInfo != null) {
           info.topLevelVariables.add(fieldInfo);
           fieldInfo.parent = info;
@@ -474,21 +482,24 @@
       }
     });
 
-    environment.forEachClass(lib, (ClassEntity clazz) {
-      ClassTypeInfo classTypeInfo = visitClassType(clazz);
+    lib.classes.forEach((ir.Class clazz) {
+      final classEntity = environment.lookupClass(libEntity, clazz.name);
+      if (classEntity == null) return;
+
+      ClassTypeInfo classTypeInfo = visitClassType(classEntity);
       if (classTypeInfo != null) {
         info.classTypes.add(classTypeInfo);
         classTypeInfo.parent = info;
       }
 
-      ClassInfo classInfo = visitClass(clazz);
+      ClassInfo classInfo = visitClass(clazz, classEntity: classEntity);
       if (classInfo != null) {
         info.classes.add(classInfo);
         classInfo.parent = info;
       }
     });
 
-    if (info.isEmpty && !shouldKeep(lib)) return null;
+    if (info.isEmpty && !shouldKeep(libEntity)) return null;
     result.libraries.add(info);
     return info;
   }
@@ -499,8 +510,8 @@
   AbstractValue _resultOfParameter(Local e) =>
       _globalInferenceResults.resultOfParameter(e);
 
-  FieldInfo visitField(FieldEntity field, {ClassEntity containingClass}) {
-    AbstractValue inferredType = _resultOfMember(field).type;
+  FieldInfo visitField(ir.Field field, {FieldEntity fieldEntity}) {
+    AbstractValue inferredType = _resultOfMember(fieldEntity).type;
     // If a field has an empty inferred type it is never used.
     if (inferredType == null ||
         closedWorld.abstractValueDomain
@@ -509,21 +520,22 @@
       return null;
     }
 
-    int size = dumpInfoTask.sizeOf(field);
-    List<CodeSpan> code = dumpInfoTask.codeOf(field);
+    int size = dumpInfoTask.sizeOf(fieldEntity);
+    List<CodeSpan> code = dumpInfoTask.codeOf(fieldEntity);
 
     // TODO(het): Why doesn't `size` account for the code size already?
     if (code != null) size += code.length;
 
     FieldInfo info = FieldInfo(
-        name: field.name,
-        type: '${environment.getFieldType(field)}',
+        name: field.name.text,
+        type: field.type.toStringInternal(),
         inferredType: '$inferredType',
         code: code,
-        outputUnit: _unitInfoForMember(field),
+        outputUnit: _unitInfoForMember(fieldEntity),
         isConst: field.isConst);
-    _entityToInfo[field] = info;
-    FieldAnalysisData fieldData = closedWorld.fieldAnalysis.getFieldData(field);
+    _entityToInfo[fieldEntity] = info;
+    FieldAnalysisData fieldData =
+        closedWorld.fieldAnalysis.getFieldData(fieldEntity);
     if (fieldData.initialValue != null) {
       info.initializer = _constantToInfo[fieldData.initialValue];
     }
@@ -534,7 +546,7 @@
       info.coverageId = '${field.hashCode}';
     }
 
-    int closureSize = _addClosureInfo(info, field);
+    int closureSize = _addClosureInfo(info, fieldEntity);
     info.size = size + closureSize;
 
     result.fields.add(info);
@@ -559,18 +571,28 @@
     return classTypeInfo;
   }
 
-  ClassInfo visitClass(ClassEntity clazz) {
+  ClassInfo visitClass(ir.Class clazz, {ClassEntity classEntity}) {
     // Omit class if it is not needed.
     ClassInfo classInfo = ClassInfo(
         name: clazz.name,
         isAbstract: clazz.isAbstract,
-        outputUnit: _unitInfoForClass(clazz));
-    _entityToInfo[clazz] = classInfo;
+        outputUnit: _unitInfoForClass(classEntity));
+    _entityToInfo[classEntity] = classInfo;
 
-    int size = dumpInfoTask.sizeOf(clazz);
-    environment.forEachLocalClassMember(clazz, (member) {
-      if (member.isFunction || member.isGetter || member.isSetter) {
-        FunctionInfo functionInfo = visitFunction(member);
+    int size = dumpInfoTask.sizeOf(classEntity);
+    clazz.members.forEach((ir.Member member) {
+      MemberEntity memberEntity =
+          environment.lookupClassMember(classEntity, member.name.text);
+      if (memberEntity == null) return;
+      // Note: JWorld representations of a kernel member may omit the field or
+      // getter. Filter those cases here.
+      if ((member is ir.Field && memberEntity is! FieldEntity) ||
+          (member is ir.Procedure && memberEntity is! FunctionEntity)) {
+        return;
+      }
+
+      if (member.function != null) {
+        FunctionInfo functionInfo = visitFunction(memberEntity);
         if (functionInfo != null) {
           classInfo.functions.add(functionInfo);
           functionInfo.parent = classInfo;
@@ -578,8 +600,8 @@
             size += closureInfo.size;
           }
         }
-      } else if (member.isField) {
-        FieldInfo fieldInfo = visitField(member, containingClass: clazz);
+      } else {
+        FieldInfo fieldInfo = visitField(member, fieldEntity: memberEntity);
         if (fieldInfo != null) {
           classInfo.fields.add(fieldInfo);
           fieldInfo.parent = classInfo;
@@ -587,12 +609,14 @@
             size += closureInfo.size;
           }
         }
-      } else {
-        throw StateError('Class member not a function or field');
       }
     });
-    environment.forEachConstructor(clazz, (constructor) {
-      FunctionInfo functionInfo = visitFunction(constructor);
+
+    clazz.constructors.forEach((ir.Constructor constructor) {
+      final constructorEntity =
+          environment.lookupConstructor(classEntity, constructor.name.text);
+      if (constructorEntity == null) return;
+      FunctionInfo functionInfo = visitFunction(constructorEntity);
       if (functionInfo != null) {
         classInfo.functions.add(functionInfo);
         functionInfo.parent = classInfo;
@@ -604,7 +628,8 @@
 
     classInfo.size = size;
 
-    if (!compiler.backendStrategy.emitterTask.neededClasses.contains(clazz) &&
+    if (!compiler.backendStrategy.emitterTask.neededClasses
+            .contains(classEntity) &&
         classInfo.fields.isEmpty &&
         classInfo.functions.isEmpty) {
       return null;