toProgramInfo function
Restore hierarchical ProgramInfo representation from the list of symbols by parsing function names.
If collapseAnonymousClosures
is set to true
then all anonymous closures
within the same scopes are collapsed together. Collapsing closures is
helpful when comparing symbol sizes between two versions of the same
program because in general there is no reliable way to recognize the same
anonymous closures into two independent compilations.
Implementation
ProgramInfo toProgramInfo(List<SymbolInfo> symbols,
{bool collapseAnonymousClosures = false}) {
final program = ProgramInfo();
for (var sym in symbols) {
final scrubbed = sym.name.scrubbed;
final libraryUri = sym.libraryUri;
// Handle stubs specially.
if (libraryUri == null) {
assert(sym.name.isStub);
final node = program.makeNode(
name: scrubbed, parent: program.stubs, type: NodeType.functionNode);
assert(node.size == null || sym.name.isTypeTestingStub);
node.size = (node.size ?? 0) + sym.size;
continue;
}
// Split the name into components (names of individual functions).
final path = sym.name.components;
var node = program.root;
final package = packageOf(libraryUri);
if (package != libraryUri) {
node = program.makeNode(
name: package, parent: node, type: NodeType.packageNode);
}
node = program.makeNode(
name: libraryUri, parent: node, type: NodeType.libraryNode);
node = program.makeNode(
name: sym.className!, parent: node, type: NodeType.classNode);
node = program.makeNode(
name: path.first, parent: node, type: NodeType.functionNode);
for (var name in path.skip(1)) {
if (collapseAnonymousClosures) {
name = Name.collapse(name);
}
node = program.makeNode(
name: name, parent: node, type: NodeType.functionNode);
}
node.size = (node.size ?? 0) + sym.size;
}
return program;
}