| 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.span; | |
| 6 | |
| 7 import 'location.dart'; | |
| 8 import 'span_mixin.dart'; | |
| 9 | |
| 10 /// A class that describes a segment of source text. | |
| 11 abstract class SourceSpan implements Comparable<SourceSpan> { | |
| 12 /// The start location of this span. | |
| 13 final SourceLocation start; | |
| 14 | |
| 15 /// The end location of this span, exclusive. | |
| 16 final SourceLocation end; | |
| 17 | |
| 18 /// The source text for this span. | |
| 19 final String text; | |
| 20 | |
| 21 /// The URL of the source (typically a file) of this span. | |
| 22 /// | |
| 23 /// This may be null, indicating that the source URL is unknown or | |
| 24 /// unavailable. | |
| 25 final Uri sourceUrl; | |
| 26 | |
| 27 /// The length of this span, in characters. | |
| 28 final int length; | |
| 29 | |
| 30 /// Creates a new span from [start] to [end] (exclusive) containing [text]. | |
| 31 /// | |
| 32 /// [start] and [end] must have the same source URL and [start] must come | |
| 33 /// before [end]. [text] must have a number of characters equal to the | |
| 34 /// distance between [start] and [end]. | |
| 35 factory SourceSpan(SourceLocation start, SourceLocation end, String text) => | |
| 36 new SourceSpanBase(start, end, text); | |
| 37 | |
| 38 /// Creates a new span that's the union of [this] and [other]. | |
| 39 /// | |
| 40 /// The two spans must have the same source URL and may not be disjoint. | |
| 41 /// [text] is computed by combining [this.text] and [other.text]. | |
| 42 SourceSpan union(SourceSpan other); | |
| 43 | |
| 44 /// Compares two spans. | |
| 45 /// | |
| 46 /// [other] must have the same source URL as [this]. This orders spans by | |
| 47 /// [start] then [length]. | |
| 48 int compareTo(SourceSpan other); | |
| 49 | |
| 50 /// Formats [message] in a human-friendly way associated with this span. | |
| 51 /// | |
| 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 | |
| 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`, | |
| 56 /// it indicates that the text shouldn't be highlighted. | |
| 57 String message(String message, {color}); | |
| 58 } | |
| 59 | |
| 60 /// A base class for source spans with [start], [end], and [text] known at | |
| 61 /// construction time. | |
| 62 class SourceSpanBase extends SourceSpanMixin { | |
| 63 final SourceLocation start; | |
| 64 final SourceLocation end; | |
| 65 final String text; | |
| 66 | |
| 67 SourceSpanBase(this.start, this.end, this.text) { | |
| 68 if (end.sourceUrl != start.sourceUrl) { | |
| 69 throw new ArgumentError("Source URLs \"${start.sourceUrl}\" and " | |
| 70 " \"${end.sourceUrl}\" don't match."); | |
| 71 } else if (end.offset < start.offset) { | |
| 72 throw new ArgumentError('End $end must come after start $start.'); | |
| 73 } else if (text.length != start.distance(end)) { | |
| 74 throw new ArgumentError('Text "$text" must be ${start.distance(end)} ' | |
| 75 'characters long.'); | |
| 76 } | |
| 77 } | |
| 78 } | |
| OLD | NEW |