Index: pkg/analyzer_cli/lib/src/error_formatter.dart
|
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
|
index e431778c1940b0cd2061dd2d361501e58a47a954..cb023c4131edf1ddc6060ca5ddededdc69510967 100644
|
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
|
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
|
@@ -11,12 +11,26 @@ import 'package:analyzer_cli/src/ansi.dart';
|
import 'package:analyzer_cli/src/options.dart';
|
import 'package:path/path.dart' as path;
|
|
+final Map<String, int> _severityCompare = {
|
+ 'error': 5,
|
+ 'warning': 4,
|
+ 'info': 3,
|
+ 'lint': 2,
|
+ 'hint': 1,
|
+};
|
+
|
+String _pluralize(String word, int count) => count == 1 ? word : word + "s";
|
+
|
+/// Given an absolute path, return a relative path if the file is contained in
|
+/// the current directory; return the original path otherwise.
|
+String _relative(String file) {
|
+ return file.startsWith(path.current) ? path.relative(file) : file;
|
+}
|
+
|
/// Returns the given error's severity.
|
ErrorSeverity _severityIdentity(AnalysisError error) =>
|
error.errorCode.errorSeverity;
|
|
-String _pluralize(String word, int count) => count == 1 ? word : word + "s";
|
-
|
/// Returns desired severity for the given [error] (or `null` if it's to be
|
/// suppressed).
|
typedef ErrorSeverity SeverityProcessor(AnalysisError error);
|
@@ -88,6 +102,64 @@ class AnalysisStats {
|
}
|
}
|
|
+/// An [AnalysisError] with line and column information.
|
+class CLIError implements Comparable<CLIError> {
|
+ final String severity;
|
+ final String sourcePath;
|
+ final int offset;
|
+ final int line;
|
+ final int column;
|
+ final String message;
|
+ final String errorCode;
|
+ final String correction;
|
+
|
+ CLIError({
|
+ this.severity,
|
+ this.sourcePath,
|
+ this.offset,
|
+ this.line,
|
+ this.column,
|
+ this.message,
|
+ this.errorCode,
|
+ this.correction,
|
+ });
|
+
|
+ @override
|
+ int get hashCode =>
|
+ severity.hashCode ^ sourcePath.hashCode ^ errorCode.hashCode ^ offset;
|
+ bool get isError => severity == 'error';
|
+ bool get isHint => severity == 'hint';
|
+ bool get isLint => severity == 'lint';
|
+
|
+ bool get isWarning => severity == 'warning';
|
+
|
+ @override
|
+ bool operator ==(other) {
|
+ if (other is! CLIError) return false;
|
+
|
+ return severity == other.severity &&
|
+ sourcePath == other.sourcePath &&
|
+ errorCode == other.errorCode &&
|
+ offset == other.offset;
|
+ }
|
+
|
+ @override
|
+ int compareTo(CLIError other) {
|
+ // severity
|
+ int compare =
|
+ _severityCompare[other.severity] - _severityCompare[this.severity];
|
+ if (compare != 0) return compare;
|
+
|
+ // path
|
+ compare = Comparable.compare(
|
+ this.sourcePath.toLowerCase(), other.sourcePath.toLowerCase());
|
+ if (compare != 0) return compare;
|
+
|
+ // offset
|
+ return this.offset - other.offset;
|
+ }
|
+}
|
+
|
/// Helper for formatting [AnalysisError]s.
|
///
|
/// The two format options are a user consumable format and a machine consumable
|
@@ -104,10 +176,11 @@ abstract class ErrorFormatter {
|
severityProcessor == null ? _severityIdentity : severityProcessor;
|
}
|
|
- /// Compute the severity for this [error] or `null` if this error should be
|
- /// filtered.
|
- ErrorSeverity _computeSeverity(AnalysisError error) =>
|
- _severityProcessor(error);
|
+ /// Call to write any batched up errors from [formatErrors].
|
+ void flush();
|
+
|
+ void formatError(
|
+ Map<AnalysisError, LineInfo> errorToLine, AnalysisError error);
|
|
void formatErrors(List<AnalysisErrorInfo> errorInfos) {
|
stats.unfilteredCount += errorInfos.length;
|
@@ -129,78 +202,10 @@ abstract class ErrorFormatter {
|
}
|
}
|
|
- void formatError(
|
- Map<AnalysisError, LineInfo> errorToLine, AnalysisError error);
|
-
|
- /// Call to write any batched up errors from [formatErrors].
|
- void flush();
|
-}
|
-
|
-class MachineErrorFormatter extends ErrorFormatter {
|
- static final int _pipeCodeUnit = '|'.codeUnitAt(0);
|
- static final int _slashCodeUnit = '\\'.codeUnitAt(0);
|
- static final int _newline = '\n'.codeUnitAt(0);
|
- static final int _return = '\r'.codeUnitAt(0);
|
-
|
- MachineErrorFormatter(
|
- StringSink out, CommandLineOptions options, AnalysisStats stats,
|
- {SeverityProcessor severityProcessor})
|
- : super(out, options, stats, severityProcessor: severityProcessor);
|
-
|
- void formatError(
|
- Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
|
- Source source = error.source;
|
- LineInfo_Location location = errorToLine[error].getLocation(error.offset);
|
- int length = error.length;
|
-
|
- ErrorSeverity severity = _severityProcessor(error);
|
-
|
- if (severity == ErrorSeverity.ERROR) {
|
- stats.errorCount++;
|
- } else if (severity == ErrorSeverity.WARNING) {
|
- stats.warnCount++;
|
- } else if (error.errorCode.type == ErrorType.HINT) {
|
- stats.hintCount++;
|
- } else if (error.errorCode.type == ErrorType.LINT) {
|
- stats.lintCount++;
|
- }
|
-
|
- out.write(severity);
|
- out.write('|');
|
- out.write(error.errorCode.type);
|
- out.write('|');
|
- out.write(error.errorCode.name);
|
- out.write('|');
|
- out.write(_escapeForMachineMode(source.fullName));
|
- out.write('|');
|
- out.write(location.lineNumber);
|
- out.write('|');
|
- out.write(location.columnNumber);
|
- out.write('|');
|
- out.write(length);
|
- out.write('|');
|
- out.write(_escapeForMachineMode(error.message));
|
- out.writeln();
|
- }
|
-
|
- static String _escapeForMachineMode(String input) {
|
- StringBuffer result = new StringBuffer();
|
- for (int c in input.codeUnits) {
|
- if (c == _newline) {
|
- result.write(r'\n');
|
- } else if (c == _return) {
|
- result.write(r'\r');
|
- } else {
|
- if (c == _slashCodeUnit || c == _pipeCodeUnit) {
|
- result.write('\\');
|
- }
|
- result.writeCharCode(c);
|
- }
|
- }
|
- return result.toString();
|
- }
|
-
|
- void flush() {}
|
+ /// Compute the severity for this [error] or `null` if this error should be
|
+ /// filtered.
|
+ ErrorSeverity _computeSeverity(AnalysisError error) =>
|
+ _severityProcessor(error);
|
}
|
|
class HumanErrorFormatter extends ErrorFormatter {
|
@@ -216,6 +221,45 @@ class HumanErrorFormatter extends ErrorFormatter {
|
ansi = new AnsiLogger(this.options.color);
|
}
|
|
+ void flush() {
|
+ // sort
|
+ List<CLIError> sortedErrors = batchedErrors.toList()..sort();
|
+
|
+ // print
|
+ for (CLIError error in sortedErrors) {
|
+ if (error.isError) {
|
+ stats.errorCount++;
|
+ } else if (error.isWarning) {
|
+ stats.warnCount++;
|
+ } else if (error.isLint) {
|
+ stats.lintCount++;
|
+ } else if (error.isHint) {
|
+ stats.hintCount++;
|
+ }
|
+
|
+ // warning • 'foo' is not a bar at lib/foo.dart:1:2 • foo_warning
|
+ String issueColor = (error.isError == ErrorSeverity.ERROR ||
|
+ error.isWarning == ErrorSeverity.WARNING)
|
+ ? ansi.red
|
+ : '';
|
+ out.write(' $issueColor${error.severity}${ansi.none} '
|
+ '${ansi.bullet} ${ansi.bold}${error.message}${ansi.none} ');
|
+ out.write('at ${error.sourcePath}');
|
+ out.write(':${error.line}:${error.column} ');
|
+ out.write('${ansi.bullet} ${error.errorCode}');
|
+ out.writeln();
|
+
|
+ // If verbose, also print any associated correction.
|
+ if (options.verbose && error.correction != null) {
|
+ out.writeln(
|
+ '${' '.padLeft(error.severity.length + 2)}${error.correction}');
|
+ }
|
+ }
|
+
|
+ // clear out batched errors
|
+ batchedErrors.clear();
|
+ }
|
+
|
void formatError(
|
Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
|
Source source = error.source;
|
@@ -262,115 +306,71 @@ class HumanErrorFormatter extends ErrorFormatter {
|
correction: error.correction,
|
));
|
}
|
-
|
- void flush() {
|
- // sort
|
- List<CLIError> sortedErrors = batchedErrors.toList()..sort();
|
-
|
- // print
|
- for (CLIError error in sortedErrors) {
|
- if (error.isError) {
|
- stats.errorCount++;
|
- } else if (error.isWarning) {
|
- stats.warnCount++;
|
- } else if (error.isLint) {
|
- stats.lintCount++;
|
- } else if (error.isHint) {
|
- stats.hintCount++;
|
- }
|
-
|
- // warning • 'foo' is not a bar at lib/foo.dart:1:2 • foo_warning
|
- String issueColor = (error.isError == ErrorSeverity.ERROR ||
|
- error.isWarning == ErrorSeverity.WARNING)
|
- ? ansi.red
|
- : '';
|
- out.write(' $issueColor${error.severity}${ansi.none} '
|
- '${ansi.bullet} ${ansi.bold}${error.message}${ansi.none} ');
|
- out.write('at ${error.sourcePath}');
|
- out.write(':${error.line}:${error.column} ');
|
- out.write('${ansi.bullet} ${error.errorCode}');
|
- out.writeln();
|
-
|
- // If verbose, also print any associated correction.
|
- if (options.verbose && error.correction != null) {
|
- out.writeln(
|
- '${' '.padLeft(error.severity.length + 2)}${error.correction}');
|
- }
|
- }
|
-
|
- // clear out batched errors
|
- batchedErrors.clear();
|
- }
|
}
|
|
-final Map<String, int> _severityCompare = {
|
- 'error': 5,
|
- 'warning': 4,
|
- 'info': 3,
|
- 'lint': 2,
|
- 'hint': 1,
|
-};
|
+class MachineErrorFormatter extends ErrorFormatter {
|
+ static final int _pipeCodeUnit = '|'.codeUnitAt(0);
|
+ static final int _slashCodeUnit = '\\'.codeUnitAt(0);
|
+ static final int _newline = '\n'.codeUnitAt(0);
|
+ static final int _return = '\r'.codeUnitAt(0);
|
|
-/// An [AnalysisError] with line and column information.
|
-class CLIError implements Comparable<CLIError> {
|
- final String severity;
|
- final String sourcePath;
|
- final int offset;
|
- final int line;
|
- final int column;
|
- final String message;
|
- final String errorCode;
|
- final String correction;
|
+ MachineErrorFormatter(
|
+ StringSink out, CommandLineOptions options, AnalysisStats stats,
|
+ {SeverityProcessor severityProcessor})
|
+ : super(out, options, stats, severityProcessor: severityProcessor);
|
|
- CLIError({
|
- this.severity,
|
- this.sourcePath,
|
- this.offset,
|
- this.line,
|
- this.column,
|
- this.message,
|
- this.errorCode,
|
- this.correction,
|
- });
|
+ void flush() {}
|
|
- bool get isError => severity == 'error';
|
- bool get isWarning => severity == 'warning';
|
- bool get isLint => severity == 'lint';
|
- bool get isHint => severity == 'hint';
|
+ void formatError(
|
+ Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
|
+ Source source = error.source;
|
+ LineInfo_Location location = errorToLine[error].getLocation(error.offset);
|
+ int length = error.length;
|
|
- @override
|
- int get hashCode =>
|
- severity.hashCode ^ sourcePath.hashCode ^ errorCode.hashCode ^ offset;
|
+ ErrorSeverity severity = _severityProcessor(error);
|
|
- @override
|
- bool operator ==(other) {
|
- if (other is! CLIError) return false;
|
+ if (severity == ErrorSeverity.ERROR) {
|
+ stats.errorCount++;
|
+ } else if (severity == ErrorSeverity.WARNING) {
|
+ stats.warnCount++;
|
+ } else if (error.errorCode.type == ErrorType.HINT) {
|
+ stats.hintCount++;
|
+ } else if (error.errorCode.type == ErrorType.LINT) {
|
+ stats.lintCount++;
|
+ }
|
|
- return severity == other.severity &&
|
- sourcePath == other.sourcePath &&
|
- errorCode == other.errorCode &&
|
- offset == other.offset;
|
+ out.write(severity);
|
+ out.write('|');
|
+ out.write(error.errorCode.type);
|
+ out.write('|');
|
+ out.write(error.errorCode.name);
|
+ out.write('|');
|
+ out.write(_escapeForMachineMode(source.fullName));
|
+ out.write('|');
|
+ out.write(location.lineNumber);
|
+ out.write('|');
|
+ out.write(location.columnNumber);
|
+ out.write('|');
|
+ out.write(length);
|
+ out.write('|');
|
+ out.write(_escapeForMachineMode(error.message));
|
+ out.writeln();
|
}
|
|
- @override
|
- int compareTo(CLIError other) {
|
- // severity
|
- int compare =
|
- _severityCompare[other.severity] - _severityCompare[this.severity];
|
- if (compare != 0) return compare;
|
-
|
- // path
|
- compare = Comparable.compare(
|
- this.sourcePath.toLowerCase(), other.sourcePath.toLowerCase());
|
- if (compare != 0) return compare;
|
-
|
- // offset
|
- return this.offset - other.offset;
|
+ static String _escapeForMachineMode(String input) {
|
+ StringBuffer result = new StringBuffer();
|
+ for (int c in input.codeUnits) {
|
+ if (c == _newline) {
|
+ result.write(r'\n');
|
+ } else if (c == _return) {
|
+ result.write(r'\r');
|
+ } else {
|
+ if (c == _slashCodeUnit || c == _pipeCodeUnit) {
|
+ result.write('\\');
|
+ }
|
+ result.writeCharCode(c);
|
+ }
|
+ }
|
+ return result.toString();
|
}
|
}
|
-
|
-/// Given an absolute path, return a relative path if the file is contained in
|
-/// the current directory; return the original path otherwise.
|
-String _relative(String file) {
|
- return file.startsWith(path.current) ? path.relative(file) : file;
|
-}
|
|