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 library error; | |
5 | |
6 import 'dart:collection'; | |
7 import 'dart:math' as math; | |
8 | |
9 import 'generated/error.dart'; | |
10 import 'generated/java_core.dart'; | |
11 import 'generated/source.dart'; | |
12 | |
13 /// The maximum line length when printing extracted source code when converting | |
14 /// an [AnalyzerError] to a string. | |
15 final _MAX_ERROR_LINE_LENGTH = 120; | |
16 | |
17 /// An error class that collects multiple [AnalyzerError]s that are emitted | |
18 /// during a single analysis. | |
19 class AnalyzerErrorGroup implements Exception { | |
20 /// The errors in this collection. | |
21 List<AnalyzerError> get errors => | |
22 new UnmodifiableListView<AnalyzerError>(_errors); | |
23 final List<AnalyzerError> _errors; | |
24 | |
25 AnalyzerErrorGroup(Iterable<AnalyzerError> errors) | |
26 : _errors = errors.toList(); | |
27 | |
28 /// Creates an [AnalyzerErrorGroup] from a list of lower-level | |
29 /// [AnalysisError]s. | |
30 AnalyzerErrorGroup.fromAnalysisErrors(Iterable<AnalysisError> errors) | |
31 : this(errors.map((e) => new AnalyzerError(e))); | |
32 | |
33 String get message => toString(); | |
34 String toString() => errors.join("\n"); | |
35 } | |
36 | |
37 /// A wrapper around [AnalysisError] that provides a more user-friendly string | |
38 /// representation. | |
39 class AnalyzerError implements Exception { | |
40 final AnalysisError error; | |
41 | |
42 AnalyzerError(this.error); | |
43 | |
44 String get message => toString(); | |
45 | |
46 String toString() { | |
47 var builder = new StringBuffer(); | |
48 var receiver = new _ContentReceiver(); | |
49 error.source.getContents(receiver); | |
50 var beforeError = receiver.result.substring(0, error.offset); | |
51 var lineNumber = "\n".allMatches(beforeError).length + 1; | |
52 builder.writeln("Error on line $lineNumber of ${error.source.fullName}: " | |
53 "${error.message}"); | |
54 | |
55 var errorLineIndex = beforeError.lastIndexOf("\n") + 1; | |
56 var errorEndOfLineIndex = receiver.result.indexOf("\n", error.offset); | |
57 if (errorEndOfLineIndex == -1) errorEndOfLineIndex = receiver.result.length; | |
58 var errorLine = receiver.result.substring( | |
59 errorLineIndex, errorEndOfLineIndex); | |
60 var errorColumn = error.offset - errorLineIndex; | |
61 var errorLength = error.length; | |
62 | |
63 // Ensure that the error line we display isn't too long. | |
64 if (errorLine.length > _MAX_ERROR_LINE_LENGTH) { | |
65 var leftLength = errorColumn; | |
66 var rightLength = errorLine.length - leftLength; | |
67 if (leftLength > _MAX_ERROR_LINE_LENGTH ~/ 2 && | |
68 rightLength > _MAX_ERROR_LINE_LENGTH ~/ 2) { | |
69 errorLine = "..." + errorLine.substring( | |
70 errorColumn - _MAX_ERROR_LINE_LENGTH ~/ 2 + 3, | |
71 errorColumn + _MAX_ERROR_LINE_LENGTH ~/ 2 - 3) | |
72 + "..."; | |
73 errorColumn = _MAX_ERROR_LINE_LENGTH ~/ 2; | |
74 } else if (rightLength > _MAX_ERROR_LINE_LENGTH ~/ 2) { | |
75 errorLine = errorLine.substring(0, _MAX_ERROR_LINE_LENGTH - 3) + "..."; | |
76 } else { | |
77 assert(leftLength > _MAX_ERROR_LINE_LENGTH ~/ 2); | |
78 errorColumn -= errorLine.length - _MAX_ERROR_LINE_LENGTH; | |
79 errorLine = "..." + errorLine.substring( | |
80 errorLine.length - _MAX_ERROR_LINE_LENGTH + 3, errorLine.length); | |
81 } | |
82 errorLength = math.min(errorLength, _MAX_ERROR_LINE_LENGTH - errorColumn); | |
83 } | |
84 builder.writeln(errorLine); | |
85 | |
86 for (var i = 0; i < errorColumn; i++) builder.write(" "); | |
87 for (var i = 0; i < errorLength; i++) builder.write("^"); | |
88 builder.writeln(); | |
89 | |
90 return builder.toString(); | |
91 } | |
92 } | |
93 | |
94 // A content receiver that collects all the content into a string. | |
95 class _ContentReceiver implements Source_ContentReceiver { | |
96 final _buffer = new StringBuffer(); | |
97 | |
98 String get result => _buffer.toString(); | |
99 | |
100 void accept(CharBuffer contents, _) => | |
101 _buffer.write(contents.subSequence(0, contents.length())); | |
102 | |
103 void accept2(String contents, _) => _buffer.write(contents); | |
104 } | |
OLD | NEW |