Add callable parameter support

This commit is contained in:
Jaapio
2022-11-04 15:43:05 +01:00
parent 50bf16734e
commit d6e90a3238
2 changed files with 58 additions and 7 deletions
+17 -1
View File
@@ -17,6 +17,7 @@ use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\TypeResolver;
use phpDocumentor\Reflection\Types\Array_; use phpDocumentor\Reflection\Types\Array_;
use phpDocumentor\Reflection\Types\Callable_; use phpDocumentor\Reflection\Types\Callable_;
use phpDocumentor\Reflection\Types\CallableParameter;
use phpDocumentor\Reflection\Types\ClassString; use phpDocumentor\Reflection\Types\ClassString;
use phpDocumentor\Reflection\Types\Collection; use phpDocumentor\Reflection\Types\Collection;
use phpDocumentor\Reflection\Types\Compound; use phpDocumentor\Reflection\Types\Compound;
@@ -33,6 +34,7 @@ use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode; use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode; use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
use PHPStan\PhpDocParser\Ast\Type\CallableTypeNode; use PHPStan\PhpDocParser\Ast\Type\CallableTypeNode;
use PHPStan\PhpDocParser\Ast\Type\CallableTypeParameterNode;
use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeForParameterNode; use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeForParameterNode;
use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeNode; use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeNode;
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode; use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
@@ -189,7 +191,21 @@ final class TypeFactory
private function createFromCallable(CallableTypeNode $type, ?Context $context): Callable_ private function createFromCallable(CallableTypeNode $type, ?Context $context): Callable_
{ {
return new Callable_(); return new Callable_(
array_map(
function (CallableTypeParameterNode $param) use ($context) {
return new CallableParameter(
$param->parameterName !== '' ? trim($param->parameterName, '$') : null,
$this->createType($param->type, $context),
$param->isReference,
$param->isVariadic,
$param->isOptional
);
},
$type->parameters
),
$this->createType($type->returnType, $context),
);
} }
private function createFromConst(ConstTypeNode $type, ?Context $context): ?Type private function createFromConst(ConstTypeNode $type, ?Context $context): ?Type
@@ -27,6 +27,7 @@ use phpDocumentor\Reflection\TypeResolver;
use phpDocumentor\Reflection\Types\Array_; use phpDocumentor\Reflection\Types\Array_;
use phpDocumentor\Reflection\Types\ArrayKey; use phpDocumentor\Reflection\Types\ArrayKey;
use phpDocumentor\Reflection\Types\Callable_; use phpDocumentor\Reflection\Types\Callable_;
use phpDocumentor\Reflection\Types\CallableParameter;
use phpDocumentor\Reflection\Types\ClassString; use phpDocumentor\Reflection\Types\ClassString;
use phpDocumentor\Reflection\Types\Collection; use phpDocumentor\Reflection\Types\Collection;
use phpDocumentor\Reflection\Types\Compound; use phpDocumentor\Reflection\Types\Compound;
@@ -49,9 +50,9 @@ use PHPUnit\Framework\TestCase;
final class TypeFactoryTest extends TestCase final class TypeFactoryTest extends TestCase
{ {
/** /**
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createType * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createType
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromGeneric * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromGeneric
* @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromCallable * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromCallable
* @dataProvider typeProvider * @dataProvider typeProvider
* @dataProvider genericsProvider * @dataProvider genericsProvider
* @dataProvider callableProvider * @dataProvider callableProvider
@@ -208,15 +209,49 @@ final class TypeFactoryTest extends TestCase
], ],
[ [
'callable(): Foo', 'callable(): Foo',
new Callable_(), new Callable_([], new Object_(new Fqsen('\\phpDocumentor\\Foo'))),
], ],
[ [
'callable(): (Foo&Bar)', 'callable(): (Foo&Bar)',
new Callable_(), new Callable_(
[],
new Intersection(
[
new Object_(new Fqsen('\\phpDocumentor\\Foo')),
new Object_(new Fqsen('\\phpDocumentor\\Bar'))
]
)
),
], ],
[ [
'callable(A&...$a=, B&...=, C): Foo', 'callable(A&...$a=, B&...=, C): Foo',
new Callable_(), new Callable_(
[
new CallableParameter(
'a',
new Object_(new Fqsen('\\phpDocumentor\\A')),
true,
true,
true
),
new CallableParameter(
null,
new Object_(new Fqsen('\\phpDocumentor\\B')),
true,
true,
true
),
new CallableParameter(
null,
new Object_(new Fqsen('\\phpDocumentor\\C')),
false,
false,
false
),
],
new Object_(new Fqsen('\\phpDocumentor\\Foo')
)
),
], ],
]; ];
} }