Skip to content

Commit 41ab4a7

Browse files
committed
Fix
1 parent 414784c commit 41ab4a7

6 files changed

Lines changed: 156 additions & 22 deletions

File tree

src/Reflection/Native/NativeMethodReflection.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class NativeMethodReflection implements MethodReflection
2020

2121
private BuiltinMethodReflection $reflection;
2222

23-
/** @var \PHPStan\Reflection\ParametersAcceptor[] */
23+
/** @var \PHPStan\Reflection\ParametersAcceptorWithPhpDocs[] */
2424
private array $variants;
2525

2626
private TrinaryLogic $hasSideEffects;
@@ -31,7 +31,7 @@ class NativeMethodReflection implements MethodReflection
3131
* @param \PHPStan\Reflection\ReflectionProvider $reflectionProvider
3232
* @param \PHPStan\Reflection\ClassReflection $declaringClass
3333
* @param BuiltinMethodReflection $reflection
34-
* @param \PHPStan\Reflection\ParametersAcceptor[] $variants
34+
* @param \PHPStan\Reflection\ParametersAcceptorWithPhpDocs[] $variants
3535
* @param TrinaryLogic $hasSideEffects
3636
* @param string|null $stubPhpDocString
3737
*/
@@ -104,7 +104,7 @@ public function getName(): string
104104
}
105105

