Skip to content

[string_scanner] Fix SpanScanner.within() and LineScanner edge cases - #2633

Merged
kevmoo merged 3 commits into
mainfrom
fix-string_scanner
Oct 23, 2026
Merged

kevmoo merged 3 commits into
mainfrom
fix-string_scanner

Conversation

@kevmoo

@kevmoo kevmoo commented Oct 3, 2026

Copy link
Copy Markdown
Member
  • Fix SpanScanner.within()'s state.line and state.column to return span-relative coordinates rather than file-relative offsets.
  • Fix SpanScanner.within()'s error() to default length to 0 rather than 1 when lastMatch is null, preventing a RangeError when the span ends at the end of the underlying SourceFile.
  • Fix SpanScanner.within()'s lastSpan to be cleared when lastMatch is lazily invalidated after a position change.
  • Fix SpanScanner.within()'s spanFromPosition() to validate ranges against string.length rather than _sourceFile.length - _startLocation.offset.
  • Fix LineScanner.position= and SpanScanner.eager().position= to clear lastMatch and lastSpan when assigned the current position.
  • Deduplicate forward and backward CR/LF newline detection in _LineScanner via _isNewlineAt() and _advancePosition(), avoiding substring allocations in LineScanner.scan().

* Fix `SpanScanner.within()`'s `state.line` and `state.column` to return
  span-relative coordinates rather than file-relative offsets.
* Fix `SpanScanner.within()`'s `error()` to default `length` to `0` rather
  than `1` when `lastMatch` is `null`, preventing a `RangeError` when the
  span ends at the end of the underlying `SourceFile`.
* Fix `SpanScanner.within()`'s `lastSpan` to be cleared when `lastMatch` is
  lazily invalidated after a position change.
* Fix `SpanScanner.within()`'s `spanFromPosition()` to validate ranges
  against `string.length` rather than `_sourceFile.length - _startLocation.offset`.
* Fix `LineScanner.position=` and `SpanScanner.eager().position=` to clear
  `lastMatch` and `lastSpan` when assigned the current `position`.
* Deduplicate forward and backward CR/LF newline detection in `_LineScanner`
  via `_isNewlineAt()` and `_advancePosition()`, avoiding substring
  allocations in `LineScanner.scan()`.
@kevmoo
kevmoo requested a review from a team as a code owner October 3, 2026 16:53

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors and fixes several issues in the string_scanner package. Specifically, it updates SpanScanner.within() to return span-relative coordinates for state.line and state.column, defaults the error length to 0 when there is no lastMatch to prevent RangeError at EOF, resets lastSpan when the position changes without a match, and validates ranges against the span's length in spanFromPosition(). Additionally, assigning the current position to LineScanner.position= or SpanScanner.eager().position= now correctly clears lastMatch and lastSpan. Comprehensive tests have been added to verify these behaviors. I have no feedback to provide as there are no review comments.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

PR Health

Coverage ✔️
File Coverage
pkgs/string_scanner/lib/src/line_scanner.dart 💚 97 % ⬆️ 0 %
pkgs/string_scanner/lib/src/relative_span_scanner.dart 💚 91 % ⬆️ 11 %

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

License Headers ✔️
// Copyright (c) 2026, 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.

Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/html/test/differential_test.dart
pkgs/html/test/dom_parsing_test.dart
pkgs/html/test/mxss_test.dart
pkgs/html/test/noah_ark_clause_limit_test.dart

This check can be disabled by tagging the PR with skip-license-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
string_scanner Non-Breaking 1.4.1 1.4.2-wip 1.4.2-wip ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

Unused Dependencies ✔️
Package Status
string_scanner ✔️ All dependencies utilized correctly.

For details on how to fix these, see dependency_validator.

This check can be disabled by tagging the PR with skip-unused-dependencies-check.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check (for example, for non-user-visible changes when the package version is already at -wip).

Comment thread pkgs/string_scanner/CHANGELOG.md Resolved
@kevmoo
kevmoo requested a review from natebosch October 19, 2026 14:48
Comment thread pkgs/string_scanner/CHANGELOG.md Resolved
Comment thread pkgs/string_scanner/CHANGELOG.md Resolved
@kevmoo
kevmoo merged commit 7403f64 into main Oct 23, 2026
22 checks passed
@kevmoo
kevmoo deleted the fix-string_scanner branch October 23, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants