mirror of
https://github.com/barryvdh/ReflectionDocBlock.git
synced 2026-08-18 10:07:12 +00:00
Fix docblock tag descriptions
Newlines and whitespaces were not handled as before. This caused issues for some users because our indent-recuction was broken. The cause seems to be an upstream issue in phpstan parser which is not resolved yet. But this work around post processing the tokens helps us to make it work as before.
This commit is contained in:
@@ -23,7 +23,9 @@ use PHPStan\PhpDocParser\Parser\TokenIterator;
|
||||
use PHPStan\PhpDocParser\Parser\TypeParser;
|
||||
use RuntimeException;
|
||||
|
||||
use function ltrim;
|
||||
use function property_exists;
|
||||
use function rtrim;
|
||||
|
||||
/**
|
||||
* Factory class creating tags using phpstan's parser
|
||||
@@ -42,18 +44,28 @@ class AbstractPHPStanFactory implements Factory
|
||||
|
||||
public function __construct(PHPStanFactory ...$factories)
|
||||
{
|
||||
$this->lexer = new Lexer();
|
||||
$constParser = new ConstExprParser();
|
||||
$this->parser = new PhpDocParser(new TypeParser($constParser), $constParser);
|
||||
$this->lexer = new Lexer(true);
|
||||
$constParser = new ConstExprParser(true, true, ['lines' => true, 'indexes' => true]);
|
||||
$this->parser = new PhpDocParser(
|
||||
new TypeParser($constParser, true, ['lines' => true, 'indexes' => true]),
|
||||
$constParser,
|
||||
true,
|
||||
true,
|
||||
['lines' => true, 'indexes' => true],
|
||||
true
|
||||
);
|
||||
$this->factories = $factories;
|
||||
}
|
||||
|
||||
public function create(string $tagLine, ?TypeContext $context = null): Tag
|
||||
{
|
||||
$tokens = new TokenIterator($this->lexer->tokenize($tagLine));
|
||||
$tokens = $this->tokenizeLine($tagLine);
|
||||
$ast = $this->parser->parseTag($tokens);
|
||||
if (property_exists($ast->value, 'description') === true) {
|
||||
$ast->value->setAttribute('description', $ast->value->description . $tokens->joinUntil(Lexer::TOKEN_END));
|
||||
$ast->value->setAttribute(
|
||||
'description',
|
||||
$ast->value->description . $tokens->joinUntil(Lexer::TOKEN_END)
|
||||
);
|
||||
}
|
||||
|
||||
if ($context === null) {
|
||||
@@ -75,4 +87,36 @@ class AbstractPHPStanFactory implements Factory
|
||||
$ast->name
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve the issue with the lexer not tokenizing the line correctly
|
||||
*
|
||||
* This method is a workaround for the lexer that includes newline tokens with spaces. For
|
||||
* phpstan this isn't an issue, as it doesn't do a lot of things with the indentation of descriptions.
|
||||
* But for us is important to keep the indentation of the descriptions, so we need to fix the lexer output.
|
||||
*/
|
||||
private function tokenizeLine(string $tagLine): TokenIterator
|
||||
{
|
||||
$tokens = $this->lexer->tokenize($tagLine);
|
||||
$fixed = [];
|
||||
foreach ($tokens as $token) {
|
||||
if (($token[1] === Lexer::TOKEN_PHPDOC_EOL) && rtrim($token[0], " \t") !== $token[0]) {
|
||||
$fixed[] = [
|
||||
rtrim($token[Lexer::VALUE_OFFSET], " \t"),
|
||||
Lexer::TOKEN_PHPDOC_EOL,
|
||||
$token[2] ?? null,
|
||||
];
|
||||
$fixed[] = [
|
||||
ltrim($token[Lexer::VALUE_OFFSET], "\n\r"),
|
||||
Lexer::TOKEN_HORIZONTAL_WS,
|
||||
($token[2] ?? null) + 1,
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
$fixed[] = $token;
|
||||
}
|
||||
|
||||
return new TokenIterator($fixed);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user