Add typeless parameter support.

This commit is contained in:
Jaapio
2024-03-12 22:49:26 +01:00
parent 2b309a247d
commit 98566f2504
5 changed files with 78 additions and 14 deletions
+11 -2
View File
@@ -9,8 +9,10 @@ use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Tags\Param; use phpDocumentor\Reflection\DocBlock\Tags\Param;
use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\TypeResolver;
use phpDocumentor\Reflection\Types\Context; use phpDocumentor\Reflection\Types\Context;
use PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TypelessParamTagValueNode;
use Webmozart\Assert\Assert; use Webmozart\Assert\Assert;
use function trim; use function trim;
@@ -32,7 +34,13 @@ final class ParamFactory implements PHPStanFactory
public function create(PhpDocTagNode $node, Context $context): Tag public function create(PhpDocTagNode $node, Context $context): Tag
{ {
$tagValue = $node->value; $tagValue = $node->value;
Assert::isInstanceOf($tagValue, ParamTagValueNode::class); Assert::isInstanceOfAny(
$tagValue,
[
ParamTagValueNode::class,
TypelessParamTagValueNode::class
]
);
return new Param( return new Param(
trim($tagValue->parameterName, '$'), trim($tagValue->parameterName, '$'),
@@ -45,6 +53,7 @@ final class ParamFactory implements PHPStanFactory
public function supports(PhpDocTagNode $node, Context $context): bool public function supports(PhpDocTagNode $node, Context $context): bool
{ {
return $node->value instanceof ParamTagValueNode; return $node->value instanceof ParamTagValueNode
|| $node->value instanceof TypelessParamTagValueNode;
} }
} }
@@ -217,6 +217,5 @@ DOC;
], ],
$docblock->getTags() $docblock->getTags()
); );
} }
} }
@@ -16,6 +16,8 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\Tags\Param; use phpDocumentor\Reflection\DocBlock\Tags\Param;
use phpDocumentor\Reflection\Types\Context; use phpDocumentor\Reflection\Types\Context;
use phpDocumentor\Reflection\Types\Integer;
use phpDocumentor\Reflection\Types\Mixed_;
use phpDocumentor\Reflection\Types\String_; use phpDocumentor\Reflection\Types\String_;
final class ParamFactoryTest extends TagFactoryTestCase final class ParamFactoryTest extends TagFactoryTestCase
@@ -24,15 +26,29 @@ final class ParamFactoryTest extends TagFactoryTestCase
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::__construct * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::__construct
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::create * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::create
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::supports * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::supports
* @dataProvider paramInputProvider
*/ */
public function testParamIsCreated(): void public function testParamIsCreated(string $input, Param $expected): void
{ {
$ast = $this->parseTag('@param string $var'); $ast = $this->parseTag($input);
$factory = new ParamFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $factory = new ParamFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
$context = new Context('global'); $context = new Context('global');
self::assertTrue($factory->supports($ast, $context)); self::assertTrue($factory->supports($ast, $context));
self::assertEquals( self::assertEquals(
$expected,
$factory->create($ast, $context)
);
}
/**
* @return array<array-key, string|Param>
*/
public function paramInputProvider(): array
{
return [
[
'@param string $var',
new Param( new Param(
'var', 'var',
new String_(), new String_(),
@@ -40,7 +56,47 @@ final class ParamFactoryTest extends TagFactoryTestCase
new Description(''), new Description(''),
false false
), ),
$factory->create($ast, $context) ],
); [
'@param $param8 Description 4',
new Param(
'param8',
new Mixed_(),
false,
new Description('Description 4'),
false
),
],
[
'@param $param9',
new Param(
'param9',
new Mixed_(),
false,
new Description(''),
false
),
],
[
'@param int My Description',
new Param(
null,
new Integer(),
false,
new Description('My Description'),
false
),
],
[
'@param foo',
new Param(
null,
new Mixed_(),
false,
new Description(''),
false
),
],
];
} }
} }
@@ -45,7 +45,7 @@ abstract class TagFactoryTestCase extends TestCase
public function givenDescriptionFactory(): DescriptionFactory public function givenDescriptionFactory(): DescriptionFactory
{ {
$factory = m::mock(DescriptionFactory::class); $factory = m::mock(DescriptionFactory::class);
$factory->shouldReceive('create')->andReturn(new Description('')); $factory->shouldReceive('create')->andReturnUsing(static fn ($args) => new Description($args));
return $factory; return $factory;
} }
@@ -25,7 +25,7 @@ final class VarFactoryTest extends TagFactoryTestCase
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::create * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::create
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::supports * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::supports
*/ */
public function testParamIsCreated(): void public function testVarIsCreated(): void
{ {
$ast = $this->parseTag('@var string $var'); $ast = $this->parseTag('@var string $var');
$factory = new VarFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $factory = new VarFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());