diff --git a/src/Types/CallableParameter.php b/src/Types/CallableParameter.php index 51c550b..84a6a7b 100644 --- a/src/Types/CallableParameter.php +++ b/src/Types/CallableParameter.php @@ -14,6 +14,8 @@ use phpDocumentor\Reflection\Type; +use function trim; + /** * Value Object representing a Callable parameters. * @@ -74,4 +76,14 @@ public function isOptional(): bool { return $this->isOptional; } + + public function __toString(): string + { + $reference = $this->isReference ? '&' : ''; + $variadic = $this->isVariadic ? '...' : ''; + $optional = $this->isOptional ? '=' : ''; + $name = $this->name !== null ? '$' . $this->name : ''; + + return trim($this->type . ' ' . $reference . $variadic . $name . $optional); + } } diff --git a/src/Types/Callable_.php b/src/Types/Callable_.php index e9b9b23..f06325b 100644 --- a/src/Types/Callable_.php +++ b/src/Types/Callable_.php @@ -15,6 +15,8 @@ use phpDocumentor\Reflection\Type; +use function implode; + /** * Value Object representing a Callable type. * @@ -63,6 +65,16 @@ public function getReturnType(): ?Type */ public function __toString(): string { - return $this->identifier; + if (!$this->parameters && $this->returnType === null) { + return $this->identifier; + } + + if ($this->returnType instanceof self) { + $returnType = '(' . (string) $this->returnType . ')'; + } else { + $returnType = (string) $this->returnType; + } + + return $this->identifier . '(' . implode(', ', $this->parameters) . '): ' . $returnType; } } diff --git a/tests/unit/TypeResolverTest.php b/tests/unit/TypeResolverTest.php index 4de0d43..61ce547 100644 --- a/tests/unit/TypeResolverTest.php +++ b/tests/unit/TypeResolverTest.php @@ -1192,6 +1192,34 @@ public function callableProvider(): array new Object_(new Fqsen('\\phpDocumentor\\Foo')) ), ], + [ + 'Closure(mixed): (callable(mixed): mixed)', + new Callable_( + 'Closure', + [ + new CallableParameter( + new Mixed_(), + null, + false, + false, + false + ), + ], + new Callable_( + 'callable', + [ + new CallableParameter( + new Mixed_(), + null, + false, + false, + false + ), + ], + new Mixed_() + ) + ), + ], ]; } diff --git a/tests/unit/Types/CallableTest.php b/tests/unit/Types/CallableTest.php index e9da675..6eca238 100644 --- a/tests/unit/Types/CallableTest.php +++ b/tests/unit/Types/CallableTest.php @@ -76,6 +76,65 @@ public static function provideToStringData(): array '\Closure', new Callable_('\Closure'), ], + 'with different types' => [ + 'callable(\\phpDocumentor\\C, \\phpDocumentor\\A &...$a=, \\phpDocumentor\\B &...=): ' + . '\\phpDocumentor\\Foo', + new Callable_( + 'callable', + [ + new CallableParameter( + new Object_(new Fqsen('\\phpDocumentor\\C')), + null, + false, + false, + false + ), + new CallableParameter( + new Object_(new Fqsen('\\phpDocumentor\\A')), + 'a', + true, + true, + true + ), + new CallableParameter( + new Object_(new Fqsen('\\phpDocumentor\\B')), + null, + true, + true, + true + ), + ], + new Object_(new Fqsen('\\phpDocumentor\\Foo')) + ), + ], + 'return callable' => [ + 'Closure(mixed): (callable(mixed): mixed)', + new Callable_( + 'Closure', + [ + new CallableParameter( + new Mixed_(), + null, + false, + false, + false + ), + ], + new Callable_( + 'callable', + [ + new CallableParameter( + new Mixed_(), + null, + false, + false, + false + ), + ], + new Mixed_() + ) + ), + ], ]; } }