| 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 /// Summarizes the information produced by the checker. | 5 /// Summarizes the information produced by the checker. |
| 6 library dev_compiler.src.report; | 6 library dev_compiler.src.report; |
| 7 | 7 |
| 8 import 'dart:math' show max; | 8 import 'dart:math' show max; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/ast.dart' show AstNode, CompilationUnit; | 10 import 'package:analyzer/src/generated/ast.dart' show AstNode, CompilationUnit; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 final int begin; | 35 final int begin; |
| 36 | 36 |
| 37 /// Offset where the error message ends in the tracked source file. | 37 /// Offset where the error message ends in the tracked source file. |
| 38 final int end; | 38 final int end; |
| 39 | 39 |
| 40 const Message(this.message, this.level, this.begin, this.end); | 40 const Message(this.message, this.level, this.begin, this.end); |
| 41 } | 41 } |
| 42 | 42 |
| 43 // Interface used to report error messages from the checker. | 43 // Interface used to report error messages from the checker. |
| 44 abstract class CheckerReporter { | 44 abstract class CheckerReporter { |
| 45 void log(Message message); |
| 46 } |
| 47 |
| 48 // Interface used to report error messages from the compiler. |
| 49 abstract class CompilerReporter extends CheckerReporter { |
| 45 final AnalysisContext _context; | 50 final AnalysisContext _context; |
| 46 CompilationUnit _unit; | 51 CompilationUnit _unit; |
| 47 Source _unitSource; | 52 Source _unitSource; |
| 48 | 53 |
| 49 CheckerReporter(this._context); | 54 CompilerReporter(this._context); |
| 50 | 55 |
| 51 /// Called when starting to process a library. | 56 /// Called when starting to process a library. |
| 52 void enterLibrary(Uri uri); | 57 void enterLibrary(Uri uri); |
| 53 void leaveLibrary(); | 58 void leaveLibrary(); |
| 54 | 59 |
| 55 /// Called when starting to process an HTML source file. | 60 /// Called when starting to process an HTML source file. |
| 56 void enterHtml(Uri uri); | 61 void enterHtml(Uri uri); |
| 57 void leaveHtml(); | 62 void leaveHtml(); |
| 58 | 63 |
| 59 /// Called when starting to process a source. All subsequent log entries must | 64 /// Called when starting to process a source. All subsequent log entries must |
| 60 /// belong to this source until the next call to enterSource. | 65 /// belong to this source until the next call to enterSource. |
| 61 void enterCompilationUnit(CompilationUnit unit, [Source source]) { | 66 void enterCompilationUnit(CompilationUnit unit, [Source source]) { |
| 62 _unit = unit; | 67 _unit = unit; |
| 63 _unitSource = source; | 68 _unitSource = source; |
| 64 } | 69 } |
| 65 void leaveCompilationUnit() { | 70 void leaveCompilationUnit() { |
| 66 _unit = null; | 71 _unit = null; |
| 67 _unitSource = null; | 72 _unitSource = null; |
| 68 } | 73 } |
| 69 | 74 |
| 70 void log(Message message); | |
| 71 | |
| 72 // Called in server-mode. | 75 // Called in server-mode. |
| 73 void clearLibrary(Uri uri); | 76 void clearLibrary(Uri uri); |
| 74 void clearHtml(Uri uri); | 77 void clearHtml(Uri uri); |
| 75 void clearAll(); | 78 void clearAll(); |
| 76 | 79 |
| 77 SourceSpanWithContext _createSpan(int start, int end) => | 80 SourceSpanWithContext _createSpan(int start, int end) => |
| 78 createSpan(_context, _unit, start, end, _unitSource); | 81 createSpan(_context, _unit, start, end, _unitSource); |
| 79 } | 82 } |
| 80 | 83 |
| 81 final _checkerLogger = new Logger('dev_compiler.checker'); | 84 final _checkerLogger = new Logger('dev_compiler.checker'); |
| 82 | 85 |
| 83 /// Simple reporter that logs checker messages as they are seen. | 86 /// Simple reporter that logs checker messages as they are seen. |
| 84 class LogReporter extends CheckerReporter { | 87 class LogReporter extends CompilerReporter { |
| 85 final bool useColors; | 88 final bool useColors; |
| 86 Source _current; | 89 Source _current; |
| 87 | 90 |
| 88 LogReporter(AnalysisContext context, {this.useColors: false}) | 91 LogReporter(AnalysisContext context, {this.useColors: false}) |
| 89 : super(context); | 92 : super(context); |
| 90 | 93 |
| 91 void enterLibrary(Uri uri) {} | 94 void enterLibrary(Uri uri) {} |
| 92 void leaveLibrary() {} | 95 void leaveLibrary() {} |
| 93 | 96 |
| 94 void enterHtml(Uri uri) {} | 97 void enterHtml(Uri uri) {} |
| (...skipping 10 matching lines...) Expand all Loading... |
| 105 final text = '[${message.runtimeType}] ${message.message}'; | 108 final text = '[${message.runtimeType}] ${message.message}'; |
| 106 _checkerLogger.log(level, span.message(text, color: color)); | 109 _checkerLogger.log(level, span.message(text, color: color)); |
| 107 } | 110 } |
| 108 | 111 |
| 109 void clearLibrary(Uri uri) {} | 112 void clearLibrary(Uri uri) {} |
| 110 void clearHtml(Uri uri) {} | 113 void clearHtml(Uri uri) {} |
| 111 void clearAll() {} | 114 void clearAll() {} |
| 112 } | 115 } |
| 113 | 116 |
| 114 /// A reporter that gathers all the information in a [GlobalSummary]. | 117 /// A reporter that gathers all the information in a [GlobalSummary]. |
| 115 class SummaryReporter extends CheckerReporter { | 118 class SummaryReporter extends CompilerReporter { |
| 116 GlobalSummary result = new GlobalSummary(); | 119 GlobalSummary result = new GlobalSummary(); |
| 117 IndividualSummary _current; | 120 IndividualSummary _current; |
| 118 final Level _level; | 121 final Level _level; |
| 119 | 122 |
| 120 SummaryReporter(AnalysisContext context, [this._level = Level.ALL]) | 123 SummaryReporter(AnalysisContext context, [this._level = Level.ALL]) |
| 121 : super(context); | 124 : super(context); |
| 122 | 125 |
| 123 void enterLibrary(Uri uri) { | 126 void enterLibrary(Uri uri) { |
| 124 var container; | 127 var container; |
| 125 if (uri.scheme == 'package') { | 128 if (uri.scheme == 'package') { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 185 |
| 183 /// Produces a string representation of the summary. | 186 /// Produces a string representation of the summary. |
| 184 String summaryToString(GlobalSummary summary) { | 187 String summaryToString(GlobalSummary summary) { |
| 185 var counter = new _Counter(); | 188 var counter = new _Counter(); |
| 186 summary.accept(counter); | 189 summary.accept(counter); |
| 187 | 190 |
| 188 var table = new _Table(); | 191 var table = new _Table(); |
| 189 // Declare columns and add header | 192 // Declare columns and add header |
| 190 table.declareColumn('package'); | 193 table.declareColumn('package'); |
| 191 table.declareColumn('AnalyzerError', abbreviate: true); | 194 table.declareColumn('AnalyzerError', abbreviate: true); |
| 192 var activeInfoTypes = | 195 |
| 193 infoTypes.where((type) => counter.totals['$type'] != null); | 196 var activeInfoTypes = counter.totals.keys; |
| 194 activeInfoTypes | 197 activeInfoTypes.forEach((t) => table.declareColumn(t, abbreviate: true)); |
| 195 .forEach((type) => table.declareColumn('$type', abbreviate: true)); | |
| 196 table.declareColumn('LinesOfCode', abbreviate: true); | 198 table.declareColumn('LinesOfCode', abbreviate: true); |
| 197 table.addHeader(); | 199 table.addHeader(); |
| 198 | 200 |
| 199 // Add entries for each package | 201 // Add entries for each package |
| 200 appendCount(count) => table.addEntry(count == null ? 0 : count); | 202 appendCount(count) => table.addEntry(count == null ? 0 : count); |
| 201 for (var package in counter.errorCount.keys) { | 203 for (var package in counter.errorCount.keys) { |
| 202 appendCount(package); | 204 appendCount(package); |
| 203 appendCount(counter.errorCount[package]['AnalyzerError']); | 205 appendCount(counter.errorCount[package]['AnalyzerError']); |
| 204 activeInfoTypes | 206 activeInfoTypes.forEach((t) => appendCount(counter.errorCount[package][t])); |
| 205 .forEach((e) => appendCount(counter.errorCount[package]['$e'])); | |
| 206 appendCount(counter.linesOfCode[package]); | 207 appendCount(counter.linesOfCode[package]); |
| 207 } | 208 } |
| 208 | 209 |
| 209 // Add totals, percents and a new header for quick reference | 210 // Add totals, percents and a new header for quick reference |
| 210 table.addEmptyRow(); | 211 table.addEmptyRow(); |
| 211 table.addHeader(); | 212 table.addHeader(); |
| 212 table.addEntry('total'); | 213 table.addEntry('total'); |
| 213 appendCount(counter.totals['AnalyzerError']); | 214 appendCount(counter.totals['AnalyzerError']); |
| 214 activeInfoTypes.forEach((type) => appendCount(counter.totals['$type'])); | 215 activeInfoTypes.forEach((t) => appendCount(counter.totals[t])); |
| 215 appendCount(counter.totalLinesOfCode); | 216 appendCount(counter.totalLinesOfCode); |
| 216 | 217 |
| 217 appendPercent(count, total) { | 218 appendPercent(count, total) { |
| 218 if (count == null) count = 0; | 219 if (count == null) count = 0; |
| 219 var value = (count * 100 / total).toStringAsFixed(2); | 220 var value = (count * 100 / total).toStringAsFixed(2); |
| 220 table.addEntry(value); | 221 table.addEntry(value); |
| 221 } | 222 } |
| 222 | 223 |
| 223 var totalLOC = counter.totalLinesOfCode; | 224 var totalLOC = counter.totalLinesOfCode; |
| 224 table.addEntry('%'); | 225 table.addEntry('%'); |
| 225 appendPercent(counter.totals['AnalyzerError'], totalLOC); | 226 appendPercent(counter.totals['AnalyzerError'], totalLOC); |
| 226 activeInfoTypes | 227 activeInfoTypes.forEach((t) => appendPercent(counter.totals[t], totalLOC)); |
| 227 .forEach((type) => appendPercent(counter.totals['$type'], totalLOC)); | |
| 228 appendCount(100); | 228 appendCount(100); |
| 229 | 229 |
| 230 return table.toString(); | 230 return table.toString(); |
| 231 } | 231 } |
| 232 | 232 |
| 233 /// Helper class to combine all the information in table form. | 233 /// Helper class to combine all the information in table form. |
| 234 class _Table { | 234 class _Table { |
| 235 int _totalColumns = 0; | 235 int _totalColumns = 0; |
| 236 int get totalColumns => _totalColumns; | 236 int get totalColumns => _totalColumns; |
| 237 | 237 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 | 372 |
| 373 visitMessage(MessageSummary message) { | 373 visitMessage(MessageSummary message) { |
| 374 var kind = message.kind; | 374 var kind = message.kind; |
| 375 errorCount.putIfAbsent(currentPackage, () => <String, int>{}); | 375 errorCount.putIfAbsent(currentPackage, () => <String, int>{}); |
| 376 errorCount[currentPackage].putIfAbsent(kind, () => 0); | 376 errorCount[currentPackage].putIfAbsent(kind, () => 0); |
| 377 errorCount[currentPackage][kind]++; | 377 errorCount[currentPackage][kind]++; |
| 378 totals.putIfAbsent(kind, () => 0); | 378 totals.putIfAbsent(kind, () => 0); |
| 379 totals[kind]++; | 379 totals[kind]++; |
| 380 } | 380 } |
| 381 } | 381 } |
| OLD | NEW |