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/options.dart'; | 10 import 'package:path/path.dart' as path; |
| 11 |
| 12 import 'options.dart'; |
11 | 13 |
12 /// Returns the given error's severity. | 14 /// Returns the given error's severity. |
13 ProcessedSeverity _identity(AnalysisError error) => | 15 ProcessedSeverity _identity(AnalysisError error) => |
14 new ProcessedSeverity(error.errorCode.errorSeverity); | 16 new ProcessedSeverity(error.errorCode.errorSeverity); |
15 | 17 |
16 String _pluralize(String word, int count) => count == 1 ? word : word + "s"; | 18 String _pluralize(String word, int count) => count == 1 ? word : word + "s"; |
17 | 19 |
18 /// 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 |
19 /// suppressed). | 21 /// suppressed). |
20 typedef ProcessedSeverity _SeverityProcessor(AnalysisError error); | 22 typedef ProcessedSeverity _SeverityProcessor(AnalysisError error); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 out.write(" and "); | 91 out.write(" and "); |
90 } | 92 } |
91 out.write(lintCount); | 93 out.write(lintCount); |
92 out.write(' '); | 94 out.write(' '); |
93 out.write(_pluralize("lint", lintCount)); | 95 out.write(_pluralize("lint", lintCount)); |
94 hasContent = true; | 96 hasContent = true; |
95 } | 97 } |
96 if (hasContent) { | 98 if (hasContent) { |
97 out.writeln(" found."); | 99 out.writeln(" found."); |
98 } else { | 100 } else { |
99 out.writeln("No issues found"); | 101 out.writeln("No issues found!"); |
100 } | 102 } |
101 } | 103 } |
102 } | 104 } |
103 | 105 |
104 /// Helper for formatting [AnalysisError]s. | 106 /// Helper for formatting [AnalysisError]s. |
105 /// The two format options are a user consumable format and a machine consumable | 107 /// The two format options are a user consumable format and a machine consumable |
106 /// format. | 108 /// format. |
107 class ErrorFormatter { | 109 class ErrorFormatter { |
108 static final int _pipeCodeUnit = '|'.codeUnitAt(0); | 110 static final int _pipeCodeUnit = '|'.codeUnitAt(0); |
109 static final int _slashCodeUnit = '\\'.codeUnitAt(0); | 111 static final int _slashCodeUnit = '\\'.codeUnitAt(0); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 out.write('|'); | 147 out.write('|'); |
146 out.write(escapePipe(source.fullName)); | 148 out.write(escapePipe(source.fullName)); |
147 out.write('|'); | 149 out.write('|'); |
148 out.write(location.lineNumber); | 150 out.write(location.lineNumber); |
149 out.write('|'); | 151 out.write('|'); |
150 out.write(location.columnNumber); | 152 out.write(location.columnNumber); |
151 out.write('|'); | 153 out.write('|'); |
152 out.write(length); | 154 out.write(length); |
153 out.write('|'); | 155 out.write('|'); |
154 out.write(escapePipe(error.message)); | 156 out.write(escapePipe(error.message)); |
| 157 out.writeln(); |
155 } else { | 158 } else { |
156 // Get display name. | 159 // Get display name. |
157 String errorType = severity.displayName; | 160 String errorType = severity.displayName; |
158 | 161 |
159 // Translate INFOs into LINTS and HINTS. | 162 // Translate INFOs into LINTS and HINTS. |
160 if (severity == ErrorSeverity.INFO) { | 163 if (severity == ErrorSeverity.INFO) { |
161 if (error.errorCode.type == ErrorType.HINT || | 164 if (error.errorCode.type == ErrorType.HINT || |
162 error.errorCode.type == ErrorType.LINT) { | 165 error.errorCode.type == ErrorType.LINT) { |
163 errorType = error.errorCode.type.displayName; | 166 errorType = error.errorCode.type.displayName; |
164 } | 167 } |
165 } | 168 } |
166 | 169 |
167 // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2) | 170 int indent = errorType.length + 3; |
168 out.write('[$errorType] ${error.message} '); | 171 |
169 out.write('(${source.fullName}'); | 172 // [warning] 'foo' is not a bar at lib/foo.dart:1:2 (foo_warning). |
170 out.write(', line ${location.lineNumber}, col ${location.columnNumber})'); | 173 String message = error.message; |
| 174 // Remove any terminating '.' from the end of the message. |
| 175 if (message.endsWith('.')) { |
| 176 message = message.substring(0, message.length - 1); |
| 177 } |
| 178 out.write('[$errorType] $message '); |
| 179 String sourceName; |
| 180 if (source.uriKind == UriKind.DART_URI) { |
| 181 sourceName = source.uri.toString(); |
| 182 } else if (source.uriKind == UriKind.PACKAGE_URI) { |
| 183 sourceName = _relative(source.fullName); |
| 184 if (sourceName == source.fullName) { |
| 185 // If we weren't able to shorten the path name, use the package: versi
on. |
| 186 sourceName = source.uri.toString(); |
| 187 } |
| 188 } else { |
| 189 sourceName = _relative(source.fullName); |
| 190 } |
| 191 out.write('at $sourceName'); |
| 192 out.write(':${location.lineNumber}:${location.columnNumber} '); |
| 193 out.write('(${error.errorCode.name.toLowerCase()}).'); |
| 194 out.writeln(); |
| 195 |
| 196 // If verbose, also print any associated correction. |
| 197 if (options.verbose && error.correction != null) { |
| 198 out.writeln('${' '.padLeft(indent)}${error.correction}'); |
| 199 } |
171 } | 200 } |
172 out.writeln(); | |
173 } | 201 } |
174 | 202 |
175 void formatErrors(List<AnalysisErrorInfo> errorInfos) { | 203 void formatErrors(List<AnalysisErrorInfo> errorInfos) { |
176 stats.unfilteredCount += errorInfos.length; | 204 stats.unfilteredCount += errorInfos.length; |
177 | 205 |
178 var errors = new List<AnalysisError>(); | 206 var errors = new List<AnalysisError>(); |
179 var errorToLine = new Map<AnalysisError, LineInfo>(); | 207 var errorToLine = new Map<AnalysisError, LineInfo>(); |
180 for (AnalysisErrorInfo errorInfo in errorInfos) { | 208 for (AnalysisErrorInfo errorInfo in errorInfos) { |
181 for (AnalysisError error in errorInfo.errors) { | 209 for (AnalysisError error in errorInfo.errors) { |
182 if (computeSeverity(error) != null) { | 210 if (computeSeverity(error) != null) { |
(...skipping 20 matching lines...) Expand all Loading... |
203 // Offset. | 231 // Offset. |
204 return error1.offset - error2.offset; | 232 return error1.offset - error2.offset; |
205 }); | 233 }); |
206 // Format errors. | 234 // Format errors. |
207 for (AnalysisError error in errors) { | 235 for (AnalysisError error in errors) { |
208 ProcessedSeverity processedSeverity = processSeverity(error); | 236 ProcessedSeverity processedSeverity = processSeverity(error); |
209 ErrorSeverity severity = processedSeverity.severity; | 237 ErrorSeverity severity = processedSeverity.severity; |
210 if (severity == ErrorSeverity.ERROR) { | 238 if (severity == ErrorSeverity.ERROR) { |
211 stats.errorCount++; | 239 stats.errorCount++; |
212 } else if (severity == ErrorSeverity.WARNING) { | 240 } else if (severity == ErrorSeverity.WARNING) { |
213 /// Only treat a warning as an error if it's not been set by a | 241 // Only treat a warning as an error if it's not been set by a processor. |
214 /// proccesser. | |
215 if (!processedSeverity.overridden && options.warningsAreFatal) { | 242 if (!processedSeverity.overridden && options.warningsAreFatal) { |
216 stats.errorCount++; | 243 stats.errorCount++; |
217 } else { | 244 } else { |
218 stats.warnCount++; | 245 stats.warnCount++; |
219 } | 246 } |
220 } else if (error.errorCode.type == ErrorType.HINT) { | 247 } else if (error.errorCode.type == ErrorType.HINT) { |
221 stats.hintCount++; | 248 stats.hintCount++; |
222 } else if (error.errorCode.type == ErrorType.LINT) { | 249 } else if (error.errorCode.type == ErrorType.LINT) { |
223 stats.lintCount++; | 250 stats.lintCount++; |
224 } | 251 } |
(...skipping 12 matching lines...) Expand all Loading... |
237 return result.toString(); | 264 return result.toString(); |
238 } | 265 } |
239 } | 266 } |
240 | 267 |
241 /// A severity with awareness of whether it was overridden by a processor. | 268 /// A severity with awareness of whether it was overridden by a processor. |
242 class ProcessedSeverity { | 269 class ProcessedSeverity { |
243 ErrorSeverity severity; | 270 ErrorSeverity severity; |
244 bool overridden; | 271 bool overridden; |
245 ProcessedSeverity(this.severity, [this.overridden = false]); | 272 ProcessedSeverity(this.severity, [this.overridden = false]); |
246 } | 273 } |
| 274 |
| 275 /// Given an absolute path, return a relative path if the file is contained in |
| 276 /// the current directory; return the original path otherwise. |
| 277 String _relative(String file) { |
| 278 return file.startsWith(path.current) ? path.relative(file) : file; |
| 279 } |
OLD | NEW |