diff --git a/src/Reflection/ParameterReflection.php b/src/Reflection/ParameterReflection.php index 42d9cde9..22ef6283 100644 --- a/src/Reflection/ParameterReflection.php +++ b/src/Reflection/ParameterReflection.php @@ -2,6 +2,7 @@ namespace Laminas\Code\Reflection; +use Laminas\Code\Reflection\DocBlock\Tag\ParamTag; use ReflectionClass; use ReflectionMethod; use ReflectionParameter; @@ -96,10 +97,19 @@ public function detectType() return null; } - $params = $docBlock->getTags('param'); + /** @var ParamTag[] $params */ + $params = $docBlock->getTags('param'); + $paramTag = $params[$this->getPosition()] ?? null; + $variableName = '$' . $this->getName(); - if (isset($params[$this->getPosition()])) { - return $params[$this->getPosition()]->getType(); + if ($paramTag && ('' === $paramTag->getVariableName() || $variableName === $paramTag->getVariableName())) { + return $paramTag->getTypes()[0] ?? ''; + } + + foreach ($params as $param) { + if ($param->getVariableName() === $variableName) { + return $param->getTypes()[0] ?? ''; + } } return null; diff --git a/test/Reflection/ParameterReflectionTest.php b/test/Reflection/ParameterReflectionTest.php index 53f066de..7d8c569d 100644 --- a/test/Reflection/ParameterReflectionTest.php +++ b/test/Reflection/ParameterReflectionTest.php @@ -58,6 +58,20 @@ public function testTypeReturn($param, $type) self::assertEquals($type, $parameter->detectType()); } + /** + * This test covers type detection when not all params declared in phpDoc block + * + * @dataProvider paramTypeWithNotAllParamsDeclared + */ + public function testTypeReturnWithNotAllParamsDeclared(string $param, string $type): void + { + $parameter = new Reflection\ParameterReflection( + [TestAsset\TestSampleClass5::class, 'methodWithNotAllParamsDeclared'], + $param + ); + self::assertEquals($type, $parameter->detectType()); + } + public function testCallableTypeHint() { $parameter = new Reflection\ParameterReflection( @@ -82,6 +96,21 @@ public function paramType(): array ]; } + /** + * @return string[][] + * @psalm-return non-empty-list + */ + public function paramTypeWithNotAllParamsDeclared(): array + { + return [ + ['one', 'string'], + ['two', 'string'], + ['three', 'int'], + ['four', 'string'], + ['five', 'string'], + ]; + } + /** * @group zendframework/zend-code#29 * @dataProvider reflectionHints diff --git a/test/Reflection/TestAsset/TestSampleClass5.php b/test/Reflection/TestAsset/TestSampleClass5.php index b859af3e..abf21b02 100644 --- a/test/Reflection/TestAsset/TestSampleClass5.php +++ b/test/Reflection/TestAsset/TestSampleClass5.php @@ -52,4 +52,21 @@ public function doSomethingElse($one, $two = 2, $three = 'three') { return 'mixedValue'; } + + /** + * @param string|array|null $two + * @param int|null $three + * @param string|bool|int|float|array|null $five + * + * @return void + */ + public function methodWithNotAllParamsDeclared( + string $one, + $two = null, + int $three = null, + string $four = '', + $five = null + ) { + + } }