Skip to content

Commit f5f4b00

Browse files
committed
Adding difference in detection between mixed[] and array
1 parent bfdea4f commit f5f4b00

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

src/Rules/TypeHints/AbstractMissingTypeHintRule.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace TheCodingMachine\PHPStan\Rules\TypeHints;
55

66

7+
use phpDocumentor\Reflection\DocBlockFactory;
78
use phpDocumentor\Reflection\Type;
89
use phpDocumentor\Reflection\Types\Array_;
910
use phpDocumentor\Reflection\Types\Boolean;
@@ -24,6 +25,8 @@
2425
use Roave\BetterReflection\Reflection\ReflectionFunction;
2526
use Roave\BetterReflection\Reflection\ReflectionMethod;
2627
use Roave\BetterReflection\Reflection\ReflectionParameter;
28+
use Roave\BetterReflection\TypesFinder\PhpDocumentor\NamespaceNodeToReflectionTypeContext;
29+
use Roave\BetterReflection\TypesFinder\ResolveTypes;
2730

2831
abstract class AbstractMissingTypeHintRule implements Rule
2932
{
@@ -181,10 +184,12 @@ private function analyzeWithTypehint($context, Type $phpTypeHint, array $docBloc
181184
}
182185

183186
if ($docblockTypehint->getValueType() instanceof Mixed_) {
184-
if ($context instanceof ReflectionParameter) {
185-
return sprintf('%s, parameter $%s type is "array". Please provide a more specific @param annotation. For instance: @param int[] $%s', $this->getContext($context), $context->getName(), $context->getName());
186-
} else {
187-
return sprintf('%s, return type is "array". Please provide a more specific @return annotation. For instance: @return int[]', $this->getContext($context));
187+
if (!$this->findExplicitMixedArray($context)) {
188+
if ($context instanceof ReflectionParameter) {
189+
return sprintf('%s, parameter $%s type is "array". Please provide a more specific @param annotation in the docblock. For instance: @param int[] $%s. Use @param mixed[] $%s if this is really an array of mixed values.', $this->getContext($context), $context->getName(), $context->getName(), $context->getName());
190+
} else {
191+
return sprintf('%s, return type is "array". Please provide a more specific @return annotation. For instance: @return int[]. Use @return mixed[] if this is really an array of mixed values.', $this->getContext($context));
192+
}
188193
}
189194
}
190195
}
@@ -193,6 +198,23 @@ private function analyzeWithTypehint($context, Type $phpTypeHint, array $docBloc
193198
return null;
194199
}
195200

201+
/**
202+
* @param ReflectionParameter|ReflectionMethod|ReflectionFunction $context
203+
* @return bool
204+
*/
205+
private function findExplicitMixedArray($context) : bool
206+
{
207+
if ($context instanceof ReflectionParameter) {
208+
$context = $context->getDeclaringFunction();
209+
}
210+
211+
$docComment = $context->getDocComment();
212+
213+
// Very approximate solution: let's find in the whole docblock whether there is a mixed[] value or not.
214+
// TODO: improve this to target precisely the parameter or return type.
215+
return strpos($docComment, 'mixed[]') !== false;
216+
}
217+
196218
/**
197219
* @param ReflectionParameter|ReflectionMethod|ReflectionFunction $context
198220
* @param Type[] $docBlockTypeHints

tests/Rules/TypeHints/MissingTypeHintRuleInFunctionTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ public function testCheckCatchedException()
6464
[
6565
'In function "mismatch", return type is type-hinted to "string" but the @return annotation says it is a "int". Please fix the @return annotation.',
6666
52,
67+
],
68+
[
69+
'In function "test8", parameter $any_array type is "array". Please provide a more specific @param annotation in the docblock. For instance: @param int[] $any_array. Use @param mixed[] $any_array if this is really an array of mixed values.',
70+
70,
71+
],
72+
[
73+
'In function "test8", return type is "array". Please provide a more specific @return annotation. For instance: @return int[]. Use @return mixed[] if this is really an array of mixed values.',
74+
70,
6775
],
6876
]);
6977
}

tests/Rules/TypeHints/data/typehints.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,21 @@ function mismatch(?string $param): string
5353
{
5454

5555
}
56+
57+
/**
58+
* @param mixed[] $any_array
59+
* @return mixed[]
60+
*/
61+
function test7(array $any_array): array
62+
{
63+
64+
}
65+
66+
/**
67+
* @param array $any_array
68+
* @return array
69+
*/
70+
function test8(array $any_array): array
71+
{
72+
73+
}

0 commit comments

Comments
 (0)