| 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 /// Summary of error messages produced by a `SummaryReporter`. | 5 /// Summary of error messages produced by a `SummaryReporter`. |
| 6 library dev_compiler.src.summary; | 6 library dev_compiler.src.summary; |
| 7 | 7 |
| 8 import 'dart:collection' show HashSet; | 8 import 'dart:collection' show HashSet; |
| 9 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 9 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
| 10 import 'package:analyzer/src/generated/source.dart' show Source; | 10 import 'package:analyzer/src/generated/source.dart' show Source; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 /// Summary for libraries in packages. | 25 /// Summary for libraries in packages. |
| 26 final Map<String, PackageSummary> packages = <String, PackageSummary>{}; | 26 final Map<String, PackageSummary> packages = <String, PackageSummary>{}; |
| 27 | 27 |
| 28 /// Summary for loose files | 28 /// Summary for loose files |
| 29 // TODO(sigmund): consider inferring the package from the pubspec instead? | 29 // TODO(sigmund): consider inferring the package from the pubspec instead? |
| 30 final Map<String, IndividualSummary> loose = <String, IndividualSummary>{}; | 30 final Map<String, IndividualSummary> loose = <String, IndividualSummary>{}; |
| 31 | 31 |
| 32 GlobalSummary(); | 32 GlobalSummary(); |
| 33 | 33 |
| 34 Map toJsonMap() => { | 34 Map toJsonMap() => { |
| 35 'system': system.values.map((l) => l.toJsonMap()).toList(), | 35 'system': system.values.map((l) => l.toJsonMap()).toList(), |
| 36 'packages': packages.values.map((p) => p.toJsonMap()).toList(), | 36 'packages': packages.values.map((p) => p.toJsonMap()).toList(), |
| 37 'loose': | 37 'loose': loose.values |
| 38 loose.values.map((l) => ['${l.runtimeType}', l.toJsonMap()]).toList(), | 38 .map((l) => ['${l.runtimeType}', l.toJsonMap()]) |
| 39 }; | 39 .toList(), |
| 40 }; |
| 40 | 41 |
| 41 void accept(SummaryVisitor visitor) => visitor.visitGlobal(this); | 42 void accept(SummaryVisitor visitor) => visitor.visitGlobal(this); |
| 42 | 43 |
| 43 static GlobalSummary parse(Map json) { | 44 static GlobalSummary parse(Map json) { |
| 44 var res = new GlobalSummary(); | 45 var res = new GlobalSummary(); |
| 45 json['system'].map(LibrarySummary.parse).forEach((l) { | 46 json['system'].map(LibrarySummary.parse).forEach((l) { |
| 46 res.system[l.name] = l; | 47 res.system[l.name] = l; |
| 47 }); | 48 }); |
| 48 json['packages'].map(PackageSummary.parse).forEach((p) { | 49 json['packages'].map(PackageSummary.parse).forEach((p) { |
| 49 res.packages[p.name] = p; | 50 res.packages[p.name] = p; |
| 50 }); | 51 }); |
| 51 json['loose'].forEach((e) { | 52 json['loose'].forEach((e) { |
| 52 var summary = e[0] == 'LibrarySummary' | 53 var summary = e[0] == 'LibrarySummary' |
| 53 ? LibrarySummary.parse(e[1]) | 54 ? LibrarySummary.parse(e[1]) |
| 54 : HtmlSummary.parse(e[1]); | 55 : HtmlSummary.parse(e[1]); |
| 55 res.loose[summary.name] = summary; | 56 res.loose[summary.name] = summary; |
| 56 }); | 57 }); |
| 57 return res; | 58 return res; |
| 58 } | 59 } |
| 59 } | 60 } |
| 60 | 61 |
| 61 /// A summary of a package. | 62 /// A summary of a package. |
| 62 class PackageSummary implements Summary { | 63 class PackageSummary implements Summary { |
| 63 final String name; | 64 final String name; |
| 64 final Map<String, LibrarySummary> libraries = <String, LibrarySummary>{}; | 65 final Map<String, LibrarySummary> libraries = <String, LibrarySummary>{}; |
| 65 | 66 |
| 66 PackageSummary(this.name); | 67 PackageSummary(this.name); |
| 67 | 68 |
| 68 Map toJsonMap() => { | 69 Map toJsonMap() => { |
| 69 'package_name': name, | 70 'package_name': name, |
| 70 'libraries': libraries.values.map((l) => l.toJsonMap()).toList(), | 71 'libraries': libraries.values.map((l) => l.toJsonMap()).toList(), |
| 71 }; | 72 }; |
| 72 | 73 |
| 73 void accept(SummaryVisitor visitor) => visitor.visitPackage(this); | 74 void accept(SummaryVisitor visitor) => visitor.visitPackage(this); |
| 74 | 75 |
| 75 static PackageSummary parse(Map json) { | 76 static PackageSummary parse(Map json) { |
| 76 var res = new PackageSummary(json['package_name']); | 77 var res = new PackageSummary(json['package_name']); |
| 77 json['libraries'].map(LibrarySummary.parse).forEach((l) { | 78 json['libraries'].map(LibrarySummary.parse).forEach((l) { |
| 78 res.libraries[l.name] = l; | 79 res.libraries[l.name] = l; |
| 79 }); | 80 }); |
| 80 return res; | 81 return res; |
| 81 } | 82 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 109 void clear() { | 110 void clear() { |
| 110 _uris.clear(); | 111 _uris.clear(); |
| 111 _lines = 0; | 112 _lines = 0; |
| 112 messages.clear(); | 113 messages.clear(); |
| 113 } | 114 } |
| 114 | 115 |
| 115 /// Total lines of code (including all parts of the library). | 116 /// Total lines of code (including all parts of the library). |
| 116 int get lines => _lines; | 117 int get lines => _lines; |
| 117 | 118 |
| 118 Map toJsonMap() => { | 119 Map toJsonMap() => { |
| 119 'library_name': name, | 120 'library_name': name, |
| 120 'messages': messages.map((m) => m.toJsonMap()).toList(), | 121 'messages': messages.map((m) => m.toJsonMap()).toList(), |
| 121 'lines': lines, | 122 'lines': lines, |
| 122 }; | 123 }; |
| 123 | 124 |
| 124 void countSourceLines(AnalysisContext context, Source source) { | 125 void countSourceLines(AnalysisContext context, Source source) { |
| 125 if (_uris.add(source.uri)) { | 126 if (_uris.add(source.uri)) { |
| 126 // TODO(jmesserly): parsing is serious overkill for this. | 127 // TODO(jmesserly): parsing is serious overkill for this. |
| 127 // Should be cached, but still. | 128 // Should be cached, but still. |
| 128 // On the other hand, if we are going to parse, we could get a much better | 129 // On the other hand, if we are going to parse, we could get a much better |
| 129 // source lines of code estimate by excluding things like comments, | 130 // source lines of code estimate by excluding things like comments, |
| 130 // blank lines, and closing braces. | 131 // blank lines, and closing braces. |
| 131 var unit = context.parseCompilationUnit(source); | 132 var unit = context.parseCompilationUnit(source); |
| 132 _lines += unit.lineInfo.getLocation(unit.endToken.end).lineNumber; | 133 _lines += unit.lineInfo.getLocation(unit.endToken.end).lineNumber; |
| 133 } | 134 } |
| 134 } | 135 } |
| 135 | 136 |
| 136 void accept(SummaryVisitor visitor) => visitor.visitLibrary(this); | 137 void accept(SummaryVisitor visitor) => visitor.visitLibrary(this); |
| 137 | 138 |
| 138 static LibrarySummary parse(Map json) => new LibrarySummary( | 139 static LibrarySummary parse(Map json) => |
| 139 json['library_name'], | 140 new LibrarySummary(json['library_name'], |
| 140 messages: json['messages'].map(MessageSummary.parse).toList(), | 141 messages: json['messages'].map(MessageSummary.parse).toList(), |
| 141 lines: json['lines']); | 142 lines: json['lines']); |
| 142 } | 143 } |
| 143 | 144 |
| 144 /// A summary at the level of an HTML file. | 145 /// A summary at the level of an HTML file. |
| 145 class HtmlSummary implements IndividualSummary { | 146 class HtmlSummary implements IndividualSummary { |
| 146 /// Unique name used to identify the HTML file. | 147 /// Unique name used to identify the HTML file. |
| 147 final String name; | 148 final String name; |
| 148 | 149 |
| 149 /// All messages collected on the file. | 150 /// All messages collected on the file. |
| 150 final List<MessageSummary> messages; | 151 final List<MessageSummary> messages; |
| 151 | 152 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 169 /// Level (error, warning, etc). | 170 /// Level (error, warning, etc). |
| 170 final String level; | 171 final String level; |
| 171 | 172 |
| 172 /// Location where the error is reported. | 173 /// Location where the error is reported. |
| 173 final SourceSpan span; | 174 final SourceSpan span; |
| 174 final String message; | 175 final String message; |
| 175 | 176 |
| 176 MessageSummary(this.kind, this.level, this.span, this.message); | 177 MessageSummary(this.kind, this.level, this.span, this.message); |
| 177 | 178 |
| 178 Map toJsonMap() => { | 179 Map toJsonMap() => { |
| 179 'kind': kind, | 180 'kind': kind, |
| 180 'level': level, | 181 'level': level, |
| 181 'message': message, | 182 'message': message, |
| 182 'url': '${span.sourceUrl}', | 183 'url': '${span.sourceUrl}', |
| 183 'start': [span.start.offset, span.start.line, span.start.column], | 184 'start': [span.start.offset, span.start.line, span.start.column], |
| 184 'end': [span.end.offset, span.end.line, span.end.column], | 185 'end': [span.end.offset, span.end.line, span.end.column], |
| 185 'text': span.text, | 186 'text': span.text, |
| 186 'context': span is SourceSpanWithContext | 187 'context': span is SourceSpanWithContext |
| 187 ? (span as SourceSpanWithContext).context | 188 ? (span as SourceSpanWithContext).context |
| 188 : null, | 189 : null, |
| 189 }; | 190 }; |
| 190 | 191 |
| 191 void accept(SummaryVisitor visitor) => visitor.visitMessage(this); | 192 void accept(SummaryVisitor visitor) => visitor.visitMessage(this); |
| 192 | 193 |
| 193 static MessageSummary parse(Map json) { | 194 static MessageSummary parse(Map json) { |
| 194 var start = new SourceLocation(json['start'][0], | 195 var start = new SourceLocation(json['start'][0], |
| 195 sourceUrl: json['url'], | 196 sourceUrl: json['url'], |
| 196 line: json['start'][1], | 197 line: json['start'][1], |
| 197 column: json['start'][2]); | 198 column: json['start'][2]); |
| 198 var end = new SourceLocation(json['end'][0], | 199 var end = new SourceLocation(json['end'][0], |
| 199 sourceUrl: json['url'], line: json['end'][1], column: json['end'][2]); | 200 sourceUrl: json['url'], line: json['end'][1], column: json['end'][2]); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 for (var msg in lib.messages) { | 240 for (var msg in lib.messages) { |
| 240 msg.accept(this); | 241 msg.accept(this); |
| 241 } | 242 } |
| 242 } | 243 } |
| 243 | 244 |
| 244 void visitHtml(HtmlSummary html) { | 245 void visitHtml(HtmlSummary html) { |
| 245 for (var msg in html.messages) { | 246 for (var msg in html.messages) { |
| 246 msg.accept(this); | 247 msg.accept(this); |
| 247 } | 248 } |
| 248 } | 249 } |
| 250 |
| 249 void visitMessage(MessageSummary message) {} | 251 void visitMessage(MessageSummary message) {} |
| 250 } | 252 } |
| OLD | NEW |