mirror of
https://github.com/barryvdh/ReflectionDocBlock.git
synced 2026-08-18 01:57:13 +00:00
Bugfix: resolve issue with multiline descriptions
The phpstan parser is not consuming the full description when parsing docblocks with a more complex description. For them it's mostlikely not an issue as phpstan doesn't use the descriptions. But it will also parse the descriptions into unexpected tags. This could be an advantage but is not according to the phpdoc spec. Our own tokenizer is already tokenizing the docblocks into the correct parts. So all we needed to do is assume all remaining tokens in the phpstan ast belong to the description. From there our own code is able to handle this as before in v5.3. fixes #365
This commit is contained in:
@@ -23,6 +23,8 @@ use PHPStan\PhpDocParser\Parser\TokenIterator;
|
||||
use PHPStan\PhpDocParser\Parser\TypeParser;
|
||||
use RuntimeException;
|
||||
|
||||
use function property_exists;
|
||||
|
||||
/**
|
||||
* Factory class creating tags using phpstan's parser
|
||||
*
|
||||
@@ -48,8 +50,11 @@ class AbstractPHPStanFactory implements Factory
|
||||
|
||||
public function create(string $tagLine, ?TypeContext $context = null): Tag
|
||||
{
|
||||
$tokens = $this->lexer->tokenize($tagLine);
|
||||
$ast = $this->parser->parseTag(new TokenIterator($tokens));
|
||||
$tokens = new TokenIterator($this->lexer->tokenize($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));
|
||||
}
|
||||
|
||||
if ($context === null) {
|
||||
$context = new TypeContext('');
|
||||
|
||||
@@ -19,6 +19,7 @@ use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\OffsetAccessTypeNode;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
use function trim;
|
||||
|
||||
@@ -68,11 +69,16 @@ final class ParamFactory implements PHPStanFactory
|
||||
);
|
||||
}
|
||||
|
||||
$description = $tagValue->getAttribute('description');
|
||||
if (is_string($description) === false) {
|
||||
$description = $tagValue->description;
|
||||
}
|
||||
|
||||
return new Param(
|
||||
trim($tagValue->parameterName, '$'),
|
||||
$this->typeResolver->createType($tagValue->type ?? new IdentifierTypeNode('mixed'), $context),
|
||||
$tagValue->isVariadic,
|
||||
$this->descriptionFactory->create($tagValue->description, $context),
|
||||
$this->descriptionFactory->create($description, $context),
|
||||
$tagValue->isReference
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
use function is_string;
|
||||
use function trim;
|
||||
|
||||
/**
|
||||
@@ -34,10 +35,15 @@ final class PropertyFactory implements PHPStanFactory
|
||||
$tagValue = $node->value;
|
||||
Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
|
||||
|
||||
$description = $tagValue->getAttribute('description');
|
||||
if (is_string($description) === false) {
|
||||
$description = $tagValue->description;
|
||||
}
|
||||
|
||||
return new Property(
|
||||
trim($tagValue->propertyName, '$'),
|
||||
$this->typeResolver->createType($tagValue->type, $context),
|
||||
$this->descriptionFactory->create($tagValue->description, $context)
|
||||
$this->descriptionFactory->create($description, $context)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
use function is_string;
|
||||
use function trim;
|
||||
|
||||
/**
|
||||
@@ -34,10 +35,15 @@ final class PropertyReadFactory implements PHPStanFactory
|
||||
$tagValue = $node->value;
|
||||
Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
|
||||
|
||||
$description = $tagValue->getAttribute('description');
|
||||
if (is_string($description) === false) {
|
||||
$description = $tagValue->description;
|
||||
}
|
||||
|
||||
return new PropertyRead(
|
||||
trim($tagValue->propertyName, '$'),
|
||||
$this->typeResolver->createType($tagValue->type, $context),
|
||||
$this->descriptionFactory->create($tagValue->description, $context)
|
||||
$this->descriptionFactory->create($description, $context)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
use function is_string;
|
||||
use function trim;
|
||||
|
||||
/**
|
||||
@@ -34,10 +35,15 @@ final class PropertyWriteFactory implements PHPStanFactory
|
||||
$tagValue = $node->value;
|
||||
Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
|
||||
|
||||
$description = $tagValue->getAttribute('description');
|
||||
if (is_string($description) === false) {
|
||||
$description = $tagValue->description;
|
||||
}
|
||||
|
||||
return new PropertyWrite(
|
||||
trim($tagValue->propertyName, '$'),
|
||||
$this->typeResolver->createType($tagValue->type, $context),
|
||||
$this->descriptionFactory->create($tagValue->description, $context)
|
||||
$this->descriptionFactory->create($description, $context)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* @internal This class is not part of the BC promise of this library.
|
||||
*/
|
||||
@@ -32,9 +34,14 @@ final class ReturnFactory implements PHPStanFactory
|
||||
$tagValue = $node->value;
|
||||
Assert::isInstanceOf($tagValue, ReturnTagValueNode::class);
|
||||
|
||||
$description = $tagValue->getAttribute('description');
|
||||
if (is_string($description) === false) {
|
||||
$description = $tagValue->description;
|
||||
}
|
||||
|
||||
return new Return_(
|
||||
$this->typeResolver->createType($tagValue->type, $context),
|
||||
$this->descriptionFactory->create($tagValue->description, $context)
|
||||
$this->descriptionFactory->create($description, $context)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
use function is_string;
|
||||
use function trim;
|
||||
|
||||
/**
|
||||
@@ -34,10 +35,15 @@ final class VarFactory implements PHPStanFactory
|
||||
$tagValue = $node->value;
|
||||
Assert::isInstanceOf($tagValue, VarTagValueNode::class);
|
||||
|
||||
$description = $tagValue->getAttribute('description');
|
||||
if (is_string($description) === false) {
|
||||
$description = $tagValue->description;
|
||||
}
|
||||
|
||||
return new Var_(
|
||||
trim($tagValue->variableName, '$'),
|
||||
$this->typeResolver->createType($tagValue->type, $context),
|
||||
$this->descriptionFactory->create($tagValue->description, $context)
|
||||
$this->descriptionFactory->create($description, $context)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user