Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Data collected by the dump-info task. | 5 /// Data collected by the dump-info task. |
| 6 library compiler.src.lib.info; | 6 library compiler.src.lib.info; |
| 7 | 7 |
| 8 // Note: this file intentionally doesn't import anything from the compiler. That | 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 | 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 | 10 // by using this library, tools can consume the information in the same way it |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 /// A globally unique id combining [kind] and [id] together. | 26 /// A globally unique id combining [kind] and [id] together. |
| 27 String get serializedId; | 27 String get serializedId; |
| 28 | 28 |
| 29 /// Bytes used in the generated code for the corresponding element. | 29 /// Bytes used in the generated code for the corresponding element. |
| 30 int size; | 30 int size; |
| 31 | 31 |
| 32 /// Serializes the information into a JSON format. | 32 /// Serializes the information into a JSON format. |
| 33 // TODO(sigmund): refactor and put toJson outside the class, so we can have 2 | 33 // TODO(sigmund): refactor and put toJson outside the class, so we can have 2 |
| 34 // different serializer/deserializers at once. | 34 // different serializer/deserializers at once. |
| 35 Map toJson(); | 35 Map toJson(); |
| 36 | |
| 37 void accept(InfoVisitor visitor); | |
| 36 } | 38 } |
| 37 | 39 |
| 38 /// Common information used for most kind of elements. | 40 /// Common information used for most kind of elements. |
| 39 // TODO(sigmund): add more: | 41 // TODO(sigmund): add more: |
| 40 // - inputSize: bytes used in the Dart source program | 42 // - inputSize: bytes used in the Dart source program |
| 41 abstract class BasicInfo implements Info { | 43 abstract class BasicInfo implements Info { |
| 42 final String kind; | 44 final String kind; |
|
Harry Terkelsen
2015/08/11 01:15:18
consider making kind an enum?
Siggi Cherem (dart-lang)
2015/08/11 16:09:27
It's interesting because I only had in mind to use
Harry Terkelsen
2015/08/11 20:11:55
I've run into the same problem when trying to enum
| |
| 43 final int id; | 45 final int id; |
| 46 | |
| 47 /// Bytes used in the generated code for the corresponding element. | |
| 44 int size; | 48 int size; |
| 45 | 49 |
| 46 String get serializedId => '$kind/$id'; | 50 String get serializedId => '$kind/$id'; |
| 47 | 51 |
| 48 String name; | 52 String name; |
| 49 | 53 |
| 50 /// If using deferred libraries, where the element associated with this info | 54 /// If using deferred libraries, where the element associated with this info |
| 51 /// is generated. | 55 /// is generated. |
| 52 OutputUnitInfo outputUnit; | 56 OutputUnitInfo outputUnit; |
| 53 | 57 |
| 54 BasicInfo(this.kind, this.id, this.name, this.outputUnit, this.size); | 58 BasicInfo(this.kind, this.id, this.name, this.outputUnit, this.size); |
| 55 | 59 |
| 60 BasicInfo._fromId(String serializedId) | |
| 61 : kind = serializedId.substring(0, serializedId.indexOf('/')), | |
| 62 id = int.parse(serializedId.substring(serializedId.indexOf('/') + 1)); | |
| 63 | |
| 56 Map toJson() { | 64 Map toJson() { |
| 57 var res = {'id': serializedId, 'kind': kind, 'name': name, 'size': size}; | 65 var res = {'id': serializedId, 'kind': kind, 'name': name, 'size': size}; |
| 58 // TODO(sigmund): omit this also when outputUnit.id == 0 | 66 // TODO(sigmund): omit this also when outputUnit.id == 0 |
| 59 // (most code is by default in the main output unit) | 67 // (most code is by default in the main output unit) |
| 60 if (outputUnit != null) res['outputUnit'] = outputUnit.serializedId; | 68 if (outputUnit != null) res['outputUnit'] = outputUnit.serializedId; |
| 61 return res; | 69 return res; |
| 62 } | 70 } |
| 63 | 71 |
| 64 String toString() => '$serializedId $name [$size]'; | 72 String toString() => '$serializedId $name [$size]'; |
| 65 } | 73 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 | 118 |
| 111 /// Minor version indicating non-breaking changes in the format. A change in | 119 /// 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 | 120 /// 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 | 121 /// previous will continue to work after the change. This is typically |
| 114 /// increased when adding new entries to the file format. | 122 /// 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. | 123 // Note: the dump-info.viewer app was written using a json parser version 3.2. |
| 116 final int minorVersion = 3; | 124 final int minorVersion = 3; |
| 117 | 125 |
| 118 AllInfo(); | 126 AllInfo(); |
| 119 | 127 |
| 128 static AllInfo parseFromJson(Map map) => new _ParseHelper().parseAll(map); | |
| 129 | |
| 120 Map _listAsJsonMap(List<Info> list) { | 130 Map _listAsJsonMap(List<Info> list) { |
| 121 var map = <String, Map>{}; | 131 var map = <String, Map>{}; |
| 122 for (var info in list) { | 132 for (var info in list) { |
| 123 map['${info.id}'] = info.toJson(); | 133 map['${info.id}'] = info.toJson(); |
| 124 } | 134 } |
| 125 return map; | 135 return map; |
| 126 } | 136 } |
| 127 | 137 |
| 128 Map _extractHoldingInfo() { | 138 Map _extractHoldingInfo() { |
| 129 var map = <String, List>{}; | 139 var map = <String, List>{}; |
| 130 void helper(CodeInfo info) { | 140 void helper(CodeInfo info) { |
| 131 if (info.uses.isEmpty) return; | 141 if (info.uses.isEmpty) return; |
| 132 map[info.serializedId] = info.uses.map((u) => u.toJson()).toList(); | 142 map[info.serializedId] = info.uses.map((u) => u.toJson()).toList(); |
| 133 } | 143 } |
| 134 functions.forEach(helper); | 144 functions.forEach(helper); |
| 135 fields.forEach(helper); | 145 fields.forEach(helper); |
| 136 return map; | 146 return map; |
| 137 } | 147 } |
| 138 | 148 |
| 139 // TODO(sigmund): implement fromJson | |
| 140 Map toJson() => { | 149 Map toJson() => { |
| 141 'elements': { | 150 'elements': { |
| 142 'library': _listAsJsonMap(libraries), | 151 'library': _listAsJsonMap(libraries), |
| 143 'class': _listAsJsonMap(classes), | 152 'class': _listAsJsonMap(classes), |
| 144 'function': _listAsJsonMap(functions), | 153 'function': _listAsJsonMap(functions), |
| 145 'typedef': _listAsJsonMap(typedefs), | 154 'typedef': _listAsJsonMap(typedefs), |
| 146 'field': _listAsJsonMap(fields), | 155 'field': _listAsJsonMap(fields), |
| 147 }, | 156 }, |
| 148 'holding': _extractHoldingInfo(), | 157 'holding': _extractHoldingInfo(), |
| 149 'outputUnits': outputUnits.map((u) => u.toJson()).toList(), | 158 'outputUnits': outputUnits.map((u) => u.toJson()).toList(), |
| 150 'dump_version': version, | 159 'dump_version': version, |
| 151 'deferredFiles': deferredFiles, | 160 'deferredFiles': deferredFiles, |
| 152 'dump_minor_version': '$minorVersion', | 161 'dump_minor_version': '$minorVersion', |
| 153 // TODO(sigmund): change viewer to accept an int? | 162 // TODO(sigmund): change viewer to accept an int? |
| 154 'program': program.toJson(), | 163 'program': program.toJson(), |
| 155 }; | 164 }; |
| 165 | |
| 166 void accept(InfoVisitor visitor) => visitor.visitAll(this); | |
| 156 } | 167 } |
| 157 | 168 |
| 158 class ProgramInfo { | 169 class ProgramInfo { |
| 159 int size; | 170 int size; |
| 160 String dart2jsVersion; | 171 String dart2jsVersion; |
| 161 DateTime compilationMoment; | 172 DateTime compilationMoment; |
| 162 Duration compilationDuration; | 173 Duration compilationDuration; |
| 163 // TODO(sigmund): use Duration. | 174 // TODO(sigmund): use Duration. |
| 164 int toJsonDuration; | 175 int toJsonDuration; |
| 165 int dumpInfoDuration; | 176 int dumpInfoDuration; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 179 Map toJson() => { | 190 Map toJson() => { |
| 180 'size': size, | 191 'size': size, |
| 181 'dart2jsVersion': dart2jsVersion, | 192 'dart2jsVersion': dart2jsVersion, |
| 182 'compilationMoment': '$compilationMoment', | 193 'compilationMoment': '$compilationMoment', |
| 183 'compilationDuration': '${compilationDuration}', | 194 'compilationDuration': '${compilationDuration}', |
| 184 'toJsonDuration': toJsonDuration, | 195 'toJsonDuration': toJsonDuration, |
| 185 'dumpInfoDuration': '$dumpInfoDuration', | 196 'dumpInfoDuration': '$dumpInfoDuration', |
| 186 'noSuchMethodEnabled': noSuchMethodEnabled, | 197 'noSuchMethodEnabled': noSuchMethodEnabled, |
| 187 'minified': minified, | 198 'minified': minified, |
| 188 }; | 199 }; |
| 200 | |
| 201 void accept(InfoVisitor visitor) => visitor.visitProgram(this); | |
| 202 } | |
| 203 | |
| 204 class _ParseHelper { | |
|
Johnni Winther
2015/08/11 08:45:37
Do we have a test of the serialization/deserializa
Siggi Cherem (dart-lang)
2015/08/11 16:09:27
Not yet, but we will. Added a TODO
| |
| 205 Map<String, Info> registry = {}; | |
| 206 | |
| 207 AllInfo parseAll(Map json) { | |
| 208 var result = new AllInfo(); | |
| 209 var elements = json['elements']; | |
| 210 result.libraries.addAll(elements['library'].values.map(parseLibrary)); | |
| 211 result.classes.addAll(elements['class'].values.map(parseClass)); | |
| 212 result.functions.addAll(elements['function'].values.map(parseFunction)); | |
| 213 result.fields.addAll(elements['field'].values.map(parseField)); | |
| 214 result.typedefs.addAll(elements['typedef'].values.map(parseTypedef)); | |
| 215 | |
| 216 var idMap = {}; | |
| 217 for (var f in result.functions) { | |
| 218 idMap[f.serializedId] = f; | |
| 219 } | |
| 220 for (var f in result.fields) { | |
| 221 idMap[f.serializedId] = f; | |
| 222 } | |
| 223 | |
| 224 json['holding'].forEach((k, deps) { | |
| 225 var src = idMap[k]; | |
| 226 assert (src != null); | |
| 227 for (var dep in deps) { | |
| 228 var target = idMap[dep['id']]; | |
| 229 assert (target != null); | |
| 230 src.uses.add(new DependencyInfo(target, dep['mask'])); | |
| 231 } | |
| 232 }); | |
| 233 | |
| 234 result.program = parseProgram(json['program']); | |
| 235 // todo: version, etc | |
| 236 return result; | |
| 237 } | |
| 238 | |
| 239 LibraryInfo parseLibrary(Map json) { | |
| 240 var result = parseId(json['id']) | |
| 241 ..name = json['name'] | |
| 242 ..uri = Uri.parse(json['canonicalUri']) | |
| 243 ..outputUnit = parseId(json['outputUnit']) | |
| 244 ..size = json['size']; | |
| 245 assert(result.kind == 'library'); | |
| 246 for (var child in json['children'].map(parseId)) { | |
| 247 if (child is FunctionInfo) { | |
| 248 result.topLevelFunctions.add(child); | |
| 249 } else if (child is FieldInfo) { | |
| 250 result.topLevelVariables.add(child); | |
| 251 } else if (child is ClassInfo) { | |
| 252 result.classes.add(child); | |
| 253 } else { | |
| 254 assert(child is TypedefInfo); | |
| 255 result.typedefs.add(child); | |
| 256 } | |
| 257 } | |
| 258 return result; | |
| 259 } | |
| 260 | |
| 261 ClassInfo parseClass(Map json) { | |
| 262 var result = parseId(json['id']) | |
| 263 ..name = json['name'] | |
| 264 ..outputUnit = parseId(json['outputUnit']) | |
| 265 ..size = json['size'] | |
| 266 ..isAbstract = json['modifiers']['abstract'] == true; | |
| 267 assert(result.kind == 'class'); | |
| 268 for (var child in json['children'].map(parseId)) { | |
| 269 if (child is FunctionInfo) { | |
| 270 result.functions.add(child); | |
| 271 } else { | |
| 272 assert(child is FieldInfo); | |
| 273 result.fields.add(child); | |
| 274 } | |
| 275 } | |
| 276 return result; | |
| 277 } | |
| 278 | |
| 279 FieldInfo parseField(Map json) { | |
| 280 return parseId(json['id']) | |
| 281 ..name = json['name'] | |
| 282 ..outputUnit = parseId(json['outputUnit']) | |
| 283 ..size = json['size'] | |
| 284 ..type = json['type'] | |
| 285 ..inferredType = json['inferredType'] | |
| 286 ..code = json['code'] | |
| 287 ..closures = json['children'].map(parseId).toList(); | |
| 288 } | |
| 289 | |
| 290 TypedefInfo parseTypedef(Map json) => parseId(json['id']) | |
| 291 ..name = json['name'] | |
| 292 ..type = json['type'] | |
| 293 ..size = 0; | |
| 294 | |
| 295 ProgramInfo parseProgram(Map json) => | |
| 296 new ProgramInfo()..size = json['size']; | |
| 297 | |
| 298 FunctionInfo parseFunction(Map json) { | |
| 299 return parseId(json['id']) | |
| 300 ..name = json['name'] | |
| 301 ..outputUnit = parseId(json['outputUnit']) | |
| 302 ..size = json['size'] | |
| 303 ..type = json['type'] | |
| 304 ..returnType = json['returnType'] | |
| 305 ..inferredReturnType = json['inferredReturnType'] | |
| 306 ..parameters = json['parameters'].map(parseParameter).toList() | |
| 307 ..code = json['code'] | |
| 308 ..sideEffects = json['sideEffects'] | |
| 309 ..modifiers = parseModifiers(json['modifiers']) | |
| 310 ..closures = json['children'].map(parseId).toList(); | |
| 311 } | |
| 312 | |
| 313 ParameterInfo parseParameter(Map json) => | |
| 314 new ParameterInfo(json['name'], json['type'], json['declaredType']); | |
| 315 | |
| 316 FunctionModifiers parseModifiers(Map<String, bool> json) { | |
| 317 return new FunctionModifiers( | |
| 318 isStatic: json['static'] == true, | |
| 319 isConst: json['const'] == true, | |
| 320 isFactory: json['factory'] == true, | |
| 321 isExternal: json['external'] == true); | |
| 322 } | |
| 323 | |
| 324 Info parseId(String serializedId) => registry.putIfAbsent(serializedId, () { | |
| 325 if (serializedId == null) { | |
| 326 return null; | |
| 327 } else if (serializedId.startsWith('function/')) { | |
| 328 return new FunctionInfo._(serializedId); | |
| 329 } else if (serializedId.startsWith('library/')) { | |
| 330 return new LibraryInfo._(serializedId); | |
| 331 } else if (serializedId.startsWith('class/')) { | |
| 332 return new ClassInfo._(serializedId); | |
| 333 } else if (serializedId.startsWith('field/')) { | |
| 334 return new FieldInfo._(serializedId); | |
| 335 } else if (serializedId.startsWith('typedef/')) { | |
| 336 return new TypedefInfo._(serializedId); | |
| 337 } else if (serializedId.startsWith('outputUnit/')) { | |
| 338 return new OutputUnitInfo._(serializedId); | |
| 339 } | |
| 340 assert(false); | |
| 341 }); | |
| 189 } | 342 } |
| 190 | 343 |
| 191 class LibraryInfo extends BasicInfo { | 344 class LibraryInfo extends BasicInfo { |
| 192 Uri uri; | 345 Uri uri; |
| 193 final List<FunctionInfo> topLevelFunctions = <FunctionInfo>[]; | 346 final List<FunctionInfo> topLevelFunctions = <FunctionInfo>[]; |
|
Harry Terkelsen
2015/08/11 01:15:18
document all of the fields for the Info classes
Siggi Cherem (dart-lang)
2015/08/11 16:09:27
Done.
| |
| 194 final List<FieldInfo> topLevelVariables = <FieldInfo>[]; | 347 final List<FieldInfo> topLevelVariables = <FieldInfo>[]; |
| 195 final List<ClassInfo> classes = <ClassInfo>[]; | 348 final List<ClassInfo> classes = <ClassInfo>[]; |
| 196 final List<TypedefInfo> typedefs = <TypedefInfo>[]; | 349 final List<TypedefInfo> typedefs = <TypedefInfo>[]; |
| 197 | 350 |
| 198 static int _id = 0; | 351 static int _id = 0; |
| 199 | 352 |
| 200 bool get isEmpty => | 353 bool get isEmpty => |
| 201 topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty; | 354 topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty; |
| 202 | 355 |
| 203 LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size) | 356 LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size) |
| 204 : super('library', _id++, name, outputUnit, size); | 357 : super('library', _id++, name, outputUnit, size); |
| 205 | 358 |
| 359 LibraryInfo._(String serializedId) : super._fromId(serializedId); | |
| 360 | |
| 206 Map toJson() => super.toJson() | 361 Map toJson() => super.toJson() |
| 207 ..addAll({ | 362 ..addAll({ |
| 208 'children': [] | 363 'children': [] |
| 209 ..addAll(topLevelFunctions.map((f) => f.serializedId)) | 364 ..addAll(topLevelFunctions.map((f) => f.serializedId)) |
| 210 ..addAll(topLevelVariables.map((v) => v.serializedId)) | 365 ..addAll(topLevelVariables.map((v) => v.serializedId)) |
| 211 ..addAll(classes.map((c) => c.serializedId)) | 366 ..addAll(classes.map((c) => c.serializedId)) |
| 212 ..addAll(typedefs.map((t) => t.serializedId)), | 367 ..addAll(typedefs.map((t) => t.serializedId)), |
| 213 'canonicalUri': '$uri', | 368 'canonicalUri': '$uri', |
| 214 }); | 369 }); |
| 370 | |
| 371 void accept(InfoVisitor visitor) => visitor.visitLibrary(this); | |
| 215 } | 372 } |
| 216 | 373 |
| 217 class OutputUnitInfo extends BasicInfo { | 374 class OutputUnitInfo extends BasicInfo { |
| 218 static int _ids = 0; | 375 static int _ids = 0; |
| 219 OutputUnitInfo(String name, int size) | 376 OutputUnitInfo(String name, int size) |
| 220 : super('outputUnit', _ids++, name, null, size); | 377 : super('outputUnit', _ids++, name, null, size); |
| 378 | |
| 379 OutputUnitInfo._(String serializedId) : super._fromId(serializedId); | |
| 380 | |
| 381 void accept(InfoVisitor visitor) => visitor.visitOutput(this); | |
| 221 } | 382 } |
| 222 | 383 |
| 223 class ClassInfo extends BasicInfo { | 384 class ClassInfo extends BasicInfo { |
| 224 bool isAbstract; | 385 bool isAbstract; |
| 225 | 386 |
| 226 // TODO(sigmund): split static vs instance vs closures | 387 // TODO(sigmund): split static vs instance vs closures |
| 227 final List<FunctionInfo> functions = <FunctionInfo>[]; | 388 final List<FunctionInfo> functions = <FunctionInfo>[]; |
| 228 final List<FieldInfo> fields = <FieldInfo>[]; | 389 final List<FieldInfo> fields = <FieldInfo>[]; |
| 229 static int _ids = 0; | 390 static int _ids = 0; |
| 230 | 391 |
| 231 ClassInfo( | 392 ClassInfo( |
| 232 {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0}) | 393 {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0}) |
| 233 : super('class', _ids++, name, outputUnit, size); | 394 : super('class', _ids++, name, outputUnit, size); |
| 234 | 395 |
| 396 ClassInfo._(String serializedId) : super._fromId(serializedId); | |
| 397 | |
| 235 Map toJson() => super.toJson() | 398 Map toJson() => super.toJson() |
| 236 ..addAll({ | 399 ..addAll({ |
| 237 // TODO(sigmund): change format, include only when abstract is true. | 400 // TODO(sigmund): change format, include only when abstract is true. |
| 238 'modifiers': {'abstract': isAbstract}, | 401 'modifiers': {'abstract': isAbstract}, |
| 239 'children': [] | 402 'children': [] |
| 240 ..addAll(fields.map((f) => f.serializedId)) | 403 ..addAll(fields.map((f) => f.serializedId)) |
| 241 ..addAll(functions.map((m) => m.serializedId)) | 404 ..addAll(functions.map((m) => m.serializedId)) |
| 242 }); | 405 }); |
| 406 | |
| 407 void accept(InfoVisitor visitor) => visitor.visitClass(this); | |
| 243 } | 408 } |
| 244 | 409 |
| 245 class FieldInfo extends BasicInfo with CodeInfo { | 410 class FieldInfo extends BasicInfo with CodeInfo { |
| 246 String type; | 411 String type; |
| 247 String inferredType; | 412 String inferredType; |
| 248 List<FunctionInfo> closures; | 413 List<FunctionInfo> closures; |
| 249 String code; | 414 String code; |
| 250 | 415 |
| 251 static int _ids = 0; | 416 static int _ids = 0; |
| 252 FieldInfo( | 417 FieldInfo( |
| 253 {String name, | 418 {String name, |
| 254 int size: 0, | 419 int size: 0, |
| 255 this.type, | 420 this.type, |
| 256 this.inferredType, | 421 this.inferredType, |
| 257 this.closures, | 422 this.closures, |
| 258 this.code, | 423 this.code, |
| 259 OutputUnitInfo outputUnit}) | 424 OutputUnitInfo outputUnit}) |
| 260 : super('field', _ids++, name, outputUnit, size); | 425 : super('field', _ids++, name, outputUnit, size); |
| 261 | 426 |
| 427 FieldInfo._(String serializedId) : super._fromId(serializedId); | |
| 428 | |
| 262 Map toJson() => super.toJson() | 429 Map toJson() => super.toJson() |
| 263 ..addAll({ | 430 ..addAll({ |
| 264 'children': closures.map((i) => i.serializedId).toList(), | 431 'children': closures.map((i) => i.serializedId).toList(), |
| 265 'inferredType': inferredType, | 432 'inferredType': inferredType, |
| 266 'code': code, | 433 'code': code, |
| 267 'type': type, | 434 'type': type, |
| 268 }); | 435 }); |
| 436 | |
| 437 void accept(InfoVisitor visitor) => visitor.visitField(this); | |
| 269 } | 438 } |
| 270 | 439 |
| 271 class TypedefInfo extends BasicInfo { | 440 class TypedefInfo extends BasicInfo { |
| 272 String type; | 441 String type; |
| 273 | 442 |
| 274 static int _ids = 0; | 443 static int _ids = 0; |
| 275 TypedefInfo(String name, this.type, OutputUnitInfo outputUnit) | 444 TypedefInfo(String name, this.type, OutputUnitInfo outputUnit) |
| 276 : super('typedef', _ids++, name, outputUnit, 0); | 445 : super('typedef', _ids++, name, outputUnit, 0); |
| 277 | 446 |
| 447 TypedefInfo._(String serializedId) : super._fromId(serializedId); | |
| 448 | |
| 278 Map toJson() => super.toJson()..['type'] = '$type'; | 449 Map toJson() => super.toJson()..['type'] = '$type'; |
| 450 | |
| 451 void accept(InfoVisitor visitor) => visitor.visitTypedef(this); | |
| 279 } | 452 } |
| 280 | 453 |
| 281 class FunctionInfo extends BasicInfo with CodeInfo { | 454 class FunctionInfo extends BasicInfo with CodeInfo { |
| 282 static const int TOP_LEVEL_FUNCTION_KIND = 0; | 455 static const int TOP_LEVEL_FUNCTION_KIND = 0; |
| 283 static const int CLOSURE_FUNCTION_KIND = 1; | 456 static const int CLOSURE_FUNCTION_KIND = 1; |
| 284 static const int METHOD_FUNCTION_KIND = 2; | 457 static const int METHOD_FUNCTION_KIND = 2; |
| 285 static const int CONSTRUCTOR_FUNCTION_KIND = 3; | 458 static const int CONSTRUCTOR_FUNCTION_KIND = 3; |
| 286 static int _ids = 0; | 459 static int _ids = 0; |
| 287 | 460 |
| 288 /// Kind of function (top-level function, closure, method, or constructor). | 461 /// Kind of function (top-level function, closure, method, or constructor). |
| 289 final int functionKind; | 462 int functionKind; |
| 290 | 463 |
| 291 /// Modifiers applied to this function. | 464 /// Modifiers applied to this function. |
| 292 final FunctionModifiers modifiers; | 465 FunctionModifiers modifiers; |
| 293 | 466 |
| 294 /// Nested closures that appear within the body of this function. | 467 /// Nested closures that appear within the body of this function. |
| 295 List<FunctionInfo> closures; | 468 List<FunctionInfo> closures; |
| 296 | 469 |
| 297 /// The type of this function. | 470 /// The type of this function. |
| 298 String type; | 471 String type; |
| 299 | 472 |
| 300 /// The declared return type. | 473 /// The declared return type. |
| 301 String returnType; | 474 String returnType; |
| 302 | 475 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 325 this.closures, | 498 this.closures, |
| 326 this.type, | 499 this.type, |
| 327 this.returnType, | 500 this.returnType, |
| 328 this.inferredReturnType, | 501 this.inferredReturnType, |
| 329 this.parameters, | 502 this.parameters, |
| 330 this.sideEffects, | 503 this.sideEffects, |
| 331 this.inlinedCount, | 504 this.inlinedCount, |
| 332 this.code}) | 505 this.code}) |
| 333 : super('function', _ids++, name, outputUnit, size); | 506 : super('function', _ids++, name, outputUnit, size); |
| 334 | 507 |
| 508 FunctionInfo._(String serializedId) : super._fromId(serializedId); | |
| 509 | |
| 335 Map toJson() => super.toJson() | 510 Map toJson() => super.toJson() |
| 336 ..addAll({ | 511 ..addAll({ |
| 337 'children': closures.map((i) => i.serializedId).toList(), | 512 'children': closures.map((i) => i.serializedId).toList(), |
| 338 'modifiers': modifiers.toJson(), | 513 'modifiers': modifiers.toJson(), |
| 339 'returnType': returnType, | 514 'returnType': returnType, |
| 340 'inferredReturnType': inferredReturnType, | 515 'inferredReturnType': inferredReturnType, |
| 341 'parameters': parameters.map((p) => p.toJson()).toList(), | 516 'parameters': parameters.map((p) => p.toJson()).toList(), |
| 342 'sideEffects': sideEffects, | 517 'sideEffects': sideEffects, |
| 343 'inlinedCount': inlinedCount, | 518 'inlinedCount': inlinedCount, |
| 344 'code': code, | 519 'code': code, |
| 345 'type': type, | 520 'type': type, |
| 346 // Note: version 3.2 of dump-info serializes `uses` in a section called | 521 // Note: version 3.2 of dump-info serializes `uses` in a section called |
| 347 // `holding` at the top-level. | 522 // `holding` at the top-level. |
| 348 }); | 523 }); |
| 524 | |
| 525 void accept(InfoVisitor visitor) => visitor.visitFunction(this); | |
| 349 } | 526 } |
| 350 | 527 |
| 351 /// Information about how a dependency is used. | 528 /// Information about how a dependency is used. |
| 352 class DependencyInfo { | 529 class DependencyInfo { |
| 353 /// The dependency, either a FunctionInfo or FieldInfo. | 530 /// The dependency, either a FunctionInfo or FieldInfo. |
| 354 final Info target; | 531 final Info target; |
| 355 | 532 |
| 356 /// Either a selector mask indicating how this is used, or 'inlined'. | 533 /// 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 | 534 // TODO(sigmund): split mask into an enum or something more precise to really |
| 358 // describe the dependencies in detail. | 535 // describe the dependencies in detail. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 // if (isExternal) res['external'] = true; | 573 // if (isExternal) res['external'] = true; |
| 397 // return res; | 574 // return res; |
| 398 // } | 575 // } |
| 399 Map toJson() => { | 576 Map toJson() => { |
| 400 'static': isStatic, | 577 'static': isStatic, |
| 401 'const': isConst, | 578 'const': isConst, |
| 402 'factory': isFactory, | 579 'factory': isFactory, |
| 403 'external': isExternal, | 580 'external': isExternal, |
| 404 }; | 581 }; |
| 405 } | 582 } |
| 583 | |
| 584 /// A simple visitor for information produced by the dart2js compiler. | |
| 585 class InfoVisitor { | |
| 586 visitAll(AllInfo info) {} | |
| 587 visitProgram(ProgramInfo info) {} | |
| 588 visitLibrary(LibraryInfo info) {} | |
| 589 visitClass(ClassInfo info) {} | |
| 590 visitField(FieldInfo info) {} | |
| 591 visitFunction(FunctionInfo info) {} | |
| 592 visitTypedef(TypedefInfo info) {} | |
| 593 visitOutput(OutputUnitInfo info) {} | |
| 594 } | |
| 595 | |
| 596 /// A visitor that recursively walks each portion of the program. Because the | |
| 597 /// info representation is redundant, this visitor only walks the structure of | |
| 598 /// the program and skips some redundant links. For example, even though | |
| 599 /// visitAll contains references to functions, this visitor only recurses to | |
| 600 /// visit libraries, then from each library we visit functions and classes, and | |
| 601 /// so on. | |
| 602 class RecursiveInfoVisitor extends InfoVisitor { | |
| 603 visitAll(AllInfo info) { | |
| 604 // Note: we don't visit functions, fields, classes, and typedefs because | |
| 605 // they are reachable from the library info. | |
| 606 info.libraries.forEach(visitLibrary); | |
| 607 } | |
| 608 | |
| 609 visitLibrary(LibraryInfo info) { | |
| 610 info.topLevelFunctions.forEach(visitFunction); | |
| 611 info.topLevelVariables.forEach(visitField); | |
| 612 info.classes.forEach(visitClass); | |
| 613 info.typedefs.forEach(visitTypedef); | |
| 614 } | |
| 615 | |
| 616 visitClass(ClassInfo info) { | |
| 617 info.functions.forEach(visitFunction); | |
| 618 info.fields.forEach(visitField); | |
| 619 } | |
| 620 | |
| 621 visitField(FieldInfo info) { | |
| 622 info.closures.forEach(visitFunction); | |
| 623 } | |
| 624 | |
| 625 visitFunction(FunctionInfo info) { | |
| 626 info.closures.forEach(visitFunction); | |
| 627 } | |
| 628 | |
| 629 visitTypedef(TypedefInfo info) {} | |
|
Harry Terkelsen
2015/08/11 01:15:18
remove or make InfoVisitor abstract
Siggi Cherem (dart-lang)
2015/08/11 16:09:27
Done.
| |
| 630 visitOutput(OutputUnitInfo info) {} | |
|
Harry Terkelsen
2015/08/11 01:15:18
ditto
Siggi Cherem (dart-lang)
2015/08/11 16:09:27
Done.
| |
| 631 } | |
| OLD | NEW |