Chromium Code Reviews| Index: lib/src/summary.dart |
| diff --git a/lib/src/summary.dart b/lib/src/summary.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f5c8ab6918d903fef192e6f469a98a2a4eb4c03d |
| --- /dev/null |
| +++ b/lib/src/summary.dart |
| @@ -0,0 +1,212 @@ |
| +// 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. |
| + |
| +/// Summary of error messages produced by a `SummaryReporter`. |
| +library dev_compiler.src.summary; |
| + |
| +import 'package:source_span/source_span.dart'; |
| + |
| +/// Summary information computed by the DDC checker. |
|
Siggi Cherem (dart-lang)
2015/03/07 02:43:01
most of this file is unmodified except that I adde
|
| +abstract class Summary { |
| + Map toJsonMap(); |
| + |
| + void accept(SummaryVisitor visitor); |
| +} |
| + |
| +/// Summary for the entire program. |
| +class GlobalSummary implements Summary { |
| + /// Summary from the system libaries. |
| + final Map<String, LibrarySummary> system = <String, LibrarySummary>{}; |
| + |
| + /// Summary for libraries in packages. |
| + final Map<String, PackageSummary> packages = <String, PackageSummary>{}; |
| + |
| + /// Summary for loose files |
| + // TODO(sigmund): consider inferring the package from the pubspec instead? |
| + final Map<String, IndividualSummary> loose = <String, IndividualSummary>{}; |
| + |
| + GlobalSummary(); |
| + |
| + Map toJsonMap() => { |
| + 'system': system.values.map((l) => l.toJsonMap()).toList(), |
| + 'packages': packages.values.map((p) => p.toJsonMap()).toList(), |
| + 'loose': |
| + loose.values.map((l) => ['${l.runtimeType}', l.toJsonMap()]).toList(), |
| + }; |
| + |
| + void accept(SummaryVisitor visitor) => visitor.visitGlobal(this); |
| + |
| + static GlobalSummary parse(Map json) { |
| + var res = new GlobalSummary(); |
| + json['system'].map(LibrarySummary.parse).forEach((l) { |
| + res.system[l.name] = l; |
| + }); |
| + json['packages'].map(PackageSummary.parse).forEach((p) { |
| + res.packages[p.name] = p; |
| + }); |
| + json['loose'].forEach((e) { |
| + var summary = e[0] == 'LibrarySummary' |
| + ? LibrarySummary.parse(e[1]) |
| + : HtmlSummary.parse(e[1]); |
| + res.loose[summary.name] = summary; |
| + }); |
| + return res; |
| + } |
| +} |
| + |
| +/// A summary of a package. |
| +class PackageSummary implements Summary { |
| + final String name; |
| + final Map<String, LibrarySummary> libraries = <String, LibrarySummary>{}; |
| + |
| + PackageSummary(this.name); |
| + |
| + Map toJsonMap() => { |
| + 'package_name': name, |
| + 'libraries': libraries.values.map((l) => l.toJsonMap()).toList(), |
| + }; |
| + |
| + void accept(SummaryVisitor visitor) => visitor.visitPackage(this); |
| + |
| + static PackageSummary parse(Map json) { |
| + var res = new PackageSummary(json['package_name']); |
| + json['libraries'].map(LibrarySummary.parse).forEach((l) { |
| + res.libraries[l.name] = l; |
| + }); |
| + return res; |
| + } |
| +} |
| + |
| +/// A summary for a library or an html file. |
| +abstract class IndividualSummary extends Summary { |
| + /// Unique name for this library. |
| + String get name; |
| + |
| + List<MessageSummary> get messages; |
| +} |
| + |
| +/// A summary at the level of a library. |
| +class LibrarySummary implements IndividualSummary { |
| + /// Unique name for this library. |
| + final String name; |
| + |
| + /// All messages collected for the library. |
| + final List<MessageSummary> messages; |
| + |
| + /// Total lines of code (including all parts of the library). |
| + int lines; |
| + |
| + LibrarySummary(this.name, [List<MessageSummary> messages, this.lines = 0]) |
| + : messages = messages == null ? <MessageSummary>[] : messages; |
| + |
| + Map toJsonMap() => { |
| + 'library_name': name, |
| + 'messages': messages.map((m) => m.toJsonMap()).toList(), |
| + 'lines': lines, |
| + }; |
| + |
| + void accept(SummaryVisitor visitor) => visitor.visitLibrary(this); |
| + |
| + static LibrarySummary parse(Map json) => new LibrarySummary( |
| + json['library_name'], json['messages'].map(MessageSummary.parse).toList(), |
| + json['lines']); |
| +} |
| + |
| +/// A summary at the level of an HTML file. |
| +class HtmlSummary implements IndividualSummary { |
| + /// Unique name used to identify the HTML file. |
| + final String name; |
| + |
| + /// All messages collected on the file. |
| + final List<MessageSummary> messages; |
| + |
| + HtmlSummary(this.name, [List<MessageSummary> messages]) |
| + : messages = messages == null ? <MessageSummary>[] : messages; |
| + |
| + Map toJsonMap() => |
| + {'name': name, 'messages': messages.map((m) => m.toJsonMap()).toList()}; |
| + |
| + void accept(SummaryVisitor visitor) => visitor.visitHtml(this); |
| + |
| + static HtmlSummary parse(Map json) => new HtmlSummary( |
| + json['name'], json['messages'].map(MessageSummary.parse).toList()); |
| +} |
| + |
| +/// A single message produced by the checker. |
| +class MessageSummary implements Summary { |
| + /// The kind of message, currently the name of the StaticInfo type. |
| + final String kind; |
| + |
| + /// Level (error, warning, etc). |
| + final String level; |
| + |
| + /// Location where the error is reported. |
| + final SourceSpan span; |
| + final String message; |
| + |
| + MessageSummary(this.kind, this.level, this.span, this.message); |
| + |
| + Map toJsonMap() => { |
| + 'kind': kind, |
| + 'level': level, |
| + 'message': message, |
| + 'url': '${span.sourceUrl}', |
| + 'start': span.start.offset, |
| + 'end': span.end.offset, |
| + 'text': span.text, |
| + }; |
| + |
| + void accept(SummaryVisitor visitor) => visitor.visitMessage(this); |
| + |
| + static MessageSummary parse(Map json) { |
| + var start = new SourceLocation(json['start'], sourceUrl: json['url']); |
| + var end = new SourceLocation(json['end'], sourceUrl: json['url']); |
| + var span = new SourceSpanBase(start, end, json['text']); |
| + return new MessageSummary( |
| + json['kind'], json['level'], span, json['message']); |
| + } |
| +} |
| + |
| +/// A visitor of the [Summary] hierarchy. |
| +abstract class SummaryVisitor { |
| + void visitGlobal(GlobalSummary global); |
| + void visitPackage(PackageSummary package); |
| + void visitLibrary(LibrarySummary lib); |
| + void visitHtml(HtmlSummary html); |
| + void visitMessage(MessageSummary message); |
| +} |
| + |
| +/// A recursive [SummaryVisitor] that visits summaries on a top-down fashion. |
| +class RecursiveSummaryVisitor implements SummaryVisitor { |
| + void visitGlobal(GlobalSummary global) { |
| + for (var lib in global.system.values) { |
| + lib.accept(this); |
| + } |
| + for (var package in global.packages.values) { |
| + package.accept(this); |
| + } |
| + for (var libOrHtml in global.loose.values) { |
| + libOrHtml.accept(this); |
| + } |
| + } |
| + |
| + void visitPackage(PackageSummary package) { |
| + for (var lib in package.libraries.values) { |
| + lib.accept(this); |
| + } |
| + } |
| + |
| + void visitLibrary(LibrarySummary lib) { |
| + for (var msg in lib.messages) { |
| + msg.accept(this); |
| + } |
| + } |
| + |
| + void visitHtml(HtmlSummary html) { |
| + for (var msg in html.messages) { |
| + msg.accept(this); |
| + } |
| + } |
| + void visitMessage(MessageSummary message) {} |
| +} |