| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library error_formatter; |
| |
| import 'generated/engine.dart'; |
| import 'generated/error.dart'; |
| import 'generated/source_io.dart'; |
| import '../options.dart'; |
| |
| /** |
| * Helper for formatting [AnalysisError]s. |
| * The two format options are a user consumable format and a machine consumable format. |
| */ |
| class ErrorFormatter { |
| StringSink out; |
| CommandLineOptions options; |
| |
| ErrorFormatter(this.out, this.options); |
| |
| void formatErrors(List<AnalysisErrorInfo> errorInfos) { |
| var errors = new List<AnalysisError>(); |
| var errorToLine = new Map<AnalysisError, LineInfo>(); |
| for (AnalysisErrorInfo errorInfo in errorInfos) { |
| for (AnalysisError error in errorInfo.errors) { |
| errors.add(error); |
| errorToLine[error] = errorInfo.lineInfo; |
| } |
| } |
| // sort errors |
| errors.sort((AnalysisError error1, AnalysisError error2) { |
| // severity |
| int compare = error2.errorCode.errorSeverity.compareTo(error1.errorCode.errorSeverity); |
| if (compare != 0) { |
| return compare; |
| } |
| // path |
| compare = Comparable.compare(error1.source.fullName.toLowerCase(), error2.source.fullName.toLowerCase()); |
| if (compare != 0) { |
| return compare; |
| } |
| // offset |
| return error1.offset - error2.offset; |
| }); |
| // format errors |
| int errorCount = 0; |
| int warnCount = 0; |
| for (AnalysisError error in errors) { |
| if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) { |
| errorCount++; |
| } else if (error.errorCode.errorSeverity == ErrorSeverity.WARNING) { |
| if (options.warningsAreFatal) { |
| errorCount++; |
| } else { |
| warnCount++; |
| } |
| } |
| formatError(errorToLine, error); |
| } |
| // print statistics |
| if (!options.machineFormat) { |
| if (errorCount != 0 && warnCount != 0) { |
| out.write(errorCount); |
| out.write(' '); |
| out.write(pluralize("error", errorCount)); |
| out.write(' and '); |
| out.write(warnCount); |
| out.write(' '); |
| out.write(pluralize("warning", warnCount)); |
| out.writeln(' found.'); |
| } else if (errorCount != 0) { |
| out.write(errorCount); |
| out.write(' '); |
| out.write(pluralize("error", errorCount)); |
| out.writeln(' found.'); |
| } else if (warnCount != 0) { |
| out.write(warnCount); |
| out.write(' '); |
| out.write(pluralize("warning", warnCount)); |
| out.writeln(' found.'); |
| } else { |
| out.writeln("No issues found."); |
| } |
| } |
| } |
| |
| void formatError(Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) { |
| Source source = error.source; |
| LineInfo_Location location = errorToLine[error].getLocation(error.offset); |
| int length = error.length; |
| var severity = error.errorCode.errorSeverity; |
| if (options.machineFormat) { |
| if (severity == ErrorSeverity.WARNING && options.warningsAreFatal) { |
| severity = ErrorSeverity.ERROR; |
| } |
| out.write(severity); |
| out.write('|'); |
| out.write(error.errorCode.type); |
| out.write('|'); |
| out.write(error.errorCode); |
| out.write('|'); |
| out.write(escapePipe(source.fullName)); |
| out.write('|'); |
| out.write(location.lineNumber); |
| out.write('|'); |
| out.write(location.columnNumber); |
| out.write('|'); |
| out.write(length); |
| out.write('|'); |
| out.write(escapePipe(error.message)); |
| } else { |
| // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2) |
| out.write('[${severity.displayName}] ${error.message} '); |
| out.write('(${source.fullName}'); |
| out.write(', line ${location.lineNumber}, col ${location.columnNumber})'); |
| } |
| out.writeln(); |
| } |
| |
| static String escapePipe(String input) { |
| var result = new StringBuffer(); |
| for (var c in input.codeUnits) { |
| if (c == '\\' || c == '|') { |
| result.write('\\'); |
| } |
| result.writeCharCode(c); |
| } |
| return result.toString(); |
| } |
| |
| static String pluralize(String word, int count) { |
| if (count == 1) { |
| return word; |
| } else { |
| return word + "s"; |
| } |
| } |
| } |