Skip to content

Commit a841233

Browse files
authored
Add a SpanScanner.spanFromPosition() method (dart-archive/string_scanner#78)
Tracking raw ints can be more efficient than tracking `LineScannerState` objects, and allows users to do small manual manipulations on the resulting positions.
1 parent fa4c694 commit a841233

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-2
lines changed

pkgs/string_scanner/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
## 1.2.1-wip
1+
## 1.3.0
22

33
* Require Dart 3.1.0
44

5+
* Add a `SpanScanner.spanFromPosition()` method which takes raw code units
6+
rather than `SpanScanner.spanFrom()`'s `LineScannerState`s.
7+
58
## 1.2.0
69

710
* Require Dart 2.18.0

pkgs/string_scanner/lib/src/relative_span_scanner.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner {
7878
_startLocation.offset + endPosition);
7979
}
8080

81+
@override
82+
FileSpan spanFromPosition(int startPosition, [int? endPosition]) {
83+
RangeError.checkValidRange(
84+
startPosition,
85+
endPosition,
86+
_sourceFile.length - _startLocation.offset,
87+
'startPosition',
88+
'endPosition');
89+
return _sourceFile.span(_startLocation.offset + startPosition,
90+
_startLocation.offset + (endPosition ?? position));
91+
}
92+
8193
@override
8294
bool matches(Pattern pattern) {
8395
if (!super.matches(pattern)) {

pkgs/string_scanner/lib/src/span_scanner.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ class SpanScanner extends StringScanner implements LineScanner {
9191
return _sourceFile.span(startState.position, endPosition);
9292
}
9393

94+
/// Creates a [FileSpan] representing the source range between [startPosition]
95+
/// and [endPosition], or the current position if [endPosition] is null.
96+
///
97+
/// Each position should be a code unit offset into the string being scanned,
98+
/// with the same conventions as [StringScanner.position].
99+
///
100+
/// Throws a [RangeError] if [startPosition] or [endPosition] aren't within
101+
/// this source file.
102+
FileSpan spanFromPosition(int startPosition, [int? endPosition]) =>
103+
_sourceFile.span(startPosition, endPosition ?? position);
104+
94105
@override
95106
bool matches(Pattern pattern) {
96107
if (!super.matches(pattern)) {

pkgs/string_scanner/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: string_scanner
2-
version: 1.2.1-wip
2+
version: 1.3.0
33
description: A class for parsing strings using a sequence of patterns.
44
repository: https://github.com/dart-lang/string_scanner
55

pkgs/string_scanner/test/span_scanner_test.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ void main() {
7575
expect(span.text, equals('o\nbar\nba'));
7676
});
7777

78+
test('.spanFromPosition() returns a span from a previous state', () {
79+
scanner.scan('fo');
80+
final start = scanner.position;
81+
scanner.scan('o\nba');
82+
scanner.scan('r\nba');
83+
84+
final span = scanner.spanFromPosition(start + 2, start + 5);
85+
expect(span.text, equals('bar'));
86+
});
87+
7888
test('.emptySpan returns an empty span at the current location', () {
7989
scanner.scan('foo\nba');
8090

@@ -139,6 +149,16 @@ void testForImplementation(
139149
expect(span.text, equals('o\nbar\nba'));
140150
});
141151

152+
test('.spanFromPosition() returns a span from a previous state', () {
153+
scanner.scan('fo');
154+
final start = scanner.position;
155+
scanner.scan('o\nba');
156+
scanner.scan('r\nba');
157+
158+
final span = scanner.spanFromPosition(start + 2, start + 5);
159+
expect(span.text, equals('bar'));
160+
});
161+
142162
test('.emptySpan returns an empty span at the current location', () {
143163
scanner.scan('foo\nba');
144164

0 commit comments

Comments
 (0)