[dart2js] separate main and deferred units in programInfo tree structures
Change-Id: Ia1a6ba772fa6384ef23ab5d814a0228c7d5613bc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252870
Commit-Queue: Islina Shan <islinashan@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
diff --git a/pkg/dart2js_info/bin/src/to_devtools_format.dart b/pkg/dart2js_info/bin/src/to_devtools_format.dart
index 8e12f5d..9469c95 100644
--- a/pkg/dart2js_info/bin/src/to_devtools_format.dart
+++ b/pkg/dart2js_info/bin/src/to_devtools_format.dart
@@ -1,13 +1,13 @@
+library dart2js_info.bin.to_devtools_format;
+
import 'dart:convert';
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:dart2js_info/info.dart';
import 'package:dart2js_info/src/io.dart';
-import 'package:dart2js_info/src/util.dart';
+import 'package:dart2js_info/src/util.dart' show longName, libraryGroupName;
import 'package:vm_snapshot_analysis/program_info.dart' as vm;
-import 'package:vm_snapshot_analysis/treemap.dart';
-
import 'usage_exception.dart';
/// Command that converts a `--dump-info` JSON output into a format ingested by Devtools.
@@ -39,12 +39,12 @@
final AllInfo allInfo = await infoFromFile(args.rest.first);
final builder = ProgramInfoBuilder(allInfo);
vm.ProgramInfo programInfo = builder.build(allInfo);
- Map<String, dynamic> treeMap = treemapFromInfo(programInfo);
- var treeMapJson = jsonEncode(treeMap);
+ Map<String, dynamic> programInfoTree = programInfo.toJson();
+ // TODO: convert the programInfo tree to a treemap
if (outputPath == null) {
- print(treeMapJson);
+ print(jsonEncode(programInfoTree));
} else {
- await File(outputPath).writeAsString(treeMapJson);
+ await File(outputPath).writeAsString(jsonEncode(programInfoTree));
}
}
}
@@ -61,17 +61,34 @@
final List<vm.ProgramInfoNode> outputInfo = [];
+ /// Mapping between the filename of the outputUnit and the [vm.ProgramInfo]
+ /// subtree representing a program unit (main or deferred).
+ final Map<String, vm.ProgramInfo> outputUnits = {};
+
+ /// Mapping between the name of the library [vm.ProgramInfoNode]
+ /// object and its corresponding outputUnit [vm.ProgramInfo] tree.
+ final Map<String, vm.ProgramInfo> libraryUnits = {};
+
+ /// Mapping between the name of an [Info] object and the corresponding
+ /// [vm.ProgramInfoNode] object.
+ ///
+ /// For packages and libraries, since their children can be split among
+ /// different outputUnits, a composite name is used instead to differentiate
+ /// between [vm.ProgramInfoNode] in different outputUnits.
+ final Map<String, vm.ProgramInfoNode> infoNodesByName = {};
+
+ /// A unique key composed of the name of an [Info] object and the
+ /// filename of the outputUnit.
+ String compositeName(String name, String outputUnitName) =>
+ "$name/$outputUnitName";
+
/// Mapping between the name of a [Info] object and the corresponding
/// [vm.ProgramInfoNode] object.
- Map<String, vm.ProgramInfoNode> infoNodesByName = {};
-
- /// Mapping between the id (aka coverageId) of an [AllInfo] node and the
- /// corresponding [vm.ProgramInfoNode] object.
final Map<String, vm.ProgramInfoNode> infoNodesById = {};
- /// Mapping between package names and the corresponding [vm.ProgramInfoNode]
- /// objects of [vm.NodeType.packageNode].
- final Map<String, vm.ProgramInfoNode> packageInfoNodes = {};
+ /// Mapping between the composite name of a package and the corresponding
+ /// [vm.ProgramInfoNode] objects of [vm.NodeType.packageNode].
+ final Map<String, dynamic> packageInfoNodes = {};
/// Mapping between an <unnamed> [LibraryInfo] object and the name of the
/// corresponding [vm.ProgramInfoNode] object.
@@ -79,33 +96,289 @@
ProgramInfoBuilder(this.info);
+ /// Collect libraries into packages and aggregate their sizes.
+ void makePackage(LibraryInfo libraryInfo, String outputUnitName) {
+ vm.ProgramInfo outputUnit = outputUnits[outputUnitName]!;
+ String libraryName = libraryInfo.name;
+ if (libraryInfo.name == '<unnamed>') {
+ libraryName = longName(libraryInfo, useLibraryUri: true, forId: true);
+ }
+ String packageName = libraryGroupName(libraryInfo) ?? libraryName;
+ vm.ProgramInfoNode? packageInfoNode = packageInfoNodes[packageName];
+ if (packageInfoNode == null) {
+ String compositePackageName = compositeName(packageName, outputUnitName);
+ vm.ProgramInfoNode newPackage = outputUnit.makeNode(
+ name: compositePackageName,
+ parent: outputUnit.root,
+ type: vm.NodeType.packageNode);
+ newPackage.size = libraryInfo.size;
+ packageInfoNodes[compositePackageName] = newPackage;
+ outputUnit.root.children[compositePackageName] = newPackage;
+ outputInfo.add(newPackage);
+ var packageNode = infoNodesByName[compositePackageName];
+ assert(packageNode == null,
+ "encountered package with duplicated name: $compositePackageName");
+ infoNodesByName[compositePackageName] = newPackage;
+ } else {
+ packageInfoNode.size = (packageInfoNode.size ?? 0) + libraryInfo.size;
+ }
+ }
+
+ void makeLibrary(LibraryInfo libraryInfo, String outputUnitName) {
+ vm.ProgramInfo outputUnit = outputUnits[outputUnitName]!;
+ String libraryName = libraryInfo.name;
+ if (libraryName == '<unnamed>') {
+ libraryName = longName(libraryInfo, useLibraryUri: true, forId: true);
+ unnamedLibraries[libraryInfo] = libraryName;
+ }
+ String packageName = libraryGroupName(libraryInfo) ?? libraryName;
+ String compositePackageName = compositeName(packageName, outputUnitName);
+ vm.ProgramInfoNode parentNode = infoNodesByName[compositePackageName]!;
+ String compositeLibraryName = compositeName(libraryName, outputUnitName);
+ vm.ProgramInfoNode newLibrary = outputUnit.makeNode(
+ name: compositeLibraryName,
+ parent: parentNode,
+ type: vm.NodeType.libraryNode);
+ newLibrary.size = libraryInfo.size;
+ parentNode.children[newLibrary.name] = newLibrary;
+ vm.ProgramInfoNode? libraryNode = infoNodesByName[compositeLibraryName];
+ assert(libraryNode == null,
+ "encountered library with duplicated name: $compositeLibraryName");
+ infoNodesByName[compositeLibraryName] = newLibrary;
+ outputInfo.add(newLibrary);
+ }
+
+ void makeFunction(FunctionInfo functionInfo) {
+ Info? parent = functionInfo.parent;
+ String outputUnitName = functionInfo.outputUnit!.filename;
+ vm.ProgramInfo? outputUnit = outputUnits[outputUnitName];
+ if (parent != null && outputUnit != null) {
+ assert(parent.kind == kindFromString('library'));
+ vm.ProgramInfoNode parentNode;
+ if (parent.kind == kindFromString('library')) {
+ if (parent.name == "<unnamed>") {
+ var tempName =
+ compositeName(unnamedLibraries[parent]!, outputUnitName);
+ parentNode = infoNodesByName[tempName]!;
+ } else {
+ parentNode =
+ infoNodesByName[compositeName(parent.name, outputUnitName)]!;
+ }
+ } else {
+ parentNode = infoNodesByName[parent.name]!;
+ }
+ vm.ProgramInfoNode newFunction = outputUnit.makeNode(
+ name: functionInfo.name,
+ parent: parentNode,
+ type: vm.NodeType.functionNode);
+ newFunction.size = functionInfo.size;
+ parentNode.children[newFunction.name] = newFunction;
+ vm.ProgramInfoNode? functionNode = infoNodesByName[newFunction.name];
+ assert(functionNode == null,
+ "encountered function with duplicated name: $newFunction.name");
+ infoNodesByName[newFunction.name] = newFunction;
+ outputInfo.add(newFunction);
+ }
+ }
+
+ void makeClass(ClassInfo classInfo) {
+ Info? parent = classInfo.parent;
+ String outputUnitName = classInfo.outputUnit!.filename;
+ vm.ProgramInfo? outputUnit = outputUnits[outputUnitName];
+ if (parent != null && outputUnit != null) {
+ vm.ProgramInfoNode parentNode;
+ if (parent.kind == kindFromString('library')) {
+ if (parent.name == "<unnamed>") {
+ var tempName =
+ compositeName(unnamedLibraries[parent]!, outputUnitName);
+ parentNode = infoNodesByName[tempName]!;
+ } else {
+ parentNode =
+ infoNodesByName[compositeName(parent.name, outputUnitName)]!;
+ }
+ } else {
+ parentNode = infoNodesByName[parent.name]!;
+ }
+ vm.ProgramInfoNode newClass = outputUnit.makeNode(
+ name: classInfo.name,
+ parent: parentNode,
+ type: vm.NodeType.classNode);
+ newClass.size = classInfo.size;
+ parentNode.children[newClass.name] = newClass;
+ vm.ProgramInfoNode? classNode = infoNodesByName[newClass.name];
+ assert(classNode == null,
+ "encountered class with duplicated name: $newClass.name");
+ infoNodesByName[newClass.name] = newClass;
+ outputInfo.add(newClass);
+ }
+ }
+
+ /// Fields are currently assigned [vm.NodeType.other].
+ ///
+ /// Note: we might want to create a separate [vm.NodeType.fieldNode] to
+ /// differentiate fields from other miscellaneous nodes for constructing
+ /// the call graph.
+ void makeField(FieldInfo fieldInfo) {
+ Info? parent = fieldInfo.parent;
+ String outputUnitName = fieldInfo.outputUnit!.filename;
+ vm.ProgramInfo? outputUnit = outputUnits[outputUnitName];
+ if (parent != null && outputUnit != null) {
+ vm.ProgramInfoNode parentNode;
+ if (parent.kind == kindFromString('library')) {
+ if (parent.name == "<unnamed>") {
+ var tempName =
+ compositeName(unnamedLibraries[parent]!, outputUnitName);
+ parentNode = infoNodesByName[tempName]!;
+ } else {
+ parentNode =
+ infoNodesByName[compositeName(parent.name, outputUnitName)]!;
+ }
+ } else {
+ parentNode = infoNodesByName[parent.name]!;
+ }
+ vm.ProgramInfoNode newField = outputUnit.makeNode(
+ name: fieldInfo.name, parent: parentNode, type: vm.NodeType.other);
+ newField.size = fieldInfo.size;
+ parentNode.children[newField.name] = newField;
+ vm.ProgramInfoNode? fieldNode = infoNodesByName[newField.name];
+ assert(fieldNode == null,
+ "encountered field with duplicated name: $newField.name");
+ infoNodesByName[newField.name] = newField;
+ outputInfo.add(newField);
+ }
+ }
+
+ void makeConstant(ConstantInfo constantInfo) {
+ String? constantName = constantInfo.code.first.text ??
+ "${constantInfo.code.first.start}/${constantInfo.code.first.end}";
+ String outputUnitName = constantInfo.outputUnit!.filename;
+ vm.ProgramInfo? outputUnit = outputUnits[outputUnitName];
+ vm.ProgramInfoNode newConstant = outputUnit!.makeNode(
+ name: constantName, parent: outputUnit.root, type: vm.NodeType.other);
+ newConstant.size = constantInfo.size;
+ outputUnit.root.children[newConstant.name] = newConstant;
+ vm.ProgramInfoNode? constantNode = infoNodesByName[newConstant.name];
+ assert(constantNode == null,
+ "encountered constant with duplicated name: $newConstant.name");
+ infoNodesByName[newConstant.name] = newConstant;
+ outputInfo.add(newConstant);
+ }
+
+ void makeTypedef(TypedefInfo typedefInfo) {
+ String outputUnitName = typedefInfo.outputUnit!.filename;
+ vm.ProgramInfo? outputUnit = outputUnits[outputUnitName];
+ vm.ProgramInfoNode newTypedef = outputUnit!.makeNode(
+ name: typedefInfo.name,
+ parent: outputUnit.root,
+ type: vm.NodeType.other);
+ newTypedef.size = typedefInfo.size;
+ vm.ProgramInfoNode? typedefNode = infoNodesByName[newTypedef.name];
+ assert(typedefNode == null,
+ "encountered constant with duplicated name: $newTypedef.name");
+ outputInfo.add(newTypedef);
+ }
+
+ void makeClassType(ClassTypeInfo classTypeInfo) {
+ Info? parent = classTypeInfo.parent;
+ String outputUnitName = classTypeInfo.outputUnit!.filename;
+ vm.ProgramInfo? outputUnit = outputUnits[outputUnitName];
+ if (parent != null && outputUnit != null) {
+ assert(parent.kind == kindFromString('library'));
+ vm.ProgramInfoNode parentNode;
+ if (parent.name == "<unnamed>") {
+ var tempName = compositeName(unnamedLibraries[parent]!, outputUnitName);
+ parentNode = infoNodesByName[tempName]!;
+ } else {
+ parentNode =
+ infoNodesByName[compositeName(parent.name, outputUnitName)]!;
+ }
+ vm.ProgramInfoNode newClassType = outputUnit.makeNode(
+ name: classTypeInfo.name,
+ parent: parentNode,
+ type: vm.NodeType.other);
+ newClassType.size = classTypeInfo.size;
+ vm.ProgramInfoNode? classTypeNode = infoNodesByName[newClassType.name];
+ assert(classTypeNode == null,
+ "encountered classType with duplicated name: $newClassType.name");
+ infoNodesByName[newClassType.name] = newClassType;
+ outputInfo.add(newClassType);
+ }
+ }
+
+ void makeClosure(ClosureInfo closureInfo) {
+ Info? parent = closureInfo.parent;
+ String outputUnitName = closureInfo.outputUnit!.filename;
+ vm.ProgramInfo? outputUnit = outputUnits[outputUnitName];
+ if (parent != null && outputUnit != null) {
+ vm.ProgramInfoNode parentNode;
+ if (parent.kind == kindFromString('library')) {
+ if (parent.name == "<unnamed>") {
+ var tempName =
+ compositeName(unnamedLibraries[parent]!, outputUnitName);
+ parentNode = infoNodesByName[tempName]!;
+ } else {
+ parentNode =
+ infoNodesByName[compositeName(parent.name, outputUnitName)]!;
+ }
+ } else {
+ parentNode = infoNodesByName[parent.name]!;
+ }
+ vm.ProgramInfoNode newClosure = outputUnit.makeNode(
+ name: closureInfo.name,
+ parent: parentNode,
+ // ProgramInfo trees consider closures and functions to both be of the functionNode type.
+ type: vm.NodeType.functionNode);
+ newClosure.size = closureInfo.size;
+ parentNode.children[newClosure.name] = newClosure;
+ vm.ProgramInfoNode? closureNode = infoNodesByName[newClosure.name];
+ assert(closureNode == null,
+ "encountered closure with duplicated name: $newClosure.name");
+ infoNodesByName[newClosure.name] = newClosure;
+ outputInfo.add(newClosure);
+ }
+ }
+
@override
- vm.ProgramInfoNode visitAll(AllInfo info) {
- outputInfo.add(program.root);
- info.libraries.forEach(makePackage);
- info.packages.forEach(visitPackage);
- info.libraries.forEach(makeLibrary);
- info.libraries.forEach(visitLibrary);
+ vm.ProgramInfoNode visitAll(AllInfo info, String outputUnitName) {
+ outputInfo.add(outputUnits[outputUnitName]!.root);
+ visitProgram(info.program!);
+ for (var package in info.packages) {
+ visitPackage(package, outputUnitName);
+ }
+ for (var library in info.libraries) {
+ visitLibrary(library, outputUnitName);
+ }
info.constants.forEach(makeConstant);
info.constants.forEach(visitConstant);
- return program.root;
+ return outputUnits[outputUnitName]!.root;
+ }
+
+ @override
+ vm.ProgramInfoNode visitOutput(OutputUnitInfo info) {
+ vm.ProgramInfo? outputUnit = outputUnits[info.filename];
+ assert(outputUnit == null, "encountered outputUnit with duplicated name");
+ var newUnit = vm.ProgramInfo();
+ outputUnits[info.filename] = newUnit;
+ outputUnits[info.filename]!.root.size = info.size;
+ return outputUnits[info.filename]!.root;
}
@override
vm.ProgramInfoNode visitProgram(ProgramInfo info) {
- throw Exception('Not supported for devtools format.');
+ program.root.size = info.size;
+ return program.root;
}
@override
- vm.ProgramInfoNode visitPackage(PackageInfo info) {
- info.libraries.forEach(makePackage);
- info.libraries.forEach(makeLibrary);
- info.libraries.forEach(visitLibrary);
- return infoNodesByName[info.name]!;
+ vm.ProgramInfoNode visitPackage(PackageInfo info, String outputUnitName) {
+ for (var library in info.libraries) {
+ visitLibrary(library, outputUnitName);
+ }
+ return infoNodesByName[compositeName(info.name, outputUnitName)]!;
}
@override
- vm.ProgramInfoNode visitLibrary(LibraryInfo info) {
+ vm.ProgramInfoNode visitLibrary(LibraryInfo info, String outputUnitName) {
info.topLevelFunctions.forEach(makeFunction);
info.topLevelFunctions.forEach(visitFunction);
info.topLevelVariables.forEach(makeField);
@@ -116,8 +389,9 @@
info.classTypes.forEach(visitClassType);
info.typedefs.forEach(makeTypedef);
info.typedefs.forEach(visitTypedef);
- return infoNodesByName[info.name] ??
- infoNodesByName[unnamedLibraries[info]]!;
+ return infoNodesByName[compositeName(info.name, outputUnitName)] ??
+ infoNodesByName[
+ compositeName(unnamedLibraries[info]!, outputUnitName)]!;
}
@override
@@ -157,7 +431,8 @@
@override
vm.ProgramInfoNode visitConstant(ConstantInfo info) {
- return infoNodesByName[info.code.first.text!]!;
+ return infoNodesByName[info.code.first.text] ??
+ infoNodesByName["${info.code.first.start}/${info.code.first.end}"]!;
}
@override
@@ -165,191 +440,18 @@
return infoNodesByName[info.name]!;
}
- @override
- vm.ProgramInfoNode visitOutput(OutputUnitInfo info) {
- throw Exception("For deferred loading.");
- }
-
vm.ProgramInfo build(AllInfo info) {
- visitAll(info);
+ info.outputUnits.forEach(visitOutput);
+ for (var outputUnitName in outputUnits.keys) {
+ for (var library in info.libraries) {
+ makePackage(library, outputUnitName);
+ makeLibrary(library, outputUnitName);
+ }
+ }
+ for (var outputUnitName in outputUnits.keys) {
+ visitAll(info, outputUnitName);
+ program.root.children[outputUnitName] = outputUnits[outputUnitName]!.root;
+ }
return program;
}
-
- /// Collect libraries into packages and aggregate their sizes.
- void makePackage(LibraryInfo libraryInfo) {
- String packageName = libraryGroupName(libraryInfo) ?? libraryInfo.name;
- vm.ProgramInfoNode? packageInfoNode = packageInfoNodes[packageName];
- if (packageInfoNode == null) {
- vm.ProgramInfoNode newPackage = program.makeNode(
- name: packageName,
- parent: program.root,
- type: vm.NodeType.packageNode);
- newPackage.size = libraryInfo.size;
- packageInfoNodes[packageName] = newPackage;
- program.root.children[packageName] = newPackage;
- outputInfo.add(newPackage);
- var packageNode = infoNodesByName[newPackage.name];
- assert(packageNode == null, "encountered package with duplicated name");
- infoNodesByName[newPackage.name] = newPackage;
- } else {
- packageInfoNode.size = (packageInfoNode.size ?? 0) + libraryInfo.size;
- }
- }
-
- void makeLibrary(LibraryInfo libraryInfo) {
- String packageName = libraryGroupName(libraryInfo) ?? libraryInfo.name;
- vm.ProgramInfoNode parentNode = infoNodesByName[packageName]!;
- String libraryName = libraryInfo.name;
- if (libraryName == '<unnamed>') {
- libraryName = longName(libraryInfo, useLibraryUri: true, forId: true);
- unnamedLibraries[libraryInfo] = libraryName;
- }
- vm.ProgramInfoNode newLibrary = program.makeNode(
- name: libraryName, parent: parentNode, type: vm.NodeType.libraryNode);
- newLibrary.size = libraryInfo.size;
- parentNode.children[newLibrary.name] = newLibrary;
- vm.ProgramInfoNode? libraryNode = infoNodesByName[newLibrary.name];
- assert(libraryNode == null, "encountered library with duplicated name");
- infoNodesByName[newLibrary.name] = newLibrary;
- outputInfo.add(newLibrary);
- }
-
- void makeFunction(FunctionInfo functionInfo) {
- Info? parent = functionInfo.parent;
- if (parent != null) {
- vm.ProgramInfoNode parentNode;
- if (parent.name == "<unnamed>" &&
- parent.kind == kindFromString('library')) {
- parentNode = infoNodesByName[unnamedLibraries[parent]]!;
- } else {
- parentNode = infoNodesByName[parent.name]!;
- }
- vm.ProgramInfoNode newFunction = program.makeNode(
- name: functionInfo.name,
- parent: parentNode,
- type: vm.NodeType.functionNode);
- newFunction.size = functionInfo.size;
- parentNode.children[newFunction.name] = newFunction;
- vm.ProgramInfoNode? functionNode = infoNodesByName[newFunction.name];
- assert(functionNode == null, "encountered function with duplicated name");
- infoNodesByName[newFunction.name] = newFunction;
- outputInfo.add(newFunction);
- }
- }
-
- void makeClass(ClassInfo classInfo) {
- Info? parent = classInfo.parent;
- if (parent != null) {
- vm.ProgramInfoNode parentNode;
- if (parent.name == "<unnamed>" &&
- parent.kind == kindFromString('library')) {
- parentNode = infoNodesByName[unnamedLibraries[parent]]!;
- } else {
- parentNode = infoNodesByName[parent.name]!;
- }
- vm.ProgramInfoNode newClass = program.makeNode(
- name: classInfo.name,
- parent: parentNode,
- type: vm.NodeType.classNode);
- newClass.size = classInfo.size;
- parentNode.children[newClass.name] = newClass;
- vm.ProgramInfoNode? classNode = infoNodesByName[newClass.name];
- assert(classNode == null, "encountered class with duplicated name");
- infoNodesByName[newClass.name] = newClass;
- outputInfo.add(newClass);
- }
- }
-
- /// Fields are currently assigned [vm.NodeType.other].
- ///
- /// Note: we might want to create a separate [vm.NodeType.fieldNode] to
- /// differentiate fields from other miscellaneous nodes for constructing
- /// the call graph.
- void makeField(FieldInfo fieldInfo) {
- Info? parent = fieldInfo.parent;
- if (parent != null) {
- vm.ProgramInfoNode parentNode;
- if (parent.name == "<unnamed>" &&
- parent.kind == kindFromString('library')) {
- parentNode = infoNodesByName[unnamedLibraries[parent]]!;
- } else {
- parentNode = infoNodesByName[parent.name]!;
- }
- vm.ProgramInfoNode newField = program.makeNode(
- name: fieldInfo.name, parent: parentNode, type: vm.NodeType.other);
- newField.size = fieldInfo.size;
- parentNode.children[newField.name] = newField;
- vm.ProgramInfoNode? fieldNode = infoNodesByName[newField.name];
- assert(fieldNode == null, "encountered field with duplicated name");
- infoNodesByName[newField.name] = newField;
- outputInfo.add(newField);
- }
- }
-
- void makeConstant(ConstantInfo constantInfo) {
- String constantName = constantInfo.code.first.text!;
- vm.ProgramInfoNode newConstant = program.makeNode(
- name: constantName, parent: program.root, type: vm.NodeType.other);
- newConstant.size = constantInfo.size;
- program.root.children[newConstant.name] = newConstant;
- vm.ProgramInfoNode? constantNode = infoNodesByName[newConstant.name];
- assert(constantNode == null, "encountered constant with duplicated name");
- infoNodesByName[newConstant.name] = newConstant;
- outputInfo.add(newConstant);
- }
-
- void makeTypedef(TypedefInfo typedefInfo) {
- vm.ProgramInfoNode newTypedef = program.makeNode(
- name: typedefInfo.name, parent: program.root, type: vm.NodeType.other);
- newTypedef.size = typedefInfo.size;
- infoNodesByName[newTypedef.name] = newTypedef;
- outputInfo.add(newTypedef);
- }
-
- void makeClassType(ClassTypeInfo classTypeInfo) {
- Info? parent = classTypeInfo.parent;
- if (parent != null) {
- vm.ProgramInfoNode parentNode;
- if (parent.name == "<unnamed>" &&
- parent.kind == kindFromString('library')) {
- parentNode = infoNodesByName[unnamedLibraries[parent]]!;
- } else {
- parentNode = infoNodesByName[parent.name]!;
- }
- vm.ProgramInfoNode newClassType = program.makeNode(
- name: classTypeInfo.name,
- parent: parentNode,
- type: vm.NodeType.other);
- newClassType.size = classTypeInfo.size;
- vm.ProgramInfoNode? classTypeNode = infoNodesByName[newClassType.name];
- assert(
- classTypeNode == null, "encountered classType with duplicated name");
- infoNodesByName[newClassType.name] = newClassType;
- outputInfo.add(newClassType);
- }
- }
-
- void makeClosure(ClosureInfo closureInfo) {
- Info? parent = closureInfo.parent;
- if (parent != null) {
- vm.ProgramInfoNode parentNode;
- if (parent.name == "<unnamed>" &&
- parent.kind == kindFromString('library')) {
- parentNode = infoNodesByName[unnamedLibraries[parent]]!;
- } else {
- parentNode = infoNodesByName[parent.name]!;
- }
- vm.ProgramInfoNode newClosure = program.makeNode(
- name: closureInfo.name,
- parent: parentNode,
- // ProgramInfo trees consider closures and functions to both be of the functionNode type.
- type: vm.NodeType.functionNode);
- newClosure.size = closureInfo.size;
- parentNode.children[newClosure.name] = newClosure;
- vm.ProgramInfoNode? closureNode = infoNodesByName[newClosure.name];
- assert(closureNode == null, "encountered closure with duplicated name");
- infoNodesByName[newClosure.name] = newClosure;
- outputInfo.add(newClosure);
- }
- }
}
diff --git a/pkg/dart2js_info/lib/info.dart b/pkg/dart2js_info/lib/info.dart
index 051d75a..7c14f74 100644
--- a/pkg/dart2js_info/lib/info.dart
+++ b/pkg/dart2js_info/lib/info.dart
@@ -203,14 +203,8 @@
: super(InfoKind.package, name, outputUnit, size, null);
@override
- T accept<T>(InfoVisitor<T> visitor) {
- if (visitor is VMProgramInfoVisitor<T>) {
- return visitor.visitPackage(this);
- } else {
- throw ArgumentError(
- "PackageInfo can only be visited by a VMProgramInfoVisitor");
- }
- }
+ T accept<T>(InfoVisitor<T> visitor) =>
+ throw Exception("PackageInfo is not supported by InfoVisitor.");
}
/// Info associated with a library element.
@@ -620,8 +614,19 @@
/// A visitor that adds implementation for PackageInfo specifically for building
/// the VM ProgramInfo Tree from a Dart2js info tree.
-abstract class VMProgramInfoVisitor<T> extends InfoVisitor<T> {
- T visitPackage(PackageInfo info);
+abstract class VMProgramInfoVisitor<T> {
+ T visitAll(AllInfo info, String outputUnit);
+ T visitProgram(ProgramInfo info);
+ T visitPackage(PackageInfo info, String outputUnit);
+ T visitLibrary(LibraryInfo info, String outputUnit);
+ T visitClass(ClassInfo info);
+ T visitClassType(ClassTypeInfo info);
+ T visitField(FieldInfo info);
+ T visitConstant(ConstantInfo info);
+ T visitFunction(FunctionInfo info);
+ T visitTypedef(TypedefInfo info);
+ T visitClosure(ClosureInfo info);
+ T visitOutput(OutputUnitInfo info);
}
/// A visitor that recursively walks each portion of the program. Because the
@@ -642,6 +647,11 @@
@override
void visitProgram(ProgramInfo info) {}
+ void visitPackage(PackageInfo info) {
+ throw Exception(
+ "PackageInfo objects are only defined for the VM Devtools format.");
+ }
+
@override
void visitLibrary(LibraryInfo info) {
info.topLevelFunctions.forEach(visitFunction);