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 library analyzer_cli.src.error_formatter; | 5 library analyzer_cli.src.error_formatter; |
6 | 6 |
7 import 'package:analyzer/error/error.dart'; | 7 import 'package:analyzer/error/error.dart'; |
8 import 'package:analyzer/src/generated/engine.dart'; | 8 import 'package:analyzer/src/generated/engine.dart'; |
9 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
| 10 import 'package:analyzer_cli/src/ansi.dart'; |
10 import 'package:analyzer_cli/src/options.dart'; | 11 import 'package:analyzer_cli/src/options.dart'; |
11 import 'package:path/path.dart' as path; | 12 import 'package:path/path.dart' as path; |
12 | 13 |
13 /// Returns the given error's severity. | 14 /// Returns the given error's severity. |
14 ProcessedSeverity _identity(AnalysisError error) => | 15 ProcessedSeverity _identity(AnalysisError error) => |
15 new ProcessedSeverity(error.errorCode.errorSeverity); | 16 new ProcessedSeverity(error.errorCode.errorSeverity); |
16 | 17 |
17 String _pluralize(String word, int count) => count == 1 ? word : word + "s"; | 18 String _pluralize(String word, int count) => count == 1 ? word : word + "s"; |
18 | 19 |
19 /// Returns desired severity for the given [error] (or `null` if it's to be | 20 /// Returns desired severity for the given [error] (or `null` if it's to be |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 } | 97 } |
97 if (hasContent) { | 98 if (hasContent) { |
98 out.writeln(" found."); | 99 out.writeln(" found."); |
99 } else { | 100 } else { |
100 out.writeln("No issues found!"); | 101 out.writeln("No issues found!"); |
101 } | 102 } |
102 } | 103 } |
103 } | 104 } |
104 | 105 |
105 /// Helper for formatting [AnalysisError]s. | 106 /// Helper for formatting [AnalysisError]s. |
| 107 /// |
106 /// The two format options are a user consumable format and a machine consumable | 108 /// The two format options are a user consumable format and a machine consumable |
107 /// format. | 109 /// format. |
108 class ErrorFormatter { | 110 class ErrorFormatter { |
109 static final int _pipeCodeUnit = '|'.codeUnitAt(0); | 111 static final int _pipeCodeUnit = '|'.codeUnitAt(0); |
110 static final int _slashCodeUnit = '\\'.codeUnitAt(0); | 112 static final int _slashCodeUnit = '\\'.codeUnitAt(0); |
111 static final int _newline = '\n'.codeUnitAt(0); | 113 static final int _newline = '\n'.codeUnitAt(0); |
112 static final int _return = '\r'.codeUnitAt(0); | 114 static final int _return = '\r'.codeUnitAt(0); |
113 | 115 |
114 final StringSink out; | 116 final StringSink out; |
115 final CommandLineOptions options; | 117 final CommandLineOptions options; |
116 final AnalysisStats stats; | 118 final AnalysisStats stats; |
117 | 119 |
118 final _SeverityProcessor processSeverity; | 120 final _SeverityProcessor processSeverity; |
119 | 121 |
| 122 AnsiLogger ansi; |
| 123 |
120 ErrorFormatter(this.out, this.options, this.stats, | 124 ErrorFormatter(this.out, this.options, this.stats, |
121 [this.processSeverity = _identity]); | 125 [this.processSeverity = _identity]) { |
| 126 ansi = new AnsiLogger(this.options.color); |
| 127 } |
122 | 128 |
123 /// Compute the severity for this [error] or `null` if this error should be | 129 /// Compute the severity for this [error] or `null` if this error should be |
124 /// filtered. | 130 /// filtered. |
125 ErrorSeverity computeSeverity(AnalysisError error) => | 131 ErrorSeverity computeSeverity(AnalysisError error) => |
126 processSeverity(error)?.severity; | 132 processSeverity(error)?.severity; |
127 | 133 |
128 void formatError( | 134 void formatError( |
129 Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) { | 135 Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) { |
130 Source source = error.source; | 136 Source source = error.source; |
131 LineInfo_Location location = errorToLine[error].getLocation(error.offset); | 137 LineInfo_Location location = errorToLine[error].getLocation(error.offset); |
(...skipping 29 matching lines...) Expand all Loading... |
161 String errorType = severity.displayName; | 167 String errorType = severity.displayName; |
162 | 168 |
163 // Translate INFOs into LINTS and HINTS. | 169 // Translate INFOs into LINTS and HINTS. |
164 if (severity == ErrorSeverity.INFO) { | 170 if (severity == ErrorSeverity.INFO) { |
165 if (error.errorCode.type == ErrorType.HINT || | 171 if (error.errorCode.type == ErrorType.HINT || |
166 error.errorCode.type == ErrorType.LINT) { | 172 error.errorCode.type == ErrorType.LINT) { |
167 errorType = error.errorCode.type.displayName; | 173 errorType = error.errorCode.type.displayName; |
168 } | 174 } |
169 } | 175 } |
170 | 176 |
171 int indent = errorType.length + 3; | 177 final int errLength = ErrorSeverity.WARNING.displayName.length; |
| 178 final int indent = errLength + 5; |
172 | 179 |
173 // [warning] 'foo' is not a bar at lib/foo.dart:1:2 (foo_warning). | 180 // warning • 'foo' is not a bar at lib/foo.dart:1:2 • foo_warning |
174 String message = error.message; | 181 String message = error.message; |
175 // Remove any terminating '.' from the end of the message. | 182 // Remove any terminating '.' from the end of the message. |
176 if (message.endsWith('.')) { | 183 if (message.endsWith('.')) { |
177 message = message.substring(0, message.length - 1); | 184 message = message.substring(0, message.length - 1); |
178 } | 185 } |
179 out.write('[$errorType] $message '); | 186 String issueColor = |
| 187 (severity == ErrorSeverity.ERROR || severity == ErrorSeverity.WARNING) |
| 188 ? ansi.red |
| 189 : ''; |
| 190 out.write(' $issueColor${errorType.padLeft(errLength)}${ansi.none} ' |
| 191 '${ansi.bullet} ${ansi.bold}$message${ansi.none} '); |
180 String sourceName; | 192 String sourceName; |
181 if (source.uriKind == UriKind.DART_URI) { | 193 if (source.uriKind == UriKind.DART_URI) { |
182 sourceName = source.uri.toString(); | 194 sourceName = source.uri.toString(); |
183 } else if (source.uriKind == UriKind.PACKAGE_URI) { | 195 } else if (source.uriKind == UriKind.PACKAGE_URI) { |
184 sourceName = _relative(source.fullName); | 196 sourceName = _relative(source.fullName); |
185 if (sourceName == source.fullName) { | 197 if (sourceName == source.fullName) { |
186 // If we weren't able to shorten the path name, use the package: versi
on. | 198 // If we weren't able to shorten the path name, use the package: versi
on. |
187 sourceName = source.uri.toString(); | 199 sourceName = source.uri.toString(); |
188 } | 200 } |
189 } else { | 201 } else { |
190 sourceName = _relative(source.fullName); | 202 sourceName = _relative(source.fullName); |
191 } | 203 } |
192 out.write('at $sourceName'); | 204 out.write('at $sourceName'); |
193 out.write(':${location.lineNumber}:${location.columnNumber} '); | 205 out.write(':${location.lineNumber}:${location.columnNumber} '); |
194 out.write('(${error.errorCode.name.toLowerCase()}).'); | 206 out.write('${ansi.bullet} ${error.errorCode.name.toLowerCase()}'); |
195 out.writeln(); | 207 out.writeln(); |
196 | 208 |
197 // If verbose, also print any associated correction. | 209 // If verbose, also print any associated correction. |
198 if (options.verbose && error.correction != null) { | 210 if (options.verbose && error.correction != null) { |
199 out.writeln('${' '.padLeft(indent)}${error.correction}'); | 211 out.writeln('${' '.padLeft(indent)}${error.correction}'); |
200 } | 212 } |
201 } | 213 } |
202 } | 214 } |
203 | 215 |
204 void formatErrors(List<AnalysisErrorInfo> errorInfos) { | 216 void formatErrors(List<AnalysisErrorInfo> errorInfos) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 ErrorSeverity severity; | 289 ErrorSeverity severity; |
278 bool overridden; | 290 bool overridden; |
279 ProcessedSeverity(this.severity, [this.overridden = false]); | 291 ProcessedSeverity(this.severity, [this.overridden = false]); |
280 } | 292 } |
281 | 293 |
282 /// Given an absolute path, return a relative path if the file is contained in | 294 /// Given an absolute path, return a relative path if the file is contained in |
283 /// the current directory; return the original path otherwise. | 295 /// the current directory; return the original path otherwise. |
284 String _relative(String file) { | 296 String _relative(String file) { |
285 return file.startsWith(path.current) ? path.relative(file) : file; | 297 return file.startsWith(path.current) ? path.relative(file) : file; |
286 } | 298 } |
OLD | NEW |