| Index: pkg/compiler/lib/src/info/info.dart
|
| diff --git a/pkg/compiler/lib/src/info/info.dart b/pkg/compiler/lib/src/info/info.dart
|
| deleted file mode 100644
|
| index 6a6f747ef7947daccbb3a15331eb78799c800353..0000000000000000000000000000000000000000
|
| --- a/pkg/compiler/lib/src/info/info.dart
|
| +++ /dev/null
|
| @@ -1,745 +0,0 @@
|
| -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -/// Data collected by the dump-info task.
|
| -library compiler.src.lib.info;
|
| -
|
| -// Note: this file intentionally doesn't import anything from the compiler. That
|
| -// should make it easier for tools to depend on this library. The idea is that
|
| -// by using this library, tools can consume the information in the same way it
|
| -// is produced by the compiler.
|
| -// TODO(sigmund): make this a proper public API (export this explicitly at the
|
| -// lib folder level.)
|
| -
|
| -/// Common interface to many pieces of information generated by the compiler.
|
| -abstract class Info {
|
| - /// An identifier for the kind of information.
|
| - InfoKind get kind;
|
| -
|
| - /// Name of the element associated with this info.
|
| - String name;
|
| -
|
| - /// An id to uniquely identify this info among infos of the same [kind].
|
| - int get id;
|
| -
|
| - /// A globally unique id combining [kind] and [id] together.
|
| - String get serializedId;
|
| -
|
| - /// Id used by the compiler when instrumenting code for code coverage.
|
| - // TODO(sigmund): It would be nice if we could use the same id for
|
| - // serialization and for coverage. Could we unify them?
|
| - String coverageId;
|
| -
|
| - /// Bytes used in the generated code for the corresponding element.
|
| - int size;
|
| -
|
| - /// Info of the enclosing element.
|
| - Info parent;
|
| -
|
| - /// Serializes the information into a JSON format.
|
| - // TODO(sigmund): refactor and put toJson outside the class, so we can have 2
|
| - // different serializer/deserializers at once.
|
| - Map toJson();
|
| -
|
| - void accept(InfoVisitor visitor);
|
| -}
|
| -
|
| -/// Common information used for most kind of elements.
|
| -// TODO(sigmund): add more:
|
| -// - inputSize: bytes used in the Dart source program
|
| -abstract class BasicInfo implements Info {
|
| - final InfoKind kind;
|
| - final int id;
|
| - String coverageId;
|
| - int size;
|
| - Info parent;
|
| -
|
| - String get serializedId => '${_kindToString(kind)}/$id';
|
| -
|
| - String name;
|
| -
|
| - /// If using deferred libraries, where the element associated with this info
|
| - /// is generated.
|
| - OutputUnitInfo outputUnit;
|
| -
|
| - BasicInfo(this.kind, this.id, this.name, this.outputUnit, this.size,
|
| - this.coverageId);
|
| -
|
| - BasicInfo._fromId(String serializedId)
|
| - : kind = _kindFromSerializedId(serializedId),
|
| - id = _idFromSerializedId(serializedId);
|
| -
|
| - Map toJson() {
|
| - var res = {
|
| - 'id': serializedId,
|
| - 'kind': _kindToString(kind),
|
| - 'name': name,
|
| - 'size': size,
|
| - };
|
| - // TODO(sigmund): Omit this also when outputUnit.id == 0 (most code is in
|
| - // the main output unit by default).
|
| - if (outputUnit != null) res['outputUnit'] = outputUnit.serializedId;
|
| - if (coverageId != null) res['coverageId'] = coverageId;
|
| - if (parent != null) res['parent'] = parent.serializedId;
|
| - return res;
|
| - }
|
| -
|
| - String toString() => '$serializedId $name [$size]';
|
| -}
|
| -
|
| -/// Info associated with elements containing executable code (like fields and
|
| -/// methods)
|
| -abstract class CodeInfo implements Info {
|
| - /// How does this function or field depend on others.
|
| - final List<DependencyInfo> uses = <DependencyInfo>[];
|
| -}
|
| -
|
| -
|
| -/// The entire information produced while compiling a program.
|
| -class AllInfo {
|
| - /// Summary information about the program.
|
| - ProgramInfo program;
|
| -
|
| - /// Information about each library processed by the compiler.
|
| - List<LibraryInfo> libraries = <LibraryInfo>[];
|
| -
|
| - /// Information about each function (includes methods and getters in any
|
| - /// library)
|
| - List<FunctionInfo> functions = <FunctionInfo>[];
|
| -
|
| - /// Information about type defs in the program.
|
| - List<TypedefInfo> typedefs = <TypedefInfo>[];
|
| -
|
| - /// Information about each class (in any library).
|
| - List<ClassInfo> classes = <ClassInfo>[];
|
| -
|
| - /// Information about fields (in any class).
|
| - List<FieldInfo> fields = <FieldInfo>[];
|
| -
|
| - /// Information about output units (should be just one entry if not using
|
| - /// deferred loading).
|
| - List<OutputUnitInfo> outputUnits = <OutputUnitInfo>[];
|
| -
|
| - /// Details about all deferred imports and what files would be loaded when the
|
| - /// import is resolved.
|
| - // TODO(sigmund): use a different format for dump-info. This currently emits
|
| - // the same map that is created for the `--deferred-map` flag.
|
| - Map<String, Map<String, dynamic>> deferredFiles;
|
| -
|
| - /// A new representation of dependencies form one info to another. An entry in
|
| - /// this map indicates that an Info depends on another (e.g. a function
|
| - /// invokes another). Please note that the data in this field might not be
|
| - /// accurate yet (this is work in progress).
|
| - Map<Info, List<Info>> dependencies = {};
|
| -
|
| - /// Major version indicating breaking changes in the format. A new version
|
| - /// means that an old deserialization algorithm will not work with the new
|
| - /// format.
|
| - final int version = 3;
|
| -
|
| - /// Minor version indicating non-breaking changes in the format. A change in
|
| - /// this version number means that the json parsing in this library from a
|
| - /// previous will continue to work after the change. This is typically
|
| - /// increased when adding new entries to the file format.
|
| - // Note: the dump-info.viewer app was written using a json parser version 3.2.
|
| - final int minorVersion = 5;
|
| -
|
| - AllInfo();
|
| -
|
| - static AllInfo parseFromJson(Map map) => new _ParseHelper().parseAll(map);
|
| -
|
| - Map _listAsJsonMap(List<Info> list) {
|
| - var map = <String, Map>{};
|
| - for (var info in list) {
|
| - map['${info.id}'] = info.toJson();
|
| - }
|
| - return map;
|
| - }
|
| -
|
| - Map _extractHoldingInfo() {
|
| - var map = <String, List>{};
|
| - void helper(CodeInfo info) {
|
| - if (info.uses.isEmpty) return;
|
| - map[info.serializedId] = info.uses.map((u) => u.toJson()).toList();
|
| - }
|
| - functions.forEach(helper);
|
| - fields.forEach(helper);
|
| - return map;
|
| - }
|
| -
|
| - Map _extractDependencies() {
|
| - var map = <String, List>{};
|
| - dependencies.forEach((k, v) {
|
| - map[k.serializedId] = v.map((i) => i.serializedId).toList();
|
| - });
|
| - return map;
|
| - }
|
| -
|
| - Map toJson() => {
|
| - 'elements': {
|
| - 'library': _listAsJsonMap(libraries),
|
| - 'class': _listAsJsonMap(classes),
|
| - 'function': _listAsJsonMap(functions),
|
| - 'typedef': _listAsJsonMap(typedefs),
|
| - 'field': _listAsJsonMap(fields),
|
| - },
|
| - 'holding': _extractHoldingInfo(),
|
| - 'dependencies': _extractDependencies(),
|
| - 'outputUnits': outputUnits.map((u) => u.toJson()).toList(),
|
| - 'dump_version': version,
|
| - 'deferredFiles': deferredFiles,
|
| - 'dump_minor_version': '$minorVersion',
|
| - // TODO(sigmund): change viewer to accept an int?
|
| - 'program': program.toJson(),
|
| - };
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitAll(this);
|
| -}
|
| -
|
| -class ProgramInfo {
|
| - int size;
|
| - String dart2jsVersion;
|
| - DateTime compilationMoment;
|
| - Duration compilationDuration;
|
| - // TODO(sigmund): use Duration.
|
| - int toJsonDuration;
|
| - int dumpInfoDuration;
|
| - bool noSuchMethodEnabled;
|
| - bool minified;
|
| -
|
| - ProgramInfo(
|
| - {this.size,
|
| - this.dart2jsVersion,
|
| - this.compilationMoment,
|
| - this.compilationDuration,
|
| - this.toJsonDuration,
|
| - this.dumpInfoDuration,
|
| - this.noSuchMethodEnabled,
|
| - this.minified});
|
| -
|
| - Map toJson() => {
|
| - 'size': size,
|
| - 'dart2jsVersion': dart2jsVersion,
|
| - 'compilationMoment': '$compilationMoment',
|
| - 'compilationDuration': '${compilationDuration}',
|
| - 'toJsonDuration': toJsonDuration,
|
| - 'dumpInfoDuration': '$dumpInfoDuration',
|
| - 'noSuchMethodEnabled': noSuchMethodEnabled,
|
| - 'minified': minified,
|
| - };
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitProgram(this);
|
| -}
|
| -
|
| -// TODO(sigmund): add unit tests.
|
| -class _ParseHelper {
|
| - Map<String, Info> registry = {};
|
| -
|
| - AllInfo parseAll(Map json) {
|
| - var result = new AllInfo();
|
| - var elements = json['elements'];
|
| - result.libraries.addAll(elements['library'].values.map(parseLibrary));
|
| - result.classes.addAll(elements['class'].values.map(parseClass));
|
| - result.functions.addAll(elements['function'].values.map(parseFunction));
|
| - result.fields.addAll(elements['field'].values.map(parseField));
|
| - result.typedefs.addAll(elements['typedef'].values.map(parseTypedef));
|
| -
|
| - var idMap = {};
|
| - for (var f in result.functions) {
|
| - idMap[f.serializedId] = f;
|
| - }
|
| - for (var f in result.fields) {
|
| - idMap[f.serializedId] = f;
|
| - }
|
| -
|
| - json['holding'].forEach((k, deps) {
|
| - var src = idMap[k];
|
| - assert (src != null);
|
| - for (var dep in deps) {
|
| - var target = idMap[dep['id']];
|
| - assert (target != null);
|
| - src.uses.add(new DependencyInfo(target, dep['mask']));
|
| - }
|
| - });
|
| -
|
| - json['dependencies']?.forEach((k, deps) {
|
| - result.dependencies[idMap[k]] = deps.map((d) => idMap[d]).toList();
|
| - });
|
| -
|
| - result.program = parseProgram(json['program']);
|
| - // todo: version, etc
|
| - return result;
|
| - }
|
| -
|
| - LibraryInfo parseLibrary(Map json) {
|
| - LibraryInfo result = parseId(json['id']);
|
| - result..name = json['name']
|
| - ..uri = Uri.parse(json['canonicalUri'])
|
| - ..outputUnit = parseId(json['outputUnit'])
|
| - ..size = json['size'];
|
| - for (var child in json['children'].map(parseId)) {
|
| - if (child is FunctionInfo) {
|
| - result.topLevelFunctions.add(child);
|
| - } else if (child is FieldInfo) {
|
| - result.topLevelVariables.add(child);
|
| - } else if (child is ClassInfo) {
|
| - result.classes.add(child);
|
| - } else {
|
| - assert(child is TypedefInfo);
|
| - result.typedefs.add(child);
|
| - }
|
| - }
|
| - return result;
|
| - }
|
| -
|
| - ClassInfo parseClass(Map json) {
|
| - ClassInfo result = parseId(json['id']);
|
| - result..name = json['name']
|
| - ..parent = parseId(json['parent'])
|
| - ..outputUnit = parseId(json['outputUnit'])
|
| - ..size = json['size']
|
| - ..isAbstract = json['modifiers']['abstract'] == true;
|
| - assert(result is ClassInfo);
|
| - for (var child in json['children'].map(parseId)) {
|
| - if (child is FunctionInfo) {
|
| - result.functions.add(child);
|
| - } else {
|
| - assert(child is FieldInfo);
|
| - result.fields.add(child);
|
| - }
|
| - }
|
| - return result;
|
| - }
|
| -
|
| - FieldInfo parseField(Map json) {
|
| - FieldInfo result = parseId(json['id']);
|
| - return result..name = json['name']
|
| - ..parent = parseId(json['parent'])
|
| - ..coverageId = json['coverageId']
|
| - ..outputUnit = parseId(json['outputUnit'])
|
| - ..size = json['size']
|
| - ..type = json['type']
|
| - ..inferredType = json['inferredType']
|
| - ..code = json['code']
|
| - ..closures = json['children'].map(parseId).toList();
|
| - }
|
| -
|
| - TypedefInfo parseTypedef(Map json) {
|
| - TypedefInfo result = parseId(json['id']);
|
| - return result..name = json['name']
|
| - ..parent = parseId(json['parent'])
|
| - ..type = json['type']
|
| - ..size = 0;
|
| - }
|
| -
|
| - ProgramInfo parseProgram(Map json) =>
|
| - new ProgramInfo()..size = json['size'];
|
| -
|
| - FunctionInfo parseFunction(Map json) {
|
| - FunctionInfo result = parseId(json['id']);
|
| - return result..name = json['name']
|
| - ..parent = parseId(json['parent'])
|
| - ..coverageId = json['coverageId']
|
| - ..outputUnit = parseId(json['outputUnit'])
|
| - ..size = json['size']
|
| - ..type = json['type']
|
| - ..returnType = json['returnType']
|
| - ..inferredReturnType = json['inferredReturnType']
|
| - ..parameters = json['parameters'].map(parseParameter).toList()
|
| - ..code = json['code']
|
| - ..sideEffects = json['sideEffects']
|
| - ..modifiers = parseModifiers(json['modifiers'])
|
| - ..closures = json['children'].map(parseId).toList();
|
| - }
|
| -
|
| - ParameterInfo parseParameter(Map json) =>
|
| - new ParameterInfo(json['name'], json['type'], json['declaredType']);
|
| -
|
| - FunctionModifiers parseModifiers(Map<String, bool> json) {
|
| - return new FunctionModifiers(
|
| - isStatic: json['static'] == true,
|
| - isConst: json['const'] == true,
|
| - isFactory: json['factory'] == true,
|
| - isExternal: json['external'] == true);
|
| - }
|
| -
|
| - Info parseId(String serializedId) => registry.putIfAbsent(serializedId, () {
|
| - if (serializedId == null) {
|
| - return null;
|
| - } else if (serializedId.startsWith('function/')) {
|
| - return new FunctionInfo._(serializedId);
|
| - } else if (serializedId.startsWith('library/')) {
|
| - return new LibraryInfo._(serializedId);
|
| - } else if (serializedId.startsWith('class/')) {
|
| - return new ClassInfo._(serializedId);
|
| - } else if (serializedId.startsWith('field/')) {
|
| - return new FieldInfo._(serializedId);
|
| - } else if (serializedId.startsWith('typedef/')) {
|
| - return new TypedefInfo._(serializedId);
|
| - } else if (serializedId.startsWith('outputUnit/')) {
|
| - return new OutputUnitInfo._(serializedId);
|
| - }
|
| - assert(false);
|
| - });
|
| -}
|
| -
|
| -/// Info associated with a library element.
|
| -class LibraryInfo extends BasicInfo {
|
| - /// Canonical uri that identifies the library.
|
| - Uri uri;
|
| -
|
| - /// Top level functions defined within the library.
|
| - final List<FunctionInfo> topLevelFunctions = <FunctionInfo>[];
|
| -
|
| - /// Top level fields defined within the library.
|
| - final List<FieldInfo> topLevelVariables = <FieldInfo>[];
|
| -
|
| - /// Classes defined within the library.
|
| - final List<ClassInfo> classes = <ClassInfo>[];
|
| -
|
| - /// Typedefs defined within the library.
|
| - final List<TypedefInfo> typedefs = <TypedefInfo>[];
|
| -
|
| - static int _id = 0;
|
| -
|
| - /// Whether there is any information recorded for this library.
|
| - bool get isEmpty =>
|
| - topLevelFunctions.isEmpty && topLevelVariables.isEmpty && classes.isEmpty;
|
| -
|
| - LibraryInfo(String name, this.uri, OutputUnitInfo outputUnit, int size)
|
| - : super(InfoKind.library, _id++, name, outputUnit, size, null);
|
| -
|
| - LibraryInfo._(String serializedId) : super._fromId(serializedId);
|
| -
|
| - Map toJson() => super.toJson()
|
| - ..addAll({
|
| - 'children': []
|
| - ..addAll(topLevelFunctions.map((f) => f.serializedId))
|
| - ..addAll(topLevelVariables.map((v) => v.serializedId))
|
| - ..addAll(classes.map((c) => c.serializedId))
|
| - ..addAll(typedefs.map((t) => t.serializedId)),
|
| - 'canonicalUri': '$uri',
|
| - });
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitLibrary(this);
|
| -}
|
| -
|
| -/// Information about an output unit. Normally there is just one for the entire
|
| -/// program unless the application uses deferred imports, in which case there
|
| -/// would be an additional output unit per deferred chunk.
|
| -class OutputUnitInfo extends BasicInfo {
|
| - static int _ids = 0;
|
| - OutputUnitInfo(String name, int size)
|
| - : super(InfoKind.outputUnit, _ids++, name, null, size, null);
|
| -
|
| - OutputUnitInfo._(String serializedId) : super._fromId(serializedId);
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitOutput(this);
|
| -}
|
| -
|
| -/// Information about a class element.
|
| -class ClassInfo extends BasicInfo {
|
| - /// Whether the class is abstract.
|
| - bool isAbstract;
|
| -
|
| - // TODO(sigmund): split static vs instance vs closures
|
| - /// Functions (static or instance) defined in the class.
|
| - final List<FunctionInfo> functions = <FunctionInfo>[];
|
| -
|
| - /// Fields defined in the class.
|
| - // TODO(sigmund): currently appears to only be populated with instance fields,
|
| - // but this should be fixed.
|
| - final List<FieldInfo> fields = <FieldInfo>[];
|
| - static int _ids = 0;
|
| -
|
| - ClassInfo(
|
| - {String name, this.isAbstract, OutputUnitInfo outputUnit, int size: 0})
|
| - : super(InfoKind.clazz, _ids++, name, outputUnit, size, null);
|
| -
|
| - ClassInfo._(String serializedId) : super._fromId(serializedId);
|
| -
|
| - Map toJson() => super.toJson()
|
| - ..addAll({
|
| - // TODO(sigmund): change format, include only when abstract is true.
|
| - 'modifiers': {'abstract': isAbstract},
|
| - 'children': []
|
| - ..addAll(fields.map((f) => f.serializedId))
|
| - ..addAll(functions.map((m) => m.serializedId))
|
| - });
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitClass(this);
|
| -}
|
| -
|
| -/// Information about a field element.
|
| -class FieldInfo extends BasicInfo with CodeInfo {
|
| - /// The type of the field.
|
| - String type;
|
| -
|
| - /// The type inferred by dart2js's whole program analysis
|
| - String inferredType;
|
| -
|
| - /// Nested closures seen in the field initializer.
|
| - List<FunctionInfo> closures;
|
| -
|
| - /// The actual generated code for the field.
|
| - String code;
|
| -
|
| - static int _ids = 0;
|
| - FieldInfo(
|
| - {String name,
|
| - String coverageId,
|
| - int size: 0,
|
| - this.type,
|
| - this.inferredType,
|
| - this.closures,
|
| - this.code,
|
| - OutputUnitInfo outputUnit})
|
| - : super(InfoKind.field, _ids++, name, outputUnit, size, coverageId);
|
| -
|
| - FieldInfo._(String serializedId) : super._fromId(serializedId);
|
| -
|
| - Map toJson() => super.toJson()
|
| - ..addAll({
|
| - 'children': closures.map((i) => i.serializedId).toList(),
|
| - 'inferredType': inferredType,
|
| - 'code': code,
|
| - 'type': type,
|
| - });
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitField(this);
|
| -}
|
| -
|
| -/// Information about a typedef declaration.
|
| -class TypedefInfo extends BasicInfo {
|
| - /// The declared type.
|
| - String type;
|
| -
|
| - static int _ids = 0;
|
| - TypedefInfo(String name, this.type, OutputUnitInfo outputUnit)
|
| - : super(InfoKind.typedef, _ids++, name, outputUnit, 0, null);
|
| -
|
| - TypedefInfo._(String serializedId) : super._fromId(serializedId);
|
| -
|
| - Map toJson() => super.toJson()..['type'] = '$type';
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitTypedef(this);
|
| -}
|
| -
|
| -/// Information about a function or method.
|
| -class FunctionInfo extends BasicInfo with CodeInfo {
|
| - static const int TOP_LEVEL_FUNCTION_KIND = 0;
|
| - static const int CLOSURE_FUNCTION_KIND = 1;
|
| - static const int METHOD_FUNCTION_KIND = 2;
|
| - static const int CONSTRUCTOR_FUNCTION_KIND = 3;
|
| - static int _ids = 0;
|
| -
|
| - /// Kind of function (top-level function, closure, method, or constructor).
|
| - int functionKind;
|
| -
|
| - /// Modifiers applied to this function.
|
| - FunctionModifiers modifiers;
|
| -
|
| - /// Nested closures that appear within the body of this function.
|
| - List<FunctionInfo> closures;
|
| -
|
| - /// The type of this function.
|
| - String type;
|
| -
|
| - /// The declared return type.
|
| - String returnType;
|
| -
|
| - /// The inferred return type.
|
| - String inferredReturnType;
|
| -
|
| - /// Name and type information for each parameter.
|
| - List<ParameterInfo> parameters;
|
| -
|
| - /// Side-effects.
|
| - // TODO(sigmund): serialize more precisely, not just a string representation.
|
| - String sideEffects;
|
| -
|
| - /// How many function calls were inlined into this function.
|
| - int inlinedCount;
|
| -
|
| - /// The actual generated code.
|
| - String code;
|
| -
|
| - FunctionInfo(
|
| - {String name,
|
| - String coverageId,
|
| - OutputUnitInfo outputUnit,
|
| - int size: 0,
|
| - this.functionKind,
|
| - this.modifiers,
|
| - this.closures,
|
| - this.type,
|
| - this.returnType,
|
| - this.inferredReturnType,
|
| - this.parameters,
|
| - this.sideEffects,
|
| - this.inlinedCount,
|
| - this.code})
|
| - : super(InfoKind.function, _ids++, name, outputUnit, size, coverageId);
|
| -
|
| - FunctionInfo._(String serializedId) : super._fromId(serializedId);
|
| -
|
| - Map toJson() => super.toJson()
|
| - ..addAll({
|
| - 'children': closures.map((i) => i.serializedId).toList(),
|
| - 'modifiers': modifiers.toJson(),
|
| - 'returnType': returnType,
|
| - 'inferredReturnType': inferredReturnType,
|
| - 'parameters': parameters.map((p) => p.toJson()).toList(),
|
| - 'sideEffects': sideEffects,
|
| - 'inlinedCount': inlinedCount,
|
| - 'code': code,
|
| - 'type': type,
|
| - // Note: version 3.2 of dump-info serializes `uses` in a section called
|
| - // `holding` at the top-level.
|
| - });
|
| -
|
| - void accept(InfoVisitor visitor) => visitor.visitFunction(this);
|
| -}
|
| -
|
| -/// Information about how a dependency is used.
|
| -class DependencyInfo {
|
| - /// The dependency, either a FunctionInfo or FieldInfo.
|
| - final Info target;
|
| -
|
| - /// Either a selector mask indicating how this is used, or 'inlined'.
|
| - // TODO(sigmund): split mask into an enum or something more precise to really
|
| - // describe the dependencies in detail.
|
| - final String mask;
|
| -
|
| - DependencyInfo(this.target, this.mask);
|
| -
|
| - Map toJson() => {'id': target.serializedId, 'mask': mask};
|
| -}
|
| -
|
| -/// Name and type information about a function parameter.
|
| -class ParameterInfo {
|
| - final String name;
|
| - final String type;
|
| - final String declaredType;
|
| -
|
| - ParameterInfo(this.name, this.type, this.declaredType);
|
| -
|
| - Map toJson() => {'name': name, 'type': type, 'declaredType': declaredType};
|
| -}
|
| -
|
| -/// Modifiers that may apply to methods.
|
| -class FunctionModifiers {
|
| - final bool isStatic;
|
| - final bool isConst;
|
| - final bool isFactory;
|
| - final bool isExternal;
|
| -
|
| - FunctionModifiers(
|
| - {this.isStatic: false,
|
| - this.isConst: false,
|
| - this.isFactory: false,
|
| - this.isExternal: false});
|
| -
|
| - // TODO(sigmund): exclude false values (requires bumping the format version):
|
| - // Map toJson() {
|
| - // var res = <String, bool>{};
|
| - // if (isStatic) res['static'] = true;
|
| - // if (isConst) res['const'] = true;
|
| - // if (isFactory) res['factory'] = true;
|
| - // if (isExternal) res['external'] = true;
|
| - // return res;
|
| - // }
|
| - Map toJson() => {
|
| - 'static': isStatic,
|
| - 'const': isConst,
|
| - 'factory': isFactory,
|
| - 'external': isExternal,
|
| - };
|
| -}
|
| -
|
| -/// Possible values of the `kind` field in the serialied infos.
|
| -enum InfoKind {
|
| - library,
|
| - clazz,
|
| - function,
|
| - field,
|
| - outputUnit,
|
| - typedef,
|
| -}
|
| -
|
| -String _kindToString(InfoKind kind) {
|
| - switch(kind) {
|
| - case InfoKind.library: return 'library';
|
| - case InfoKind.clazz: return 'class';
|
| - case InfoKind.function: return 'function';
|
| - case InfoKind.field: return 'field';
|
| - case InfoKind.outputUnit: return 'outputUnit';
|
| - case InfoKind.typedef: return 'typedef';
|
| - default: return null;
|
| - }
|
| -}
|
| -
|
| -int _idFromSerializedId(String serializedId) =>
|
| - int.parse(serializedId.substring(serializedId.indexOf('/') + 1));
|
| -
|
| -InfoKind _kindFromSerializedId(String serializedId) =>
|
| - _kindFromString(serializedId.substring(0, serializedId.indexOf('/')));
|
| -
|
| -InfoKind _kindFromString(String kind) {
|
| - switch(kind) {
|
| - case 'library': return InfoKind.library;
|
| - case 'class': return InfoKind.clazz;
|
| - case 'function': return InfoKind.function;
|
| - case 'field': return InfoKind.field;
|
| - case 'outputUnit': return InfoKind.outputUnit;
|
| - case 'typedef': return InfoKind.typedef;
|
| - default: return null;
|
| - }
|
| -}
|
| -
|
| -/// A simple visitor for information produced by the dart2js compiler.
|
| -class InfoVisitor {
|
| - visitAll(AllInfo info) {}
|
| - visitProgram(ProgramInfo info) {}
|
| - visitLibrary(LibraryInfo info) {}
|
| - visitClass(ClassInfo info) {}
|
| - visitField(FieldInfo info) {}
|
| - visitFunction(FunctionInfo info) {}
|
| - visitTypedef(TypedefInfo info) {}
|
| - visitOutput(OutputUnitInfo info) {}
|
| -}
|
| -
|
| -/// A visitor that recursively walks each portion of the program. Because the
|
| -/// info representation is redundant, this visitor only walks the structure of
|
| -/// the program and skips some redundant links. For example, even though
|
| -/// visitAll contains references to functions, this visitor only recurses to
|
| -/// visit libraries, then from each library we visit functions and classes, and
|
| -/// so on.
|
| -class RecursiveInfoVisitor extends InfoVisitor {
|
| - visitAll(AllInfo info) {
|
| - // Note: we don't visit functions, fields, classes, and typedefs because
|
| - // they are reachable from the library info.
|
| - info.libraries.forEach(visitLibrary);
|
| - }
|
| -
|
| - visitLibrary(LibraryInfo info) {
|
| - info.topLevelFunctions.forEach(visitFunction);
|
| - info.topLevelVariables.forEach(visitField);
|
| - info.classes.forEach(visitClass);
|
| - info.typedefs.forEach(visitTypedef);
|
| - }
|
| -
|
| - visitClass(ClassInfo info) {
|
| - info.functions.forEach(visitFunction);
|
| - info.fields.forEach(visitField);
|
| - }
|
| -
|
| - visitField(FieldInfo info) {
|
| - info.closures.forEach(visitFunction);
|
| - }
|
| -
|
| - visitFunction(FunctionInfo info) {
|
| - info.closures.forEach(visitFunction);
|
| - }
|
| -}
|
|
|