Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/PhpParser/ParserAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,13 @@ protected function getExpectedTokens(int $state): array {
*/
protected function getAttributes(int $tokenStartPos, int $tokenEndPos): array {
$startToken = $this->tokens[$tokenStartPos];
$endToken = $this->tokens[$tokenEndPos];
$afterEndToken = $this->tokens[$tokenEndPos + 1];
return [
'startLine' => $startToken->line,
'startTokenPos' => $tokenStartPos,
'startFilePos' => $startToken->pos,
'endLine' => $afterEndToken->line,
'endLine' => $afterEndToken->line - (substr($endToken->text, -1) === "\n" ? 1 : 0),
'endTokenPos' => $tokenEndPos,
'endFilePos' => $afterEndToken->pos - 1,
];
Expand Down
27 changes: 27 additions & 0 deletions test/PhpParser/ParserTestAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,33 @@ function test($a) {
], $var->getAttributes());
}

public function testEndLineAfterTrailingNewline(): void {
$parser = $this->getParser(new Lexer());
foreach (["\n", "\r\n"] as $newline) {
foreach ([
['<?php' . $newline . 'echo 1 ?>' . $newline . 'foo' . $newline, [[2, 2], [3, 3]]],
['<?php' . $newline . 'echo 1 ?>' . $newline . 'foo' . $newline . $newline, [[2, 2], [3, 4]]],
['<?php' . $newline . 'echo 1 ?>' . $newline . 'foo', [[2, 2], [3, 3]]],
['<?php' . $newline . 'echo 1 ?>' . $newline, [[2, 2]]],
] as [$code, $expected]) {
$lines = [];
foreach ($parser->parse($code) as $node) {
$lines[] = [$node->getStartLine(), $node->getEndLine()];
}
$this->assertSame($expected, $lines);
}
}
}

public function testInterpolatedStringPartEndLine(): void {
$parser = $this->getParser(new Lexer());
$stmts = $parser->parse('<?php' . "\n" . '"$a' . "\n" . '$b";');
$part = $stmts[0]->expr->parts[1];
$this->assertInstanceOf(Node\InterpolatedStringPart::class, $part);
$this->assertSame(2, $part->getStartLine());
$this->assertSame(2, $part->getEndLine());
}

public function testInvalidToken(): void {
$this->expectException(\RangeException::class);
$this->expectExceptionMessage('The lexer returned an invalid token (id=999, value=foobar)');
Expand Down
4 changes: 2 additions & 2 deletions test/code/parser/scalar/flexibleDocStringErrors.test
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ Invalid indentation - tabs and spaces cannot be mixed from 8:1 to 8:3
Invalid indentation - tabs and spaces cannot be mixed from 10:6 to 12:5
Invalid body indentation level (expecting an indentation level of at least 5) from 14:6 to 18:8
Invalid body indentation level (expecting an indentation level of at least 1) from 20:1 to 22:4
Invalid body indentation level (expecting an indentation level of at least 2) from 25:1 to 26:0
Invalid body indentation level (expecting an indentation level of at least 2) from 25:1 to 25:0
Invalid body indentation level (expecting an indentation level of at least 1) from 30:1 to 30:4
Invalid body indentation level (expecting an indentation level of at least 1) from 34:1 to 35:0
Invalid body indentation level (expecting an indentation level of at least 1) from 34:1 to 34:0
array(
0: Stmt_Expression(
expr: Scalar_String(
Expand Down