| 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 |