Skip to content

Commit

Permalink
TokenIterator - detect newline
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 29, 2023
1 parent ccca1bd commit 522c7e2
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/Parser/TokenIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use function count;
use function in_array;
use function strlen;
use function substr;

class TokenIterator
{
Expand All @@ -25,6 +26,9 @@ class TokenIterator
/** @var list<int> */
private $skippedTokenTypes = [Lexer::TOKEN_HORIZONTAL_WS];

/** @var string|null */
private $newline = null;

/**
* @param list<array{string, int, int}> $tokens
*/
Expand Down Expand Up @@ -144,6 +148,12 @@ public function consumeTokenType(int $tokenType): void
$this->throwError($tokenType);
}

if ($tokenType === Lexer::TOKEN_PHPDOC_EOL) {
if ($this->newline === null) {
$this->detectNewline();
}
}

$this->index++;
$this->skipIrrelevantTokens();
}
Expand Down Expand Up @@ -184,13 +194,30 @@ public function tryConsumeTokenType(int $tokenType): bool
return false;
}

if ($tokenType === Lexer::TOKEN_PHPDOC_EOL) {
if ($this->newline === null) {
$this->detectNewline();
}
}

$this->index++;
$this->skipIrrelevantTokens();

return true;
}


private function detectNewline(): void
{
$value = $this->currentTokenValue();
if (substr($value, 0, 2) === "\r\n") {
$this->newline = "\r\n";
} elseif (substr($value, 0, 1) === "\n") {
$this->newline = "\n";
}
}


public function getSkippedHorizontalWhiteSpaceIfAny(): string
{
if ($this->index > 0 && $this->tokens[$this->index - 1][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) {
Expand Down Expand Up @@ -339,6 +366,11 @@ public function hasTokenImmediatelyAfter(int $pos, int $expectedTokenType): bool
return false;
}

public function getDetectedNewline(): ?string
{
return $this->newline;
}

/**
* Whether the given position is immediately surrounded by parenthesis.
*/
Expand Down
58 changes: 58 additions & 0 deletions tests/PHPStan/Parser/TokenIteratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php declare(strict_types = 1);

namespace PHPStan\PhpDocParser\Parser;

use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPUnit\Framework\TestCase;
use const PHP_EOL;

class TokenIteratorTest extends TestCase
{

/**
* @return iterable<array{string, ?string}>
*/
public function dataGetDetectedNewline(): iterable
{
yield [
'/** @param Foo $a */',
null,
];

yield [
'/**' . "\n" .
' * @param Foo $a' . "\n" .
' */',
"\n",
];

yield [
'/**' . "\r\n" .
' * @param Foo $a' . "\r\n" .
' */',
"\r\n",
];

yield [
'/**' . PHP_EOL .
' * @param Foo $a' . PHP_EOL .
' */',
PHP_EOL,
];
}

/**
* @dataProvider dataGetDetectedNewline
*/
public function testGetDetectedNewline(string $phpDoc, ?string $expectedNewline): void
{
$lexer = new Lexer(true);
$tokens = new TokenIterator($lexer->tokenize($phpDoc));
$constExprParser = new ConstExprParser();
$typeParser = new TypeParser($constExprParser);
$phpDocParser = new PhpDocParser($typeParser, $constExprParser);
$phpDocParser->parse($tokens);
$this->assertSame($expectedNewline, $tokens->getDetectedNewline());
}

}

0 comments on commit 522c7e2

Please sign in to comment.