diff --git a/src/TypeResolver.php b/src/TypeResolver.php index 80e68109..79a2ba37 100644 --- a/src/TypeResolver.php +++ b/src/TypeResolver.php @@ -466,18 +466,22 @@ private function createFromGeneric(GenericTypeNode $type, Context $context): Typ private function createFromCallable(CallableTypeNode $type, Context $context): Callable_ { - return new Callable_(array_map( - function (CallableTypeParameterNode $param) use ($context): CallableParameter { - return new CallableParameter( - $this->createType($param->type, $context), - $param->parameterName !== '' ? trim($param->parameterName, '$') : null, - $param->isReference, - $param->isVariadic, - $param->isOptional - ); - }, - $type->parameters - ), $this->createType($type->returnType, $context)); + return new Callable_( + (string) $type->identifier, + array_map( + function (CallableTypeParameterNode $param) use ($context): CallableParameter { + return new CallableParameter( + $this->createType($param->type, $context), + $param->parameterName !== '' ? trim($param->parameterName, '$') : null, + $param->isReference, + $param->isVariadic, + $param->isOptional + ); + }, + $type->parameters + ), + $this->createType($type->returnType, $context) + ); } private function createFromConst(ConstTypeNode $type, Context $context): Type diff --git a/src/Types/Callable_.php b/src/Types/Callable_.php index 6b06489e..e9b9b232 100644 --- a/src/Types/Callable_.php +++ b/src/Types/Callable_.php @@ -22,6 +22,8 @@ */ final class Callable_ implements Type { + /** @var string */ + private $identifier; /** @var Type|null */ private $returnType; /** @var CallableParameter[] */ @@ -30,12 +32,21 @@ final class Callable_ implements Type /** * @param CallableParameter[] $parameters */ - public function __construct(array $parameters = [], ?Type $returnType = null) - { + public function __construct( + string $identifier = 'callable', + array $parameters = [], + ?Type $returnType = null + ) { + $this->identifier = $identifier; $this->parameters = $parameters; $this->returnType = $returnType; } + public function getIdentifier(): string + { + return $this->identifier; + } + /** @return CallableParameter[] */ public function getParameters(): array { @@ -52,6 +63,6 @@ public function getReturnType(): ?Type */ public function __toString(): string { - return 'callable'; + return $this->identifier; } } diff --git a/tests/unit/TypeResolverTest.php b/tests/unit/TypeResolverTest.php index fadc9fe7..8abd02e6 100644 --- a/tests/unit/TypeResolverTest.php +++ b/tests/unit/TypeResolverTest.php @@ -1135,11 +1135,20 @@ public function callableProvider(): array ], [ 'callable(): Foo', - new Callable_([], new Object_(new Fqsen('\\phpDocumentor\\Foo'))), + new Callable_('callable', [], new Object_(new Fqsen('\\phpDocumentor\\Foo'))), + ], + [ + 'Closure(): Foo', + new Callable_('Closure', [], new Object_(new Fqsen('\\phpDocumentor\\Foo'))), + ], + [ + '\Closure(): Foo', + new Callable_('\Closure', [], new Object_(new Fqsen('\\phpDocumentor\\Foo'))), ], [ 'callable(): (Foo&Bar)', new Callable_( + 'callable', [], new Intersection( [ @@ -1152,6 +1161,7 @@ public function callableProvider(): array [ 'callable(A&...$a=, B&...=, C): Foo', new Callable_( + 'callable', [ new CallableParameter( new Object_(new Fqsen('\\phpDocumentor\\A')), diff --git a/tests/unit/Types/CallableTest.php b/tests/unit/Types/CallableTest.php new file mode 100644 index 00000000..e9da6755 --- /dev/null +++ b/tests/unit/Types/CallableTest.php @@ -0,0 +1,81 @@ +assertSame($identifier, $type->getIdentifier()); + $this->assertSame($parameters, $type->getParameters()); + $this->assertSame($returnType, $type->getReturnType()); + } + + /** + * @dataProvider provideToStringData + */ + public function testToString(string $expectedResult, Callable_ $type): void + { + $this->assertSame($expectedResult, (string) $type); + } + + /** + * @return array + */ + public static function provideToStringData(): array + { + return [ + 'basic' => [ + 'callable', + new Callable_(), + ], + 'closure' => [ + '\Closure', + new Callable_('\Closure'), + ], + ]; + } +}