Skip to content

Commit

Permalink
Add a SpanScanner.spanFromPosition() method (#78)
Browse files Browse the repository at this point in the history
Tracking raw ints can be more efficient than tracking
`LineScannerState` objects, and allows users to do small manual
manipulations on the resulting positions.
  • Loading branch information
nex3 committed Jul 9, 2024
1 parent 0de03b5 commit a40bbbd
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 2 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
12 changes: 12 additions & 0 deletions lib/src/relative_span_scanner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner {
_startLocation.offset + endPosition);
}

@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)) {
Expand Down
11 changes: 11 additions & 0 deletions lib/src/span_scanner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ class SpanScanner extends StringScanner implements LineScanner {
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)) {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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

Expand Down
20 changes: 20 additions & 0 deletions test/span_scanner_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ void main() {
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');

Expand Down Expand Up @@ -139,6 +149,16 @@ void testForImplementation(
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');

Expand Down

0 comments on commit a40bbbd

Please sign in to comment.