OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library source_span.source_span_mixin; | |
6 | |
7 import 'package:path/path.dart' as p; | |
8 | |
9 import 'colors.dart' as colors; | |
10 import 'source_span.dart'; | |
11 import 'utils.dart'; | |
12 | |
13 /// A mixin for easily implementing [SourceSpan]. | |
14 /// | |
15 /// This implements the [SourceSpan] methods in terms of [start], [end], and | |
16 /// [text]. This assumes that [start] and [end] have the same source URL, that | |
17 /// [start] comes before [end], and that [text] has a number of characters equal | |
18 /// to the distance between [start] and [end]. | |
19 abstract class SourceSpanMixin implements SourceSpan { | |
20 Uri get sourceUrl => start.sourceUrl; | |
21 int get length => end.offset - start.offset; | |
22 | |
23 int compareTo(SourceSpan other) { | |
24 int d = start.compareTo(other.start); | |
25 return d == 0 ? end.compareTo(other.end) : d; | |
26 } | |
27 | |
28 SourceSpan union(SourceSpan other) { | |
29 if (sourceUrl != other.sourceUrl) { | |
30 throw new ArgumentError("Source URLs \"${sourceUrl}\" and " | |
31 " \"${other.sourceUrl}\" don't match."); | |
32 } | |
33 | |
34 var start = min(this.start, other.start); | |
35 var end = max(this.end, other.end); | |
36 var beginSpan = start == this.start ? this : other; | |
37 var endSpan = end == this.end ? this : other; | |
38 | |
39 if (beginSpan.end.compareTo(endSpan.start) < 0) { | |
40 throw new ArgumentError("Spans $this and $other are disjoint."); | |
41 } | |
42 | |
43 var text = beginSpan.text + | |
44 endSpan.text.substring(beginSpan.end.distance(endSpan.start)); | |
Siggi Cherem (dart-lang)
2014/07/16 21:26:10
for disjoint unions, we could use a text with ' ..
nweiz
2014/07/17 20:22:08
I don't like the idea of making [text] not match [
| |
45 return new SourceSpan(start, end, text); | |
46 } | |
47 | |
48 String message(String message, {color}) { | |
49 if (color == true) color = colors.RED; | |
50 if (color == false) color = null; | |
51 | |
52 var buffer = new StringBuffer(); | |
53 buffer.write('line ${start.line + 1}, column ${start.column + 1}'); | |
54 if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); | |
55 buffer.write(': $message'); | |
56 if (length == 0) return buffer.toString(); | |
57 | |
58 buffer.write("\n"); | |
59 var textLine = text.split("\n").first; | |
Siggi Cherem (dart-lang)
2014/07/16 21:26:10
not sure I follow why just the first line?
nweiz
2014/07/17 20:22:08
To match the old behavior. I'd like to look into m
| |
60 if (color != null) buffer.write(color); | |
61 buffer.write(textLine); | |
62 buffer.write("\n"); | |
63 buffer.write('^' * textLine.length); | |
64 if (color != null) buffer.write(colors.NONE); | |
65 return buffer.toString(); | |
66 } | |
67 | |
68 bool operator ==(SourceSpan other) => | |
69 start == other.start && end == other.end; | |
70 | |
71 int get hashCode => start.hashCode + (31 * end.hashCode); | |
72 | |
73 String toString() => '<$runtimeType: from $start to $end "$text">'; | |
74 } | |
OLD | NEW |