106106
/**
107-
* @return \PHPStan\Reflection\ParametersAcceptor[]
107+
* @return \PHPStan\Reflection\ParametersAcceptorWithPhpDocs[]
108108
*/
109109
public function getVariants(): array
110110
{
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Reflection\Native;
4+
5+
use PHPStan\Reflection\ParameterReflectionWithPhpDocs;
6+
use PHPStan\Reflection\PassedByReference;
7+
use PHPStan\Type\ArrayType;
8+
use PHPStan\Type\IntegerType;
9+
use PHPStan\Type\Type;
10+
11+
class NativeParameterWithPhpDocsReflection implements ParameterReflectionWithPhpDocs
12+
{
13+
14+
private string $name;
15+
16+
private bool $optional;
17+
18+
private \PHPStan\Type\Type $type;
19+
20+
private \PHPStan\Type\Type $phpDocType;
21+
22+
private \PHPStan\Type\Type $nativeType;
23+
24+
private \PHPStan\Reflection\PassedByReference $passedByReference;
25+
26+
private bool $variadic;
27+
28+
private ?\PHPStan\Type\Type $defaultValue;
29+
30+
private bool $variadicParameterAlreadyExpanded;
31+
32+
public function __construct(
33+
string $name,
34+
bool $optional,
35+
Type $type,
36+
Type $phpDocType,
37+
Type $nativeType,
38+
PassedByReference $passedByReference,
39+
bool $variadic,
40+
?Type $defaultValue,
41+
bool $variadicParameterAlreadyExpanded = false
42+
)
43+
{
44+
$this->name = $name;
45+
$this->optional = $optional;
46+
$this->type = $type;
47+
$this->phpDocType = $phpDocType;
48+
$this->nativeType = $nativeType;
49+
$this->passedByReference = $passedByReference;
50+
$this->variadic = $variadic;
51+
$this->defaultValue = $defaultValue;
52+
$this->variadicParameterAlreadyExpanded = $variadicParameterAlreadyExpanded;
53+
}
54+
55+
public function getName(): string
56+
{
57+
return $this->name;
58+
}
59+
60+
public function isOptional(): bool
61+
{
62+
return $this->optional;
63+
}
64+
65+
public function getType(): Type
66+
{
67+
$type = $this->type;
68+
if ($this->variadic && !$this->variadicParameterAlreadyExpanded) {
69+
$type = new ArrayType(new IntegerType(), $type);
70+
}
71+
72+
return $type;
73+
}
74+
75+
public function getPhpDocType(): Type
76+
{
77+
return $this->phpDocType;
78+
}
79+
80+
public function getNativeType(): Type
81+
{
82+
return $this->nativeType;
83+
}
84+
85+
public function passedByReference(): PassedByReference
86+
{
87+
return $this->passedByReference;
88+
}
89+
90+
public function isVariadic(): bool
91+
{
92+
return $this->variadic;
93+
}
94+
95+
public function getDefaultValue(): ?Type
96+
{
97+
return $this->defaultValue;
98+
}
99+
100+
/**
101+
* @param mixed[] $properties
102+
* @return self
103+
*/
104+
public static function __set_state(array $properties): self
105+
{
106+
return new self(
107+
$properties['name'],
108+
$properties['optional'],
109+
$properties['type'],
110+
$properties['phpDocType'],
111+
$properties['nativeType'],
112+
$properties['passedByReference'],
113+
$properties['variadic'],
114+
$properties['defaultValue']
115+
);
116+
}
117+
118+
}

src/Reflection/Php/PhpClassReflectionExtension.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
use PHPStan\Reflection\Annotations\AnnotationsMethodsClassReflectionExtension;
1919
use PHPStan\Reflection\Annotations\AnnotationsPropertiesClassReflectionExtension;
2020
use PHPStan\Reflection\ClassReflection;
21-
use PHPStan\Reflection\FunctionVariant;
21+
use PHPStan\Reflection\FunctionVariantWithPhpDocs;
2222
use PHPStan\Reflection\MethodReflection;
2323
use PHPStan\Reflection\MethodsClassReflectionExtension;
2424
use PHPStan\Reflection\Native\NativeMethodReflection;
25-
use PHPStan\Reflection\Native\NativeParameterReflection;
25+
use PHPStan\Reflection\Native\NativeParameterWithPhpDocsReflection;
2626
use PHPStan\Reflection\PropertiesClassReflectionExtension;
2727
use PHPStan\Reflection\PropertyReflection;
2828
use PHPStan\Reflection\ReflectionProvider;
@@ -444,22 +444,26 @@ private function createMethod(
444444
}
445445
}
446446
}
447-
$variants[] = new FunctionVariant(
447+
$variants[] = new FunctionVariantWithPhpDocs(
448448
TemplateTypeMap::createEmpty(),
449449
null,
450-
array_map(static function (ParameterSignature $parameterSignature) use ($stubPhpDocParameterTypes, $stubPhpDocParameterVariadicity): NativeParameterReflection {
451-
return new NativeParameterReflection(
450+
array_map(static function (ParameterSignature $parameterSignature) use ($stubPhpDocParameterTypes, $stubPhpDocParameterVariadicity): NativeParameterWithPhpDocsReflection {
451+
return new NativeParameterWithPhpDocsReflection(
452452
$parameterSignature->getName(),
453453
$parameterSignature->isOptional(),
454454
$stubPhpDocParameterTypes[$parameterSignature->getName()] ?? $parameterSignature->getType(),
455+
$stubPhpDocParameterTypes[$parameterSignature->getName()] ?? new MixedType(),
456+
new MixedType(true), // todo
455457
$parameterSignature->passedByReference(),
456458
$stubPhpDocParameterVariadicity[$parameterSignature->getName()] ?? $parameterSignature->isVariadic(),
457459
null,
458460
isset($stubPhpDocParameterTypes[$parameterSignature->getName()])
459461
);
460462
}, $methodSignature->getParameters()),
461463
$methodSignature->isVariadic(),
462-
$phpDocReturnType ?? $methodSignature->getReturnType()
464+
$phpDocReturnType ?? $methodSignature->getReturnType(),
465+
$phpDocReturnType ?? new MixedType(),
466+
new MixedType(true) // todo $methodSignature->getNativeReturnType()
463467
);
464468
}
465469

src/Rules/Methods/OverridingMethodRule.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
use PHPStan\Php\PhpVersion;
99
use PHPStan\Reflection\FunctionVariantWithPhpDocs;
1010
use PHPStan\Reflection\MethodPrototypeReflection;
11-
use PHPStan\Reflection\Native\NativeParameterReflection;
11+
use PHPStan\Reflection\ParameterReflectionWithPhpDocs;
1212
use PHPStan\Reflection\ParametersAcceptorSelector;
1313
use PHPStan\Reflection\Php\PhpMethodFromParserNodeReflection;
14-
use PHPStan\Reflection\Php\PhpParameterReflection;
1514
use PHPStan\Rules\Rule;
1615
use PHPStan\Rules\RuleErrorBuilder;
1716
use PHPStan\Type\ArrayType;
@@ -212,14 +211,12 @@ public function processNode(Node $node, Scope $scope): array
212211

213212
$methodParameterType = $methodParameter->getNativeType();
214213

215-
if ($prototypeParameter instanceof PhpParameterReflection) {
216-
$prototypeParameterType = $prototypeParameter->getNativeType();
217-
} elseif ($prototypeParameter instanceof NativeParameterReflection) {
218-
$prototypeParameterType = $prototypeParameter->getType();
219-
} else {
214+
if (!$prototypeParameter instanceof ParameterReflectionWithPhpDocs) {
220215
continue;
221216
}
222217

218+
$prototypeParameterType = $prototypeParameter->getNativeType();
219+
223220
if ($this->isTypeCompatible($methodParameterType, $prototypeParameterType, $this->phpVersion->supportsParameterContravariance())) {
224221
continue;
225222
}
@@ -279,12 +276,12 @@ public function processNode(Node $node, Scope $scope): array
279276

280277
$methodReturnType = $methodVariant->getNativeReturnType();
281278

282-
if ($prototypeVariant instanceof FunctionVariantWithPhpDocs) {
283-
$prototypeReturnType = $prototypeVariant->getNativeReturnType();
284-
} else {
285-
$prototypeReturnType = $prototypeVariant->getReturnType();
279+
if (!$prototypeVariant instanceof FunctionVariantWithPhpDocs) {
280+
return $messages;
286281
}
287282

283+
$prototypeReturnType = $prototypeVariant->getNativeReturnType();
284+
288285
if (!$this->isTypeCompatible($prototypeReturnType, $methodReturnType, $this->phpVersion->supportsReturnCovariance())) {
289286
if ($this->phpVersion->supportsReturnCovariance()) {
290287
$messages[] = RuleErrorBuilder::message(sprintf(

tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public function testOverridingFinalMethod(int $phpVersion, string $message): voi
8080
115,
8181
],
8282
[
83-
'Parameter #1 $size (string) of method OverridingFinalMethod\FixedArray::setSize() is not ' . $message . ' with parameter #1 $size (int) of method SplFixedArray::setSize().',
83+
'Parameter #1 $size (int) of method OverridingFinalMethod\FixedArray::setSize() is not ' . $message . ' with parameter #1 $size (mixed) of method SplFixedArray::setSize().',
8484
125,
8585
],
8686
[

tests/PHPStan/Rules/Methods/data/overriding-method.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public function doFoo()
122122
class FixedArray extends \SplFixedArray
123123
{
124124

125-
public function setSize(string $size): bool
125+
public function setSize(int $size): bool
126126
{
127127

128128
}
@@ -238,3 +238,18 @@ public function doFoo(int $i, int $j = null)
238238
}
239239

240240
}
241+
242+
/**
243+
* @implements \IteratorAggregate<int, Foo>
244+
*/
245+
class SomeIterator implements \IteratorAggregate
246+
{
247+
/**
248+
* @return \Traversable<int, Foo>
249+
*/
250+
public function getIterator()
251+
{
252+
yield new Foo;
253+
}
254+
255+
}

0 commit comments

Comments
 (0)