Add a `SpanScanner.spanFromPosition()` method (dart-lang/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.
diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md
index 386a55b..a4c17b6 100644
--- a/pkgs/string_scanner/CHANGELOG.md
+++ b/pkgs/string_scanner/CHANGELOG.md
@@ -1,7 +1,10 @@
-## 1.2.1-wip
+## 1.3.0
* Require Dart 3.1.0
+* Add a `SpanScanner.spanFromPosition()` method which takes raw code units
+ rather than `SpanScanner.spanFrom()`'s `LineScannerState`s.
+
## 1.2.0
* Require Dart 2.18.0
diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart
index 150d507..cd9af0e 100644
--- a/pkgs/string_scanner/lib/src/relative_span_scanner.dart
+++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart
@@ -79,6 +79,18 @@
}
@override
+ FileSpan spanFromPosition(int startPosition, [int? endPosition]) {
+ RangeError.checkValidRange(
+ startPosition,
+ endPosition,
+ _sourceFile.length - _startLocation.offset,
+ 'startPosition',
+ 'endPosition');
+ return _sourceFile.span(_startLocation.offset + startPosition,
+ _startLocation.offset + (endPosition ?? position));
+ }
+
+ @override
bool matches(Pattern pattern) {
if (!super.matches(pattern)) {
_lastSpan = null;
diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart
index 413a433..509cf60 100644
--- a/pkgs/string_scanner/lib/src/span_scanner.dart
+++ b/pkgs/string_scanner/lib/src/span_scanner.dart
@@ -91,6 +91,17 @@
return _sourceFile.span(startState.position, endPosition);
}
+ /// Creates a [FileSpan] representing the source range between [startPosition]
+ /// and [endPosition], or the current position if [endPosition] is null.
+ ///
+ /// Each position should be a code unit offset into the string being scanned,
+ /// with the same conventions as [StringScanner.position].
+ ///
+ /// Throws a [RangeError] if [startPosition] or [endPosition] aren't within
+ /// this source file.
+ FileSpan spanFromPosition(int startPosition, [int? endPosition]) =>
+ _sourceFile.span(startPosition, endPosition ?? position);
+
@override
bool matches(Pattern pattern) {
if (!super.matches(pattern)) {
diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml
index eea570a..b858538 100644
--- a/pkgs/string_scanner/pubspec.yaml
+++ b/pkgs/string_scanner/pubspec.yaml
@@ -1,5 +1,5 @@
name: string_scanner
-version: 1.2.1-wip
+version: 1.3.0
description: A class for parsing strings using a sequence of patterns.
repository: https://github.com/dart-lang/string_scanner
diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart
index 0e20c36..93d9c47 100644
--- a/pkgs/string_scanner/test/span_scanner_test.dart
+++ b/pkgs/string_scanner/test/span_scanner_test.dart
@@ -75,6 +75,16 @@
expect(span.text, equals('o\nbar\nba'));
});
+ test('.spanFromPosition() returns a span from a previous state', () {
+ scanner.scan('fo');
+ final start = scanner.position;
+ scanner.scan('o\nba');
+ scanner.scan('r\nba');
+
+ final span = scanner.spanFromPosition(start + 2, start + 5);
+ expect(span.text, equals('bar'));
+ });
+
test('.emptySpan returns an empty span at the current location', () {
scanner.scan('foo\nba');
@@ -139,6 +149,16 @@
expect(span.text, equals('o\nbar\nba'));
});
+ test('.spanFromPosition() returns a span from a previous state', () {
+ scanner.scan('fo');
+ final start = scanner.position;
+ scanner.scan('o\nba');
+ scanner.scan('r\nba');
+
+ final span = scanner.spanFromPosition(start + 2, start + 5);
+ expect(span.text, equals('bar'));
+ });
+
test('.emptySpan returns an empty span at the current location', () {
scanner.scan('foo\nba');