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/engine.dart' show AnalysisContext; | 10 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
11 import 'package:analyzer/src/generated/error.dart'; | 11 import 'package:analyzer/src/generated/error.dart'; |
12 import 'package:logging/logging.dart'; | 12 import 'package:logging/logging.dart'; |
13 import 'package:path/path.dart' as path; | 13 import 'package:path/path.dart' as path; |
14 import 'package:source_span/source_span.dart'; | 14 import 'package:source_span/source_span.dart'; |
15 | 15 |
16 import 'utils.dart'; | 16 import 'utils.dart'; |
17 import 'summary.dart'; | 17 import 'summary.dart'; |
18 | 18 |
19 final _checkerLogger = new Logger('dev_compiler.checker'); | 19 final _checkerLogger = new Logger('dev_compiler.checker'); |
20 | 20 |
21 SourceSpanWithContext _toSpan(AnalysisContext context, AnalysisError error) { | |
22 var source = error.source; | |
23 var lineInfo = context.computeLineInfo(source); | |
24 var content = context.getContents(source).data; | |
25 var start = error.offset; | |
26 var end = start + error.length; | |
27 return createSpanHelper(lineInfo, start, end, source, content); | |
28 } | |
29 /// Simple reporter that logs checker messages as they are seen. | 21 /// Simple reporter that logs checker messages as they are seen. |
30 class LogReporter implements AnalysisErrorListener { | 22 class LogReporter implements AnalysisErrorListener { |
31 final AnalysisContext _context; | 23 final AnalysisContext _context; |
32 final bool useColors; | 24 final bool useColors; |
33 | 25 |
34 LogReporter(this._context, {this.useColors: false}); | 26 LogReporter(this._context, {this.useColors: false}); |
35 | 27 |
36 void onError(AnalysisError error) { | 28 void onError(AnalysisError error) { |
37 var level = _severityToLevel[error.errorCode.errorSeverity]; | 29 var level = _severityToLevel[error.errorCode.errorSeverity]; |
38 | 30 |
39 // Upgrade analyzer warnings to errors. | 31 // Upgrade analyzer warnings to errors. |
40 // TODO(jmesserly: reconcile this... | 32 // TODO(jmesserly: reconcile this... |
41 if (!error.errorCode.name.startsWith('dev_compiler.') && | 33 if (!error.errorCode.name.startsWith('dev_compiler.') && |
42 level == Level.WARNING) { | 34 level == Level.WARNING) { |
43 level = Level.SEVERE; | 35 level = Level.SEVERE; |
44 } | 36 } |
45 | 37 |
46 var color = useColors ? colorOf(level.name) : null; | 38 // TODO(jmesserly): figure out what to do with the error's name. |
| 39 var lineInfo = _context.computeLineInfo(error.source); |
| 40 var location = lineInfo.getLocation(error.offset); |
47 | 41 |
48 // TODO(jmesserly): figure out what to do with the error's name. | 42 // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2) |
49 var text = '[${errorCodeName(error.errorCode)}] ' + error.message; | 43 var text = new StringBuffer() |
50 text = _toSpan(_context, error).message(text, color: color); | 44 ..write('[${errorCodeName(error.errorCode)}] ') |
| 45 ..write(error.message) |
| 46 ..write(' (${path.prettyUri(error.source.uri)}') |
| 47 ..write(', line ${location.lineNumber}, col ${location.columnNumber})'); |
51 | 48 |
52 // TODO(jmesserly): just print these instead of sending through logger? | 49 // TODO(jmesserly): just print these instead of sending through logger? |
53 _checkerLogger.log(level, text); | 50 _checkerLogger.log(level, text); |
54 } | 51 } |
55 } | 52 } |
56 | 53 |
57 // TODO(jmesserly): remove log levels, instead just use severity. | 54 // TODO(jmesserly): remove log levels, instead just use severity. |
58 const _severityToLevel = const { | 55 const _severityToLevel = const { |
59 ErrorSeverity.ERROR: Level.SEVERE, | 56 ErrorSeverity.ERROR: Level.SEVERE, |
60 ErrorSeverity.WARNING: Level.WARNING, | 57 ErrorSeverity.WARNING: Level.WARNING, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 | 91 |
95 var span = _toSpan(_context, error); | 92 var span = _toSpan(_context, error); |
96 var summary = _getIndividualSummary(error.source.uri); | 93 var summary = _getIndividualSummary(error.source.uri); |
97 if (summary is LibrarySummary) { | 94 if (summary is LibrarySummary) { |
98 summary.countSourceLines(_context, error.source); | 95 summary.countSourceLines(_context, error.source); |
99 } | 96 } |
100 summary.messages.add(new MessageSummary(errorCodeName(code), | 97 summary.messages.add(new MessageSummary(errorCodeName(code), |
101 code.errorSeverity.displayName, span, error.message)); | 98 code.errorSeverity.displayName, span, error.message)); |
102 } | 99 } |
103 | 100 |
| 101 // TODO(jmesserly): fix to not depend on SourceSpan. This will be really slow |
| 102 // because it will reload source text from disk, for every single message... |
| 103 SourceSpanWithContext _toSpan(AnalysisContext context, AnalysisError error) { |
| 104 var source = error.source; |
| 105 var lineInfo = context.computeLineInfo(source); |
| 106 var content = context.getContents(source).data; |
| 107 var start = error.offset; |
| 108 var end = start + error.length; |
| 109 return createSpanHelper(lineInfo, start, end, source, content); |
| 110 } |
| 111 |
104 void clearLibrary(Uri uri) { | 112 void clearLibrary(Uri uri) { |
105 (_getIndividualSummary(uri) as LibrarySummary).clear(); | 113 (_getIndividualSummary(uri) as LibrarySummary).clear(); |
106 } | 114 } |
107 | 115 |
108 void clearHtml(Uri uri) { | 116 void clearHtml(Uri uri) { |
109 HtmlSummary htmlSummary = result.loose['$uri']; | 117 HtmlSummary htmlSummary = result.loose['$uri']; |
110 if (htmlSummary != null) htmlSummary.messages.clear(); | 118 if (htmlSummary != null) htmlSummary.messages.clear(); |
111 } | 119 } |
112 } | 120 } |
113 | 121 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 | 308 |
301 visitMessage(MessageSummary message) { | 309 visitMessage(MessageSummary message) { |
302 var kind = message.kind; | 310 var kind = message.kind; |
303 errorCount.putIfAbsent(currentPackage, () => <String, int>{}); | 311 errorCount.putIfAbsent(currentPackage, () => <String, int>{}); |
304 errorCount[currentPackage].putIfAbsent(kind, () => 0); | 312 errorCount[currentPackage].putIfAbsent(kind, () => 0); |
305 errorCount[currentPackage][kind]++; | 313 errorCount[currentPackage][kind]++; |
306 totals.putIfAbsent(kind, () => 0); | 314 totals.putIfAbsent(kind, () => 0); |
307 totals[kind]++; | 315 totals[kind]++; |
308 } | 316 } |
309 } | 317 } |
OLD | NEW |