Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 /// Summary of error messages produced by a `SummaryReporter`. | |
| 6 library dev_compiler.src.summary; | |
| 7 | |
| 8 import 'package:source_span/source_span.dart'; | |
| 9 | |
| 10 /// 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
| |
| 11 abstract class Summary { | |
| 12 Map toJsonMap(); | |
| 13 | |
| 14 void accept(SummaryVisitor visitor); | |
| 15 } | |
| 16 | |
| 17 /// Summary for the entire program. | |
| 18 class GlobalSummary implements Summary { | |
| 19 /// Summary from the system libaries. | |
| 20 final Map<String, LibrarySummary> system = <String, LibrarySummary>{}; | |
| 21 | |
| 22 /// Summary for libraries in packages. | |
| 23 final Map<String, PackageSummary> packages = <String, PackageSummary>{}; | |
| 24 | |
| 25 /// Summary for loose files | |
| 26 // TODO(sigmund): consider inferring the package from the pubspec instead? | |
| 27 final Map<String, IndividualSummary> loose = <String, IndividualSummary>{}; | |
| 28 | |
| 29 GlobalSummary(); | |
| 30 | |
| 31 Map toJsonMap() => { | |
| 32 'system': system.values.map((l) => l.toJsonMap()).toList(), | |
| 33 'packages': packages.values.map((p) => p.toJsonMap()).toList(), | |
| 34 'loose': | |
| 35 loose.values.map((l) => ['${l.runtimeType}', l.toJsonMap()]).toList(), | |
| 36 }; | |
| 37 | |
| 38 void accept(SummaryVisitor visitor) => visitor.visitGlobal(this); | |
| 39 | |
| 40 static GlobalSummary parse(Map json) { | |
| 41 var res = new GlobalSummary(); | |
| 42 json['system'].map(LibrarySummary.parse).forEach((l) { | |
| 43 res.system[l.name] = l; | |
| 44 }); | |
| 45 json['packages'].map(PackageSummary.parse).forEach((p) { | |
| 46 res.packages[p.name] = p; | |
| 47 }); | |
| 48 json['loose'].forEach((e) { | |
| 49 var summary = e[0] == 'LibrarySummary' | |
| 50 ? LibrarySummary.parse(e[1]) | |
| 51 : HtmlSummary.parse(e[1]); | |
| 52 res.loose[summary.name] = summary; | |
| 53 }); | |
| 54 return res; | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 /// A summary of a package. | |
| 59 class PackageSummary implements Summary { | |
| 60 final String name; | |
| 61 final Map<String, LibrarySummary> libraries = <String, LibrarySummary>{}; | |
| 62 | |
| 63 PackageSummary(this.name); | |
| 64 | |
| 65 Map toJsonMap() => { | |
| 66 'package_name': name, | |
| 67 'libraries': libraries.values.map((l) => l.toJsonMap()).toList(), | |
| 68 }; | |
| 69 | |
| 70 void accept(SummaryVisitor visitor) => visitor.visitPackage(this); | |
| 71 | |
| 72 static PackageSummary parse(Map json) { | |
| 73 var res = new PackageSummary(json['package_name']); | |
| 74 json['libraries'].map(LibrarySummary.parse).forEach((l) { | |
| 75 res.libraries[l.name] = l; | |
| 76 }); | |
| 77 return res; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 /// A summary for a library or an html file. | |
| 82 abstract class IndividualSummary extends Summary { | |
| 83 /// Unique name for this library. | |
| 84 String get name; | |
| 85 | |
| 86 List<MessageSummary> get messages; | |
| 87 } | |
| 88 | |
| 89 /// A summary at the level of a library. | |
| 90 class LibrarySummary implements IndividualSummary { | |
| 91 /// Unique name for this library. | |
| 92 final String name; | |
| 93 | |
| 94 /// All messages collected for the library. | |
| 95 final List<MessageSummary> messages; | |
| 96 | |
| 97 /// Total lines of code (including all parts of the library). | |
| 98 int lines; | |
| 99 | |
| 100 LibrarySummary(this.name, [List<MessageSummary> messages, this.lines = 0]) | |
| 101 : messages = messages == null ? <MessageSummary>[] : messages; | |
| 102 | |
| 103 Map toJsonMap() => { | |
| 104 'library_name': name, | |
| 105 'messages': messages.map((m) => m.toJsonMap()).toList(), | |
| 106 'lines': lines, | |
| 107 }; | |
| 108 | |
| 109 void accept(SummaryVisitor visitor) => visitor.visitLibrary(this); | |
| 110 | |
| 111 static LibrarySummary parse(Map json) => new LibrarySummary( | |
| 112 json['library_name'], json['messages'].map(MessageSummary.parse).toList(), | |
| 113 json['lines']); | |
| 114 } | |
| 115 | |
| 116 /// A summary at the level of an HTML file. | |
| 117 class HtmlSummary implements IndividualSummary { | |
| 118 /// Unique name used to identify the HTML file. | |
| 119 final String name; | |
| 120 | |
| 121 /// All messages collected on the file. | |
| 122 final List<MessageSummary> messages; | |
| 123 | |
| 124 HtmlSummary(this.name, [List<MessageSummary> messages]) | |
| 125 : messages = messages == null ? <MessageSummary>[] : messages; | |
| 126 | |
| 127 Map toJsonMap() => | |
| 128 {'name': name, 'messages': messages.map((m) => m.toJsonMap()).toList()}; | |
| 129 | |
| 130 void accept(SummaryVisitor visitor) => visitor.visitHtml(this); | |
| 131 | |
| 132 static HtmlSummary parse(Map json) => new HtmlSummary( | |
| 133 json['name'], json['messages'].map(MessageSummary.parse).toList()); | |
| 134 } | |
| 135 | |
| 136 /// A single message produced by the checker. | |
| 137 class MessageSummary implements Summary { | |
| 138 /// The kind of message, currently the name of the StaticInfo type. | |
| 139 final String kind; | |
| 140 | |
| 141 /// Level (error, warning, etc). | |
| 142 final String level; | |
| 143 | |
| 144 /// Location where the error is reported. | |
| 145 final SourceSpan span; | |
| 146 final String message; | |
| 147 | |
| 148 MessageSummary(this.kind, this.level, this.span, this.message); | |
| 149 | |
| 150 Map toJsonMap() => { | |
| 151 'kind': kind, | |
| 152 'level': level, | |
| 153 'message': message, | |
| 154 'url': '${span.sourceUrl}', | |
| 155 'start': span.start.offset, | |
| 156 'end': span.end.offset, | |
| 157 'text': span.text, | |
| 158 }; | |
| 159 | |
| 160 void accept(SummaryVisitor visitor) => visitor.visitMessage(this); | |
| 161 | |
| 162 static MessageSummary parse(Map json) { | |
| 163 var start = new SourceLocation(json['start'], sourceUrl: json['url']); | |
| 164 var end = new SourceLocation(json['end'], sourceUrl: json['url']); | |
| 165 var span = new SourceSpanBase(start, end, json['text']); | |
| 166 return new MessageSummary( | |
| 167 json['kind'], json['level'], span, json['message']); | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 /// A visitor of the [Summary] hierarchy. | |
| 172 abstract class SummaryVisitor { | |
| 173 void visitGlobal(GlobalSummary global); | |
| 174 void visitPackage(PackageSummary package); | |
| 175 void visitLibrary(LibrarySummary lib); | |
| 176 void visitHtml(HtmlSummary html); | |
| 177 void visitMessage(MessageSummary message); | |
| 178 } | |
| 179 | |
| 180 /// A recursive [SummaryVisitor] that visits summaries on a top-down fashion. | |
| 181 class RecursiveSummaryVisitor implements SummaryVisitor { | |
| 182 void visitGlobal(GlobalSummary global) { | |
| 183 for (var lib in global.system.values) { | |
| 184 lib.accept(this); | |
| 185 } | |
| 186 for (var package in global.packages.values) { | |
| 187 package.accept(this); | |
| 188 } | |
| 189 for (var libOrHtml in global.loose.values) { | |
| 190 libOrHtml.accept(this); | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 void visitPackage(PackageSummary package) { | |
| 195 for (var lib in package.libraries.values) { | |
| 196 lib.accept(this); | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 void visitLibrary(LibrarySummary lib) { | |
| 201 for (var msg in lib.messages) { | |
| 202 msg.accept(this); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 void visitHtml(HtmlSummary html) { | |
| 207 for (var msg in html.messages) { | |
| 208 msg.accept(this); | |
| 209 } | |
| 210 } | |
| 211 void visitMessage(MessageSummary message) {} | |
| 212 } | |
| OLD | NEW |