diff --git a/src/Rules/ArrayTypes/MissingArrayValueTypeInMethodParameterRule.php b/src/Rules/ArrayTypes/MissingArrayValueTypeInMethodParameterRule.php new file mode 100644 index 00000000..c5d34dd2 --- /dev/null +++ b/src/Rules/ArrayTypes/MissingArrayValueTypeInMethodParameterRule.php @@ -0,0 +1,78 @@ +isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $methodReflection = $scope->getClassReflection()->getNativeMethod($node->name->name); + + $messages = []; + + foreach (ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getParameters() as $parameterReflection) { + $message = $this->checkMethodParameter($methodReflection, $parameterReflection); + if ($message === null) { + continue; + } + + /** @var string $message */ + $message = $message; + + $messages[] = $message; + } + + return $messages; + } + + private function checkMethodParameter(MethodReflection $methodReflection, ParameterReflection $parameterReflection): ?string + { + $parameterType = $parameterReflection->getType(); + + if (!$parameterType instanceof ArrayType) { + return null; + } + + $valueType = $parameterType->getIterableValueType(); + + if ($valueType instanceof MixedType && !$valueType->isExplicitMixed()) { + return sprintf( + 'Method %s::%s() has parameter $%s of type array with no value typehint specified.', + $methodReflection->getDeclaringClass()->getDisplayName(), + $methodReflection->getName(), + $parameterReflection->getName() + ); + } + + return null; + } + +} diff --git a/tests/Rules/ArrayTypes/MissingArrayValueTypeInMethodParameterRuleTest.php b/tests/Rules/ArrayTypes/MissingArrayValueTypeInMethodParameterRuleTest.php new file mode 100644 index 00000000..52eee2e0 --- /dev/null +++ b/tests/Rules/ArrayTypes/MissingArrayValueTypeInMethodParameterRuleTest.php @@ -0,0 +1,33 @@ +analyse([__DIR__ . '/data/missing-array-types-in-method-parameter-typehint.php'], [ + /* not detected by now + [ + 'Method MissingArrayValueTypeInMethodParameter\FooInterface::getFoo() has parameter $p1 of type array with no value typehint specified.', + 11, + ], + */ + [ + 'Method MissingArrayValueTypeInMethodParameter\FooParent::getBar() has parameter $p2 of type array with no value typehint specified.', + 18, + ], + [ + 'Method MissingArrayValueTypeInMethodParameter\Foo::getBar() has parameter $p2 of type array with no value typehint specified.', + 39, + ], + ]); + } + +} diff --git a/tests/Rules/ArrayTypes/data/missing-array-types-in-method-parameter-typehint.php b/tests/Rules/ArrayTypes/data/missing-array-types-in-method-parameter-typehint.php new file mode 100644 index 00000000..d12803da --- /dev/null +++ b/tests/Rules/ArrayTypes/data/missing-array-types-in-method-parameter-typehint.php @@ -0,0 +1,60 @@ +>> $p1 + */ + public function getFoo($p1): void + { + + } + + /** + * @param $p2 + */ + public function getBar(array $p2) + { + + } + + /** + * @param array $p3 + */ + public function getBaz($p3, $p4): bool + { + return false; + } + + /** + * @param mixed[] $p5 + */ + public function getFooBar(array $p5): bool + { + return false; + } + +} diff --git a/tests/Rules/Functions/data/missing-function-return-typehint.php b/tests/Rules/Functions/data/missing-function-return-typehint.php index 493a5daf..29b8c24e 100644 --- a/tests/Rules/Functions/data/missing-function-return-typehint.php +++ b/tests/Rules/Functions/data/missing-function-return-typehint.php @@ -12,7 +12,7 @@ function globalFunction2($a, $b, $c): bool $closure = function($a, $b, $c) { }; - + return false; }