Skip to content

Commit 0dfd821

Browse files
committed
Do not allow @phpstan-self-out above static method
1 parent 04e5009 commit 0dfd821

File tree

5 files changed

+43
-9
lines changed

5 files changed

+43
-9
lines changed

Diff for: src/Analyser/NodeScopeResolver.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2649,7 +2649,7 @@ static function (): void {
26492649
$nodeCallback(new InvalidateExprNode($expr->var), $scope);
26502650
$scope = $scope->invalidateExpression($expr->var, true);
26512651
}
2652-
if ($parametersAcceptor !== null) {
2652+
if ($parametersAcceptor !== null && !$methodReflection->isStatic()) {
26532653
$selfOutType = $methodReflection->getSelfOutType();
26542654
if ($selfOutType !== null) {
26552655
$scope = $scope->assignExpression(

Diff for: src/Rules/PhpDoc/IncompatibleSelfOutTypeRule.php

+13-8
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,24 @@ public function processNode(Node $node, Scope $scope): array
3434
$classReflection = $method->getDeclaringClass();
3535
$classType = new ObjectType($classReflection->getName(), null, $classReflection);
3636

37-
if ($classType->isSuperTypeOf($selfOutType)->yes()) {
38-
return [];
39-
}
40-
41-
return [
42-
RuleErrorBuilder::message(sprintf(
37+
$errors = [];
38+
if (!$classType->isSuperTypeOf($selfOutType)->yes()) {
39+
$errors[] = RuleErrorBuilder::message(sprintf(
4340
'Self-out type %s of method %s::%s is not subtype of %s.',
4441
$selfOutType->describe(VerbosityLevel::precise()),
4542
$classReflection->getName(),
4643
$method->getName(),
4744
$classType->describe(VerbosityLevel::precise()),
48-
))->identifier('selfOut.type')->build(),
49-
];
45+
))->identifier('selfOut.type')->build();
46+
}
47+
48+
if ($method->isStatic()) {
49+
$errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-self-out is not supported above static method %s::%s().', $classReflection->getName(), $method->getName()))
50+
->identifier('selfOut.static')
51+
->build();
52+
}
53+
54+
return $errors;
5055
}
5156

5257
}

Diff for: tests/PHPStan/Analyser/nsrt/self-out.php

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public function setData($data) {
5050
*/
5151
public function test(): void {
5252
}
53+
54+
/**
55+
* @phpstan-self-out self<false>
56+
*/
57+
public static function selfOutWithStaticMethod(): void
58+
{
59+
60+
}
5361
}
5462

5563
/**
@@ -94,4 +102,7 @@ function () {
94102

95103
$i->setData(true);
96104
assertType('SelfOut\\a<true>', $i);
105+
106+
$i->selfOutWithStaticMethod();
107+
assertType('SelfOut\\a<true>', $i);
97108
};

Diff for: tests/PHPStan/Rules/PhpDoc/IncompatibleSelfOutTypeRuleTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public function testRule(): void
2727
'Self-out type IncompatibleSelfOutType\A|null of method IncompatibleSelfOutType\A::four is not subtype of IncompatibleSelfOutType\A.',
2828
28,
2929
],
30+
[
31+
'PHPDoc tag @phpstan-self-out is not supported above static method IncompatibleSelfOutType\Foo::selfOutStatic().',
32+
38,
33+
],
3034
]);
3135
}
3236

Diff for: tests/PHPStan/Rules/PhpDoc/data/incompatible-self-out-type.php

+14
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ public function three();
2727
*/
2828
public function four();
2929
}
30+
31+
/**
32+
* @template T
33+
*/
34+
class Foo
35+
{
36+
37+
/** @phpstan-self-out self<int> */
38+
public static function selfOutStatic(): void
39+
{
40+
41+
}
42+
43+
}

0 commit comments

Comments
 (0)