Index: pkg/compiler/lib/src/dump_info.dart |
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart |
index 2a775a16522c4b3022c3ed335f969933b620ea75..82d02c51d6efc9d60ee72f9fb0412d8485f30297 100644 |
--- a/pkg/compiler/lib/src/dump_info.dart |
+++ b/pkg/compiler/lib/src/dump_info.dart |
@@ -9,6 +9,7 @@ import 'dart:convert' |
import 'package:dart2js_info/info.dart'; |
+import 'closure.dart'; |
import 'common/tasks.dart' show CompilerTask; |
import 'common.dart'; |
import 'compiler.dart' show Compiler; |
@@ -130,7 +131,6 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { |
coverageId: '${element.hashCode}', |
type: '${element.type}', |
inferredType: '$inferredType', |
- size: size, |
code: code, |
outputUnit: _unitInfoForElement(element), |
isConst: element.isConst); |
@@ -143,19 +143,9 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { |
} |
} |
- List<FunctionInfo> nestedClosures = <FunctionInfo>[]; |
- for (Element closure in element.nestedClosures) { |
- Info child = this.process(closure); |
- if (child != null) { |
- ClassInfo parent = this.process(closure.enclosingElement); |
- if (parent != null) { |
- child.name = "${parent.name}.${child.name}"; |
- } |
- nestedClosures.add(child); |
- size += child.size; |
- } |
- } |
- info.closures = nestedClosures; |
+ int closureSize = _addClosureInfo(info, element); |
+ info.size = size + closureSize; |
+ |
result.fields.add(info); |
return info; |
} |
@@ -174,29 +164,14 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { |
if (info is FieldInfo) { |
classInfo.fields.add(info); |
info.parent = classInfo; |
+ for (ClosureInfo closureInfo in info.closures) { |
+ size += closureInfo.size; |
+ } |
} else { |
assert(info is FunctionInfo); |
classInfo.functions.add(info); |
info.parent = classInfo; |
- } |
- |
- // Closures are placed in the library namespace, but we want to attribute |
- // them to a function, and by extension, this class. Process and add the |
- // sizes here. |
- if (member is MemberElement) { |
- for (Element closure in member.nestedClosures) { |
- FunctionInfo closureInfo = this.process(closure); |
- if (closureInfo == null) continue; |
- |
- // TODO(sigmund): remove this legacy update on the name, represent the |
- // information explicitly in the info format. |
- // Look for the parent element of this closure might be the enclosing |
- // class or an enclosing function. |
- Element parent = closure.enclosingElement; |
- ClassInfo parentInfo = this.process(parent); |
- if (parentInfo != null) { |
- closureInfo.name = "${parentInfo.name}.${closureInfo.name}"; |
- } |
+ for (ClosureInfo closureInfo in (info as FunctionInfo).closures) { |
size += closureInfo.size; |
} |
} |
@@ -215,6 +190,26 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { |
return classInfo; |
} |
+ ClosureInfo visitClosureClassElement(ClosureClassElement element, _) { |
+ ClosureInfo closureInfo = new ClosureInfo( |
+ name: element.name, |
+ outputUnit: _unitInfoForElement(element), |
+ size: compiler.dumpInfoTask.sizeOf(element)); |
+ _elementToInfo[element] = closureInfo; |
+ |
+ ClosureClassMap closureMap = |
+ compiler.closureToClassMapper.closureMappingCache[element.node]; |
+ assert(closureMap != null && closureMap.closureClassElement == element); |
+ |
+ FunctionInfo functionInfo = this.process(closureMap.callElement); |
+ if (functionInfo == null) return null; |
+ closureInfo.function = functionInfo; |
+ functionInfo.parent = closureInfo; |
+ |
+ result.closures.add(closureInfo); |
+ return closureInfo; |
+ } |
+ |
FunctionInfo visitFunctionElement(FunctionElement element, _) { |
int size = compiler.dumpInfoTask.sizeOf(element); |
// TODO(sigmund): consider adding a small info to represent unreachable |
@@ -294,27 +289,40 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> { |
outputUnit: _unitInfoForElement(element)); |
_elementToInfo[element] = info; |
- List<FunctionInfo> nestedClosures = <FunctionInfo>[]; |
if (element is MemberElement) { |
- MemberElement member = element as MemberElement; |
- for (Element closure in member.nestedClosures) { |
- Info child = this.process(closure); |
- if (child != null) { |
- BasicInfo parent = this.process(closure.enclosingElement); |
- if (parent != null) { |
- child.name = "${parent.name}.${child.name}"; |
- } |
- nestedClosures.add(child); |
- child.parent = parent; |
- size += child.size; |
- } |
- } |
+ int closureSize = _addClosureInfo(info, element as MemberElement); |
+ size += closureSize; |
+ } else { |
+ info.closures = <ClosureInfo>[]; |
} |
- info.closures = nestedClosures; |
+ |
result.functions.add(info); |
return info; |
} |
+ /// Adds closure information to [info], using all nested closures in [member]. |
+ /// |
+ /// Returns the total size of the nested closures, to add to the info size. |
+ int _addClosureInfo(Info info, MemberElement member) { |
+ assert(info is FunctionInfo || info is FieldInfo); |
+ int size = 0; |
+ List<ClosureInfo> nestedClosures = <ClosureInfo>[]; |
+ for (Element function in member.nestedClosures) { |
+ assert(function is SynthesizedCallMethodElementX); |
+ SynthesizedCallMethodElementX callMethod = function; |
+ ClosureInfo closure = this.process(callMethod.closureClass); |
+ if (closure != null) { |
+ closure.parent = info; |
+ nestedClosures.add(closure); |
+ size += closure.size; |
+ } |
+ } |
+ if (info is FunctionInfo) info.closures = nestedClosures; |
+ if (info is FieldInfo) info.closures = nestedClosures; |
+ |
+ return size; |
+ } |
+ |
OutputUnitInfo _infoFromOutputUnit(OutputUnit outputUnit) { |
return _outputToInfo.putIfAbsent(outputUnit, () { |
// Dump-info currently only works with the full emitter. If another |