diff --git a/src/DocBlock/Tags/Factory/TypeFactory.php b/src/DocBlock/Tags/Factory/TypeFactory.php index 2204c2f..5745d99 100644 --- a/src/DocBlock/Tags/Factory/TypeFactory.php +++ b/src/DocBlock/Tags/Factory/TypeFactory.php @@ -17,6 +17,7 @@ use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Array_; use phpDocumentor\Reflection\Types\Callable_; +use phpDocumentor\Reflection\Types\CallableParameter; use phpDocumentor\Reflection\Types\ClassString; use phpDocumentor\Reflection\Types\Collection; 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\ArrayTypeNode; use PHPStan\PhpDocParser\Ast\Type\CallableTypeNode; +use PHPStan\PhpDocParser\Ast\Type\CallableTypeParameterNode; use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeForParameterNode; use PHPStan\PhpDocParser\Ast\Type\ConditionalTypeNode; use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode; @@ -189,7 +191,21 @@ final class TypeFactory 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 diff --git a/tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php index ca3c282..bb5a126 100644 --- a/tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php @@ -27,6 +27,7 @@ use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Array_; use phpDocumentor\Reflection\Types\ArrayKey; use phpDocumentor\Reflection\Types\Callable_; +use phpDocumentor\Reflection\Types\CallableParameter; use phpDocumentor\Reflection\Types\ClassString; use phpDocumentor\Reflection\Types\Collection; use phpDocumentor\Reflection\Types\Compound; @@ -49,9 +50,9 @@ use PHPUnit\Framework\TestCase; final class TypeFactoryTest extends TestCase { /** - * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createType - * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromGeneric - * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromCallable + * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createType + * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromGeneric + * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\TypeFactory::createFromCallable * @dataProvider typeProvider * @dataProvider genericsProvider * @dataProvider callableProvider @@ -208,15 +209,49 @@ final class TypeFactoryTest extends TestCase ], [ 'callable(): Foo', - new Callable_(), + new Callable_([], new Object_(new Fqsen('\\phpDocumentor\\Foo'))), ], [ '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', - 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') + ) + ), ], ]; }