Repository navigation
Honor TokenReader subrange bounds in peek and backtrack. - #485
Christopher Pruijsen (cpruijsen) wants to merge 1 commit into
Conversation
Embedded readers could observe tokens outside their TokenSequence window because peekToken, peekPreviousTokenKind, and backtrackToMarker ignored the start/end indexes that the other peek methods already enforce. Fixes microsoft#481
Sylvester Kaczmarek (sylvesterkaczmarek)
left a comment
There was a problem hiding this comment.
At an embedded reader boundary, peekToken() now returns the tokenizer's global EndOfInput token. Its range is at the end of the whole comment, not readerEndIndex. NodeParser uses peekToken().range for diagnostics, so errors at an embedded boundary can point at the wrong location. Can this return an EOI token/range at the subrange end?
|
True about the range, it is the end of the comment. I do not think it reaches a diagnostic today. The |
|
Thanks for checking the call paths. Agreed that the range concern is not currently observable in NodeParser diagnostics. I would keep this fix focused on preventing out-of-window reads and backtracking. A subrange-local EndOfInput token can be handled separately if a caller needs its range. No further change requested from me. |
TokenReader.peekToken(),peekPreviousTokenKind(), andbacktrackToMarker()now honor the same[_readerStartIndex, _readerEndIndex)window thatpeekTokenKind()/peekTokenAfterKind()/peekTokenAfterAfterKind()already enforce. Fixes #481: an embedded reader could observe the token before its start or after its end, andbacktrackToMarkercould rewind into the outer stream.TokenReaderis not a public export. CurrentNodeParserhot paths already callpeekTokenKind()first, which is why existing parser snapshots did not fail.Decision
peekToken()past the window returns the stream'sEndOfInputtoken (tokens[tokens.length - 1]);peekPreviousTokenKind()treats_readerStartIndexas start-of-input;backtrackToMarkerthrows ifmarker < _readerStartIndex.Alternative: throw from
peekToken()(likereadToken()), or clamp an out-of-range marker to the window start. Open PR #482 takes the throw-from-peekToken()option.readToken()already states that peek must always return a validToken, and the other peek methods already signalEndOfInputat the window edge. Expired markers already throw as a parser bug. Can switch to throw-on-peek or clamp-on-backtrack.Test plan
tsdoc/src/parser/__tests__/TokenReader.test.tsfails without the source change and passes with it (embedded predecessor leak, next-token leak, emptyTokenSequence.createEmpty, out-of-range backtrack).@microsoft/tsdocHeft test run (typecheck / ESLint / API Extractor / 259 Jest tests).rush change --verifyon CI (change file included).Change log
Rush change file:
common/changes/@microsoft/tsdoc/fix-tokenreader-bounds_2026-09-11-13-00.json(patch).