OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 library error_formatter; | |
6 | |
7 import 'generated/engine.dart'; | |
8 import 'generated/error.dart'; | |
9 import 'generated/source_io.dart'; | |
10 import '../options.dart'; | |
11 | |
12 /** | |
13 * Helper for formatting [AnalysisError]s. | |
14 * The two format options are a user consumable format and a machine consumable
format. | |
15 */ | |
16 class ErrorFormatter { | |
17 StringSink out; | |
18 CommandLineOptions options; | |
19 | |
20 ErrorFormatter(this.out, this.options); | |
21 | |
22 void formatErrors(List<AnalysisErrorInfo> errorInfos) { | |
23 var errors = new List<AnalysisError>(); | |
24 var errorToLine = new Map<AnalysisError, LineInfo>(); | |
25 for (AnalysisErrorInfo errorInfo in errorInfos) { | |
26 for (AnalysisError error in errorInfo.errors) { | |
27 errors.add(error); | |
28 errorToLine[error] = errorInfo.lineInfo; | |
29 } | |
30 } | |
31 // sort errors | |
32 errors.sort((AnalysisError error1, AnalysisError error2) { | |
33 // severity | |
34 int compare = error2.errorCode.errorSeverity.compareTo(error1.errorCode.er
rorSeverity); | |
35 if (compare != 0) { | |
36 return compare; | |
37 } | |
38 // path | |
39 compare = Comparable.compare(error1.source.fullName.toLowerCase(), error2.
source.fullName.toLowerCase()); | |
40 if (compare != 0) { | |
41 return compare; | |
42 } | |
43 // offset | |
44 return error1.offset - error2.offset; | |
45 }); | |
46 // format errors | |
47 int errorCount = 0; | |
48 int warnCount = 0; | |
49 int hintCount = 0; | |
50 for (AnalysisError error in errors) { | |
51 var severity = error.errorCode.errorSeverity; | |
52 if (severity == ErrorSeverity.ERROR) { | |
53 errorCount++; | |
54 } else if (severity == ErrorSeverity.WARNING) { | |
55 if (options.warningsAreFatal) { | |
56 errorCount++; | |
57 } else { | |
58 if (error.errorCode.type == ErrorType.HINT) { | |
59 hintCount++; | |
60 } else { | |
61 warnCount++; | |
62 } | |
63 } | |
64 } | |
65 formatError(errorToLine, error); | |
66 } | |
67 // print statistics | |
68 if (!options.machineFormat) { | |
69 var hasErrors = errorCount != 0; | |
70 var hasWarns = warnCount != 0; | |
71 var hasHints = hintCount != 0; | |
72 bool hasContent = false; | |
73 if (hasErrors) { | |
74 out.write(errorCount); | |
75 out.write(' '); | |
76 out.write(pluralize("error", errorCount)); | |
77 hasContent = true; | |
78 } | |
79 if (hasWarns) { | |
80 if (hasContent) { | |
81 if (!hasHints) { | |
82 out.write(' and '); | |
83 } else { | |
84 out.write(", "); | |
85 } | |
86 } | |
87 out.write(warnCount); | |
88 out.write(' '); | |
89 out.write(pluralize("warning", warnCount)); | |
90 hasContent = true; | |
91 } | |
92 if (hasHints) { | |
93 if (hasContent) { | |
94 out.write(" and "); | |
95 } | |
96 out.write(hintCount); | |
97 out.write(' '); | |
98 out.write(pluralize("hint", hintCount)); | |
99 hasContent = true; | |
100 } | |
101 if (hasContent) { | |
102 out.writeln(" found."); | |
103 } else { | |
104 out.writeln("No issues found"); | |
105 } | |
106 } | |
107 } | |
108 | |
109 void formatError(Map<AnalysisError, LineInfo> errorToLine, AnalysisError error
) { | |
110 Source source = error.source; | |
111 LineInfo_Location location = errorToLine[error].getLocation(error.offset); | |
112 int length = error.length; | |
113 var severity = error.errorCode.errorSeverity; | |
114 if (options.machineFormat) { | |
115 if (severity == ErrorSeverity.WARNING && options.warningsAreFatal) { | |
116 severity = ErrorSeverity.ERROR; | |
117 } | |
118 out.write(severity); | |
119 out.write('|'); | |
120 out.write(error.errorCode.type); | |
121 out.write('|'); | |
122 out.write(error.errorCode); | |
123 out.write('|'); | |
124 out.write(escapePipe(source.fullName)); | |
125 out.write('|'); | |
126 out.write(location.lineNumber); | |
127 out.write('|'); | |
128 out.write(location.columnNumber); | |
129 out.write('|'); | |
130 out.write(length); | |
131 out.write('|'); | |
132 out.write(escapePipe(error.message)); | |
133 } else { | |
134 String errorType = error.errorCode.errorSeverity.displayName; | |
135 if (error.errorCode.type == ErrorType.HINT) { | |
136 errorType = error.errorCode.type.displayName; | |
137 } | |
138 // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2) | |
139 out.write('[$errorType] ${error.message} '); | |
140 out.write('(${source.fullName}'); | |
141 out.write(', line ${location.lineNumber}, col ${location.columnNumber})'); | |
142 } | |
143 out.writeln(); | |
144 } | |
145 | |
146 static String escapePipe(String input) { | |
147 var result = new StringBuffer(); | |
148 for (var c in input.codeUnits) { | |
149 if (c == '\\' || c == '|') { | |
150 result.write('\\'); | |
151 } | |
152 result.writeCharCode(c); | |
153 } | |
154 return result.toString(); | |
155 } | |
156 | |
157 static String pluralize(String word, int count) { | |
158 if (count == 1) { | |
159 return word; | |
160 } else { | |
161 return word + "s"; | |
162 } | |
163 } | |
164 } | |
OLD | NEW |