Index: lib/src/span.dart |
diff --git a/lib/src/span.dart b/lib/src/span.dart |
index 9f150482c6da354adbbad9753a12a306b4bf432c..6f9013e55dc3b582ae01205ace1976110e557db9 100644 |
--- a/lib/src/span.dart |
+++ b/lib/src/span.dart |
@@ -57,6 +57,25 @@ abstract class SourceSpan implements Comparable<SourceSpan> { |
String message(String message, {color}); |
} |
+/// A class that describes a segment of source text with additional context. |
+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.
|
+ /// The text of the line containing this span. |
+ /// |
+ /// If the span covers multiple lines, this should only contain the first. |
+ final String context; |
+ |
+ /// Creates a new span from [start] to [end] (exclusive) containing [text], in |
+ /// the [context] line. |
+ /// |
+ /// [start] and [end] must have the same source URL and [start] must come |
+ /// before [end]. [text] must have a number of characters equal to the |
+ /// distance between [start] and [end]. [context] must contain [text], and |
+ /// [text] should start at `start.column` within [context]. |
+ factory SourceSpanWithContext( |
+ SourceLocation start, SourceLocation end, String text, String context) = |
+ SourceSpanWithContextBase; |
+} |
+ |
/// A base class for source spans with [start], [end], and [text] known at |
/// construction time. |
class SourceSpanBase extends SourceSpanMixin { |
@@ -76,3 +95,33 @@ class SourceSpanBase extends SourceSpanMixin { |
} |
} |
} |
+ |
+/// A base class for source spans with [start], [end], [text], and [context] |
+/// known at construction time. |
+class SourceSpanWithContextBase extends SourceSpanBase |
+ implements SourceSpanWithContext { |
+ /// The text of the line containing this span. |
+ /// |
+ /// 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
|
+ final String context; |
+ |
+ /// Creates a new span from [start] to [end] (exclusive) containing [text], in |
+ /// the [context] line. |
+ /// |
+ /// [start] and [end] must have the same source URL and [start] must come |
+ /// before [end]. [text] must have a number of characters equal to the |
+ /// distance between [start] and [end]. [context] must contain [text], and |
+ /// [text] should start at `start.column` within [context]. |
+ SourceSpanWithContextBase( |
+ SourceLocation start, SourceLocation end, String text, this.context) |
+ : super(start, end, text) { |
+ var index = context.indexOf(text); |
+ if (index == -1) { |
+ throw new ArgumentError( |
+ 'The context line "$context" must contain "$text".'); |
+ } else if (index != start.column) { |
+ throw new ArgumentError('The span text "$text" must start at ' |
+ 'column ${start.column + 1} in the context line "$context".'); |
+ } |
+ } |
+} |