Chromium Code Reviews| Index: pkg/source_span/lib/src/source_span.dart | 
| diff --git a/pkg/source_span/lib/src/source_span.dart b/pkg/source_span/lib/src/source_span.dart | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..ba7f7aba469d7b9d3665d461bc6f0c6717d3f1eb | 
| --- /dev/null | 
| +++ b/pkg/source_span/lib/src/source_span.dart | 
| @@ -0,0 +1,76 @@ | 
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 
| +// for details. All rights reserved. Use of this source code is governed by a | 
| +// BSD-style license that can be found in the LICENSE file. | 
| + | 
| +library source_span.source_span; | 
| + | 
| +import 'source_location.dart'; | 
| +import 'source_span_mixin.dart'; | 
| + | 
| +/// A class that describes a segment of source text. | 
| +abstract class SourceSpan implements Comparable<SourceSpan> { | 
| + /// The start location of this span. | 
| + final SourceLocation start; | 
| + | 
| + /// The end location of this span, exclusive. | 
| + final SourceLocation end; | 
| + | 
| + /// The source text for this span. | 
| + final String text; | 
| + | 
| + /// The URL of the source (typically a file) of this span. | 
| + /// | 
| + /// This may be null, indicating that the source URL is unknown or | 
| + /// unavailable. | 
| + final Uri sourceUrl; | 
| + | 
| + /// The length of this span, in characters. | 
| + final int length; | 
| + | 
| + /// Creates a new span from [start] to [end] (exclusive) containing [text]. | 
| + /// | 
| + /// [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]. | 
| + factory SourceSpan(SourceLocation start, SourceLocation end, String text) => | 
| + new _SourceSpan(start, end, text); | 
| + | 
| + /// Creates a new span that's the union of [this] and [other]. | 
| + /// | 
| + /// The two spans must have the same source URL and may not be disjoint. | 
| 
 
Siggi Cherem (dart-lang)
2014/07/16 21:26:10
I don't think we should make disjointness an error
 
nweiz
2014/07/17 20:22:08
I made it forbid disjoint spans because I really w
 
Siggi Cherem (dart-lang)
2014/07/17 22:24:39
Ah, I had not realized until now that you made `te
 
nweiz
2014/07/17 23:18:15
Do we have a use case for spans without text avail
 
Siggi Cherem (dart-lang)
2014/07/18 00:11:54
I understand.
The only use-case I've seen is in t
 
nweiz
2014/07/18 00:30:24
I like "expand"—I've added it to FileSpan, which I
 
Siggi Cherem (dart-lang)
2014/07/18 00:45:24
Ah - thanks, I somehow missed it. After the file r
 
 | 
| + /// [text] is computed by combining [this.text] and [other.text]. | 
| + SourceSpan union(SourceSpan other); | 
| + | 
| + /// Compares two spans. | 
| + /// | 
| + /// [other] must have the same source URL as [this]. This orders spans by | 
| + /// [start] then [length]. | 
| + int compareTo(SourceSpan other); | 
| + | 
| + /// Formats [message] in a human-friendly way associated with this span. | 
| + /// | 
| + /// [color] may either be a [String], a [bool], or `null`. If it's a string, | 
| + /// it indicates an ANSII terminal color escape that should be used to | 
| + /// highlight the span's text. If it's `true`, it indicates that the text | 
| + /// should be highlighted using the default color. If it's `false` or `null`, | 
| + /// it indicates that the text shouldn't be highlighted. | 
| 
 
Siggi Cherem (dart-lang)
2014/07/16 21:26:09
that's a lot of semantics in one argument. I don't
 
nweiz
2014/07/17 20:22:08
I agree that this is packing "color" a little full
 
Siggi Cherem (dart-lang)
2014/07/17 22:24:39
ok. sounds good
 
 | 
| + String message(String message, {color}); | 
| +} | 
| + | 
| +class _SourceSpan extends SourceSpanMixin { | 
| + final SourceLocation start; | 
| + final SourceLocation end; | 
| + final String text; | 
| + | 
| + _SourceSpan(this.start, this.end, this.text) { | 
| 
 
Siggi Cherem (dart-lang)
2014/07/16 21:26:10
why not make this class public? alternatively, mak
 
nweiz
2014/07/17 20:22:08
I tried to put this stuff in SourceSpan, but it ca
 
Siggi Cherem (dart-lang)
2014/07/17 22:24:39
Your idea sounds good, it seems to match what we d
 
nweiz
2014/07/17 23:18:15
I like this idea a lot, but it means that someone
 
 | 
| + if (end.sourceUrl != start.sourceUrl) { | 
| + throw new ArgumentError("Source URLs \"${start.sourceUrl}\" and " | 
| + " \"${end.sourceUrl}\" don't match."); | 
| + } else if (end.offset < start.offset) { | 
| + throw new ArgumentError('End $end must come after start $start.'); | 
| + } else if (text.length != start.distance(end)) { | 
| + throw new ArgumentError('Text "$text" must be ${start.distance(end)} ' | 
| + 'characters long.'); | 
| + } | 
| + } | 
| +} |