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.span; | 5 library source_span.span; |
6 | 6 |
7 import 'location.dart'; | 7 import 'location.dart'; |
8 import 'span_mixin.dart'; | 8 import 'span_mixin.dart'; |
9 | 9 |
10 /// A class that describes a segment of source text. | 10 /// A class that describes a segment of source text. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 /// Formats [message] in a human-friendly way associated with this span. | 50 /// Formats [message] in a human-friendly way associated with this span. |
51 /// | 51 /// |
52 /// [color] may either be a [String], a [bool], or `null`. If it's a string, | 52 /// [color] may either be a [String], a [bool], or `null`. If it's a string, |
53 /// it indicates an ANSII terminal color escape that should be used to | 53 /// it indicates an ANSII terminal color escape that should be used to |
54 /// highlight the span's text. If it's `true`, it indicates that the text | 54 /// highlight the span's text. If it's `true`, it indicates that the text |
55 /// should be highlighted using the default color. If it's `false` or `null`, | 55 /// should be highlighted using the default color. If it's `false` or `null`, |
56 /// it indicates that the text shouldn't be highlighted. | 56 /// it indicates that the text shouldn't be highlighted. |
57 String message(String message, {color}); | 57 String message(String message, {color}); |
58 } | 58 } |
59 | 59 |
60 /// A class that describes a segment of source text with additional context. | |
61 abstract class SourceSpanWithContext extends SourceSpan { | |
nweiz
2015/03/25 01:15:20
Now that I think about it, it would be nice to hav
Siggi Cherem (dart-lang)
2015/03/26 21:07:29
Done.
| |
62 /// The text of the line containing this span. | |
63 /// | |
64 /// If the span covers multiple lines, this should only contain the first. | |
65 final String context; | |
66 | |
67 /// Creates a new span from [start] to [end] (exclusive) containing [text], in | |
68 /// the [context] line. | |
69 /// | |
70 /// [start] and [end] must have the same source URL and [start] must come | |
71 /// before [end]. [text] must have a number of characters equal to the | |
72 /// distance between [start] and [end]. [context] must contain [text], and | |
73 /// [text] should start at `start.column` within [context]. | |
74 factory SourceSpanWithContext( | |
75 SourceLocation start, SourceLocation end, String text, String context) = | |
76 SourceSpanWithContextBase; | |
77 } | |
78 | |
60 /// A base class for source spans with [start], [end], and [text] known at | 79 /// A base class for source spans with [start], [end], and [text] known at |
61 /// construction time. | 80 /// construction time. |
62 class SourceSpanBase extends SourceSpanMixin { | 81 class SourceSpanBase extends SourceSpanMixin { |
63 final SourceLocation start; | 82 final SourceLocation start; |
64 final SourceLocation end; | 83 final SourceLocation end; |
65 final String text; | 84 final String text; |
66 | 85 |
67 SourceSpanBase(this.start, this.end, this.text) { | 86 SourceSpanBase(this.start, this.end, this.text) { |
68 if (end.sourceUrl != start.sourceUrl) { | 87 if (end.sourceUrl != start.sourceUrl) { |
69 throw new ArgumentError("Source URLs \"${start.sourceUrl}\" and " | 88 throw new ArgumentError("Source URLs \"${start.sourceUrl}\" and " |
70 " \"${end.sourceUrl}\" don't match."); | 89 " \"${end.sourceUrl}\" don't match."); |
71 } else if (end.offset < start.offset) { | 90 } else if (end.offset < start.offset) { |
72 throw new ArgumentError('End $end must come after start $start.'); | 91 throw new ArgumentError('End $end must come after start $start.'); |
73 } else if (text.length != start.distance(end)) { | 92 } else if (text.length != start.distance(end)) { |
74 throw new ArgumentError('Text "$text" must be ${start.distance(end)} ' | 93 throw new ArgumentError('Text "$text" must be ${start.distance(end)} ' |
75 'characters long.'); | 94 'characters long.'); |
76 } | 95 } |
77 } | 96 } |
78 } | 97 } |
98 | |
99 /// A base class for source spans with [start], [end], [text], and [context] | |
100 /// known at construction time. | |
101 class SourceSpanWithContextBase extends SourceSpanBase | |
102 implements SourceSpanWithContext { | |
103 /// The text of the line containing this span. | |
104 /// | |
105 /// If the span covers multiple lines, this should only contain the first. | |
nweiz
2015/03/25 01:10:39
I just realized that this property is incorrect; t
Siggi Cherem (dart-lang)
2015/03/26 21:07:29
I went with somewhere in between. I validate that
| |
106 final String context; | |
107 | |
108 /// Creates a new span from [start] to [end] (exclusive) containing [text], in | |
109 /// the [context] line. | |
110 /// | |
111 /// [start] and [end] must have the same source URL and [start] must come | |
112 /// before [end]. [text] must have a number of characters equal to the | |
113 /// distance between [start] and [end]. [context] must contain [text], and | |
114 /// [text] should start at `start.column` within [context]. | |
115 SourceSpanWithContextBase( | |
116 SourceLocation start, SourceLocation end, String text, this.context) | |
117 : super(start, end, text) { | |
118 var index = context.indexOf(text); | |
119 if (index == -1) { | |
120 throw new ArgumentError( | |
121 'The context line "$context" must contain "$text".'); | |
122 } else if (index != start.column) { | |
123 throw new ArgumentError('The span text "$text" must start at ' | |
124 'column ${start.column + 1} in the context line "$context".'); | |
125 } | |
126 } | |
127 } | |
OLD | NEW |