OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 source_span.file; | 5 library source_span.file; |
6 | 6 |
7 import 'dart:math' as math; | 7 import 'dart:math' as math; |
8 import 'dart:typed_data'; | 8 import 'dart:typed_data'; |
9 | 9 |
10 import 'package:path/path.dart' as p; | 10 import 'package:path/path.dart' as p; |
11 | 11 |
12 import 'colors.dart' as colors; | 12 import 'colors.dart' as colors; |
13 import 'location.dart'; | 13 import 'location.dart'; |
14 import 'span.dart'; | 14 import 'span.dart'; |
15 import 'span_context.dart'; | |
15 import 'span_mixin.dart'; | 16 import 'span_mixin.dart'; |
16 import 'utils.dart'; | 17 import 'utils.dart'; |
17 | 18 |
18 // Constants to determine end-of-lines. | 19 // Constants to determine end-of-lines. |
19 const int _LF = 10; | 20 const int _LF = 10; |
20 const int _CR = 13; | 21 const int _CR = 13; |
21 | 22 |
22 /// A class representing a source file. | 23 /// A class representing a source file. |
23 /// | 24 /// |
24 /// This doesn't necessarily have to correspond to a file on disk, just a chunk | 25 /// This doesn't necessarily have to correspond to a file on disk, just a chunk |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 } | 177 } |
177 | 178 |
178 /// A [SourceSpan] within a [SourceFile]. | 179 /// A [SourceSpan] within a [SourceFile]. |
179 /// | 180 /// |
180 /// Unlike the base [SourceSpan], [FileSpan] lazily computes its line and column | 181 /// Unlike the base [SourceSpan], [FileSpan] lazily computes its line and column |
181 /// values based on its offset and the contents of [file]. [FileSpan.message] is | 182 /// values based on its offset and the contents of [file]. [FileSpan.message] is |
182 /// also able to provide more context then [SourceSpan.message], and | 183 /// also able to provide more context then [SourceSpan.message], and |
183 /// [FileSpan.union] will return a [FileSpan] if possible. | 184 /// [FileSpan.union] will return a [FileSpan] if possible. |
184 /// | 185 /// |
185 /// A [FileSpan] can be created using [SourceFile.span]. | 186 /// A [FileSpan] can be created using [SourceFile.span]. |
186 class FileSpan extends SourceSpanMixin { | 187 class FileSpan extends SourceSpanMixin implements SourceSpanContext { |
187 /// The [file] that [this] belongs to. | 188 /// The [file] that [this] belongs to. |
188 final SourceFile file; | 189 final SourceFile file; |
189 | 190 |
190 /// The offset of the beginning of the span. | 191 /// The offset of the beginning of the span. |
191 /// | 192 /// |
192 /// [start] is lazily generated from this to avoid allocating unnecessary | 193 /// [start] is lazily generated from this to avoid allocating unnecessary |
193 /// objects. | 194 /// objects. |
194 final int _start; | 195 final int _start; |
195 | 196 |
196 /// The offset of the end of the span. | 197 /// The offset of the end of the span. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 if (sourceUrl != other.sourceUrl) { | 256 if (sourceUrl != other.sourceUrl) { |
256 throw new ArgumentError("Source URLs \"${sourceUrl}\" and " | 257 throw new ArgumentError("Source URLs \"${sourceUrl}\" and " |
257 " \"${other.sourceUrl}\" don't match."); | 258 " \"${other.sourceUrl}\" don't match."); |
258 } | 259 } |
259 | 260 |
260 var start = math.min(this._start, other._start); | 261 var start = math.min(this._start, other._start); |
261 var end = math.max(this._end, other._end); | 262 var end = math.max(this._end, other._end); |
262 return new FileSpan._(file, start, end); | 263 return new FileSpan._(file, start, end); |
263 } | 264 } |
264 | 265 |
265 String message(String message, {color}) { | 266 String get contextLine { |
Siggi Cherem (dart-lang)
2015/03/21 00:19:59
the old logic basically is now shared with the def
|
nweiz
2015/03/24 23:01:17
Nit: put getters above the constructor.
Siggi Cherem (dart-lang)
2015/03/25 00:33:25
Done.
|
266 if (color == true) color = colors.RED; | |
267 if (color == false) color = null; | |
268 | |
269 var line = start.line; | 267 var line = start.line; |
270 var column = start.column; | 268 return file.getText(file.getOffset(line), |
271 | |
272 var buffer = new StringBuffer(); | |
273 buffer.write('line ${start.line + 1}, column ${start.column + 1}'); | |
274 if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); | |
275 buffer.write(': $message\n'); | |
276 | |
277 var textLine = file.getText(file.getOffset(line), | |
278 line == file.lines - 1 ? null : file.getOffset(line + 1)); | 269 line == file.lines - 1 ? null : file.getOffset(line + 1)); |
279 | |
280 column = math.min(column, textLine.length - 1); | |
281 var toColumn = | |
282 math.min(column + end.offset - start.offset, textLine.length); | |
283 | |
284 if (color != null) { | |
285 buffer.write(textLine.substring(0, column)); | |
286 buffer.write(color); | |
287 buffer.write(textLine.substring(column, toColumn)); | |
288 buffer.write(colors.NONE); | |
289 buffer.write(textLine.substring(toColumn)); | |
290 } else { | |
291 buffer.write(textLine); | |
292 } | |
293 if (!textLine.endsWith('\n')) buffer.write('\n'); | |
294 | |
295 buffer.write(' ' * column); | |
296 if (color != null) buffer.write(color); | |
297 buffer.write('^' * math.max(toColumn - column, 1)); | |
298 if (color != null) buffer.write(colors.NONE); | |
299 return buffer.toString(); | |
300 } | 270 } |
301 } | 271 } |
OLD | NEW |