fix: make resetPosition() accept a token character offset
resetPosition() used its argument directly as an index into the internal tokens array. The only position value the public API exposes is Token::$position, a character offset into the input string, so passing a multi-character token's offset silently resumed the lexer at the wrong token, or past the end of input. resetPosition() now locates the token whose character offset is greater than or equal to the given position and resumes from there, matching the offset semantics already used by getInputUntilPosition(). Closes #53
This commit is contained in:
1 parent
49dccbdc43
commit
f6e27044ad
2 files changed
+54
-2
No files matched your search
@@ -86,6 +86,39 @@ class AbstractLexerTest extends TestCase
|
||||
$this->assertEquals($expectedTokens[0], $this->concreteLexer->lookahead);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/doctrine/lexer/issues/53
|
||||
*
|
||||
* resetPosition() takes a character offset, not a token index. The input
|
||||
* below has multi-character tokens, so the second token's offset (6)
|
||||
* differs from its index (1).
|
||||
*/
|
||||
public function testResetPositionByTokenPosition(): void
|
||||
{
|
||||
$this->concreteLexer->setInput('price=10');
|
||||
|
||||
$this->assertTrue($this->concreteLexer->moveNext());
|
||||
$this->assertTrue($this->concreteLexer->moveNext());
|
||||
|
||||
$target = $this->concreteLexer->lookahead;
|
||||
$this->assertSame('=', $target->value);
|
||||
$this->assertSame(5, $target->position);
|
||||
|
||||
// Move the cursor past the index that used to coincide with the target.
|
||||
$remainingTokens = 0;
|
||||
while ($this->concreteLexer->moveNext()) {
|
||||
$remainingTokens++;
|
||||
}
|
||||
|
||||
$this->assertSame(1, $remainingTokens);
|
||||
$this->assertNull($this->concreteLexer->lookahead);
|
||||
|
||||
$this->concreteLexer->resetPosition($target->position);
|
||||
|
||||
$this->assertTrue($this->concreteLexer->moveNext());
|
||||
$this->assertEquals($target, $this->concreteLexer->lookahead);
|
||||
}
|
||||
|
||||
/** @phpstan-param list<Token<string, string|int>> $expectedTokens */
|
||||
#[DataProvider('dataProvider')]
|
||||
public function testMoveNext(string $input, array $expectedTokens): void
|
||||
|
||||
Reference in new issue
Block a user