Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Side by Side Diff: pkg/compiler/lib/src/info/info.dart

Issue 1253763004: dart2js: represent dump-info explicitly, so we can easily create tools that process the data (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: additional fixes Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/dump_info.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Data collected by the dump-info task.
6 library compiler.src.lib.info;
7
8 // Note: this file intentionally doesn't import anything from the compiler. That
9 // should make it easier for tools to depend on this library. The idea is that
10 // by using this library, tools can consume the information in the same way it
11 // is produced by the compiler.
12 // TODO(sigmund): make this a proper public API (export this explicitly at the
13 // lib folder level.)
14
15 /// Common interface to many pieces of information generated by the compiler.
16 abstract class Info {
17 /// An identifier for the kind of information.
18 String get kind;
19
20 /// Name of the element associated with this info.
21 String name;
22
23 /// An id to uniquely identify this info among infos of the same [kind].
24 int get id;
25
26 /// A globally unique id combining [kind] and [id] together.
27 String get serializedId;
28
29 /// Bytes used in the generated code for the corresponding element.
30 int size;
31
32 /// Serializes the information into a JSON format.
33 // TODO(sigmund): refactor and put toJson outside the class, so we can have 2
34 // different serializer/deserializers at once.
35 Map toJson();
36 }
37
38 /// Common information used for most kind of elements.
39 // TODO(sigmund): add more:
40 // - inputSize: bytes used in the Dart source program
41 abstract class BasicInfo implements Info {
42 final String kind;
43 final int id;
44 int size;
45
46 String get serializedId => '$kind/$id';
47
48 String name;
49
50 /// If using deferred libraries, where the element associated with this info
51 /// is generated.
52 OutputUnitInfo outputUnit;
53
54 BasicInfo(this.kind, this.id, this.name, this.outputUnit, this.size);
55
56 Map toJson() {
57 var res = {'id': serializedId, 'kind': kind, 'name': name, 'size': size};
58 // TODO(sigmund): omit this also when outputUnit.id == 0
59 // (most code is by default in the main output unit)
60 if (outputUnit != null) res['outputUnit'] = outputUnit.serializedId;
61 return res;
62 }
63
64 String toString() => '$serializedId $name [$size]';
65 }
66
67 /// Info associated with elements containing executable code (like fields and
68 /// methods)
69 abstract class CodeInfo implements Info {
70 /// How does this function or field depend on others.
71 final List<DependencyInfo> uses = <DependencyInfo>[];
72 }
73
74
75 /// The entire information produced while compiling a program.
76 class AllInfo {
77 /// Summary information about the program.
78 ProgramInfo program;
79
80 /// Information about each library processed by the compiler.
81 List<LibraryInfo> libraries = <LibraryInfo>[];
82
83 /// Information about each function (includes methods and getters in any
84 /// library)
85 List<FunctionInfo> functions = <FunctionInfo>[];
86
87 /// Information about type defs in the program.
88 List<TypedefInfo> typedefs = <TypedefInfo>[];
89
90 /// Information about each class (in any library).
91 List<ClassInfo> classes = <ClassInfo>[];
92
93 /// Information about fields (in any class).
94 List<FieldInfo> fields = <FieldInfo>[];
95
96 /// Information about output units (should be just one entry if not using
97 /// deferred loading).
98 List<OutputUnitInfo> outputUnits = <OutputUnitInfo>[];
99
100 /// Details about all deferred imports and what files would be loaded when the
101 /// import is resolved.
102 // TODO(sigmund): use a different format for dump-info. This currently emits
103 // the same map that is created for the `--deferred-map` flag.
104 Map<String, Map<String, dynamic>> deferredFiles;
105
106 /// Major version indicating breaking changes in the format. A new version
107 /// means that an old deserialization algorithm will not work with the new
108 /// format.
109 final int version = 3;
110
111 /// Minor version indicating non-breaking changes in the format. A change in
112 /// this version number means that the json parsing in this library from a
113 /// previous will continue to work after the change. This is typically
114 /// increased when adding new entries to the file format.
115 // Note: the dump-info.viewer app was written using a json parser version 3.2.
116 final int minorVersion = 3;
117
118 AllInfo();
119
120 Map _listAsJsonMap(List<Info> list) {
121 var map = <String, Map>{};
122 for (var info in list) {
123 map['${info.id}'] = info.toJson();
124 }
125 return map;
126 }
127
128 Map _extractHoldingInfo() {
129 var map = <String, List>{};
130 void helper(CodeInfo info) {
131 if (info.uses.isEmpty) return;
132 map[info.serializedId] = info.uses.map((u) => u.toJson()).toList();
133 }
134 functions.forEach(helper);
135 fields.forEach(helper);
136 return map;
137 }
138
139 // TODO(sigmund): implement fromJson
140 Map toJson() => {
141 'elements': {
142 'library': _listAsJsonMap(libraries),
143 'class': _listAsJsonMap(classes),
144 'function': _listAsJsonMap(functions),
145 'typedef': _listAsJsonMap(typedefs),
146 'field': _listAsJsonMap(fields),
147 },
148 'holding': _extractHoldingInfo(),
149 'outputUnits': outputUnits.map((u) => u.toJson()).toList(),
150 'dump_version': version,
151 'deferredFiles': deferredFiles,
152 'dump_minor_version': '$minorVersion',
153 // TODO(sigmund): change viewer to accept an int?
154 'program': program.toJson(),
155 };
156 }
157
158 class ProgramInfo {
159 int size;
160 String dart2jsVersion;
161 DateTime compilationMoment;
162 Duration compilationDuration;
163 // TODO(sigmund): use Duration.
164 int toJsonDuration;
165 int dumpInfoDuration;
166 bool noSuchMethodEnabled;
167 bool minified;
168
169 ProgramInfo(
170 {this.size,
171 this.dart2jsVersion,
172 this.compilationMoment,
173 this.compilationDuration,
174 this.toJsonDuration,
175 this.dumpInfoDuration,
176 this.noSuchMethodEnabled,
177 this.minified});
178
179 Map toJson() => {
180 'size': size,
181 'dart2jsVersion': dart2jsVersion,
182 'compilationMoment': '$compilationMoment',
183 'compilationDuration': '${compilationDuration}',
184 'toJsonDuration': toJsonDuration,
185 'dumpInfoDuration': '$dumpInfoDuration',
186 'noSuchMethodEnabled': noSuchMethodEnabled,
187 'minified': minified,
188 };
189 }
190
191 class LibraryInfo extends BasicInfo {
192 Uri uri;
193 final List<FunctionInfo> topLevelFunctions = <FunctionInfo>[];
194 final List<FieldInfo> topLevelVariables = <FieldInfo>[];
195 final List<ClassInfo> classes = <ClassInfo>[];
196 final List<TypedefInfo> typedefs = <TypedefInfo>[];
197
198 static int _id = 0;
199
200 bool get isEmpty =>
201 topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty;
202
203 LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size)
204 : super('library', _id++, name, outputUnit, size);
205
206 Map toJson() => super.toJson()
207 ..addAll({
208 'children': []
209 ..addAll(topLevelFunctions.map((f) => f.serializedId))
210 ..addAll(topLevelVariables.map((v) => v.serializedId))
211 ..addAll(classes.map((c) => c.serializedId))
212 ..addAll(typedefs.map((t) => t.serializedId)),
213 'canonicalUri': '$uri',
214 });
215 }
216
217 class OutputUnitInfo extends BasicInfo {
218 static int _ids = 0;
219 OutputUnitInfo(String name, int size)
220 : super('outputUnit', _ids++, name, null, size);
221 }
222
223 class ClassInfo extends BasicInfo {
224 bool isAbstract;
225
226 // TODO(sigmund): split static vs instance vs closures
227 final List<FunctionInfo> functions = <FunctionInfo>[];
228 final List<FieldInfo> fields = <FieldInfo>[];
229 static int _ids = 0;
230
231 ClassInfo(
232 {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0})
233 : super('class', _ids++, name, outputUnit, size);
234
235 Map toJson() => super.toJson()
236 ..addAll({
237 // TODO(sigmund): change format, include only when abstract is true.
238 'modifiers': {'abstract': isAbstract},
239 'children': []
240 ..addAll(fields.map((f) => f.serializedId))
241 ..addAll(functions.map((m) => m.serializedId))
242 });
243 }
244
245 class FieldInfo extends BasicInfo with CodeInfo {
246 String type;
247 String inferredType;
248 List<FunctionInfo> closures;
249 String code;
250
251 static int _ids = 0;
252 FieldInfo(
253 {String name,
254 int size: 0,
255 this.type,
256 this.inferredType,
257 this.closures,
258 this.code,
259 OutputUnitInfo outputUnit})
260 : super('field', _ids++, name, outputUnit, size);
261
262 Map toJson() => super.toJson()
263 ..addAll({
264 'children': closures.map((i) => i.serializedId).toList(),
265 'inferredType': inferredType,
266 'code': code,
267 'type': type,
268 });
269 }
270
271 class TypedefInfo extends BasicInfo {
272 String type;
273
274 static int _ids = 0;
275 TypedefInfo(String name, this.type, OutputUnitInfo outputUnit)
276 : super('typedef', _ids++, name, outputUnit, 0);
277
278 Map toJson() => super.toJson()..['type'] = '$type';
279 }
280
281 class FunctionInfo extends BasicInfo with CodeInfo {
282 static const int TOP_LEVEL_FUNCTION_KIND = 0;
283 static const int CLOSURE_FUNCTION_KIND = 1;
284 static const int METHOD_FUNCTION_KIND = 2;
285 static const int CONSTRUCTOR_FUNCTION_KIND = 3;
286 static int _ids = 0;
287
288 /// Kind of function (top-level function, closure, method, or constructor).
289 final int functionKind;
290
291 /// Modifiers applied to this function.
292 final FunctionModifiers modifiers;
293
294 /// Nested closures that appear within the body of this function.
295 List<FunctionInfo> closures;
296
297 /// The type of this function.
298 String type;
299
300 /// The declared return type.
301 String returnType;
302
303 /// The inferred return type.
304 String inferredReturnType;
305
306 /// Name and type information for each parameter.
307 List<ParameterInfo> parameters;
308
309 /// Side-effects.
310 // TODO(sigmund): serialize more precisely, not just a string representation.
311 String sideEffects;
312
313 /// How many function calls were inlined into this function.
314 int inlinedCount;
315
316 /// The actual generated code.
317 String code;
318
319 FunctionInfo(
320 {String name,
321 OutputUnitInfo outputUnit,
322 int size: 0,
323 this.functionKind,
324 this.modifiers,
325 this.closures,
326 this.type,
327 this.returnType,
328 this.inferredReturnType,
329 this.parameters,
330 this.sideEffects,
331 this.inlinedCount,
332 this.code})
333 : super('function', _ids++, name, outputUnit, size);
334
335 Map toJson() => super.toJson()
336 ..addAll({
337 'children': closures.map((i) => i.serializedId).toList(),
338 'modifiers': modifiers.toJson(),
339 'returnType': returnType,
340 'inferredReturnType': inferredReturnType,
341 'parameters': parameters.map((p) => p.toJson()).toList(),
342 'sideEffects': sideEffects,
343 'inlinedCount': inlinedCount,
344 'code': code,
345 'type': type,
346 // Note: version 3.2 of dump-info serializes `uses` in a section called
347 // `holding` at the top-level.
348 });
349 }
350
351 /// Information about how a dependency is used.
352 class DependencyInfo {
353 /// The dependency, either a FunctionInfo or FieldInfo.
354 final Info target;
355
356 /// Either a selector mask indicating how this is used, or 'inlined'.
357 // TODO(sigmund): split mask into an enum or something more precise to really
358 // describe the dependencies in detail.
359 final String mask;
360
361 DependencyInfo(this.target, this.mask);
362
363 Map toJson() => {'id': target.serializedId, 'mask': mask};
364 }
365
366 /// Name and type information about a function parameter.
367 class ParameterInfo {
368 final String name;
369 final String type;
370 final String declaredType;
371
372 ParameterInfo(this.name, this.type, this.declaredType);
373
374 Map toJson() => {'name': name, 'type': type, 'declaredType': declaredType};
375 }
376
377 /// Modifiers that may apply to methods.
378 class FunctionModifiers {
379 final bool isStatic;
380 final bool isConst;
381 final bool isFactory;
382 final bool isExternal;
383
384 FunctionModifiers(
385 {this.isStatic: false,
386 this.isConst: false,
387 this.isFactory: false,
388 this.isExternal: false});
389
390 // TODO(sigmund): exclude false values (requires bumping the format version):
391 // Map toJson() {
392 // var res = <String, bool>{};
393 // if (isStatic) res['static'] = true;
394 // if (isConst) res['const'] = true;
395 // if (isFactory) res['factory'] = true;
396 // if (isExternal) res['external'] = true;
397 // return res;
398 // }
399 Map toJson() => {
400 'static': isStatic,
401 'const': isConst,
402 'factory': isFactory,
403 'external': isExternal,
404 };
405 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/dump_info.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698