Skip to content

Commit

Permalink
Do not allow @phpstan-self-out above static method
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Aug 23, 2024
1 parent 04e5009 commit 0dfd821
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -2649,7 +2649,7 @@ static function (): void {
$nodeCallback(new InvalidateExprNode($expr->var), $scope);
$scope = $scope->invalidateExpression($expr->var, true);
}
if ($parametersAcceptor !== null) {
if ($parametersAcceptor !== null && !$methodReflection->isStatic()) {
$selfOutType = $methodReflection->getSelfOutType();
if ($selfOutType !== null) {
$scope = $scope->assignExpression(
Expand Down
21 changes: 13 additions & 8 deletions src/Rules/PhpDoc/IncompatibleSelfOutTypeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,24 @@ public function processNode(Node $node, Scope $scope): array
$classReflection = $method->getDeclaringClass();
$classType = new ObjectType($classReflection->getName(), null, $classReflection);

if ($classType->isSuperTypeOf($selfOutType)->yes()) {
return [];
}

return [
RuleErrorBuilder::message(sprintf(
$errors = [];
if (!$classType->isSuperTypeOf($selfOutType)->yes()) {
$errors[] = RuleErrorBuilder::message(sprintf(
'Self-out type %s of method %s::%s is not subtype of %s.',
$selfOutType->describe(VerbosityLevel::precise()),
$classReflection->getName(),
$method->getName(),
$classType->describe(VerbosityLevel::precise()),
))->identifier('selfOut.type')->build(),
];
))->identifier('selfOut.type')->build();
}

if ($method->isStatic()) {
$errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-self-out is not supported above static method %s::%s().', $classReflection->getName(), $method->getName()))
->identifier('selfOut.static')
->build();
}

return $errors;
}

}
11 changes: 11 additions & 0 deletions tests/PHPStan/Analyser/nsrt/self-out.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ public function setData($data) {
*/
public function test(): void {
}

/**
* @phpstan-self-out self<false>
*/
public static function selfOutWithStaticMethod(): void
{

}
}

/**
Expand Down Expand Up @@ -94,4 +102,7 @@ function () {

$i->setData(true);
assertType('SelfOut\\a<true>', $i);

$i->selfOutWithStaticMethod();
assertType('SelfOut\\a<true>', $i);
};
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public function testRule(): void
'Self-out type IncompatibleSelfOutType\A|null of method IncompatibleSelfOutType\A::four is not subtype of IncompatibleSelfOutType\A.',
28,
],
[
'PHPDoc tag @phpstan-self-out is not supported above static method IncompatibleSelfOutType\Foo::selfOutStatic().',
38,
],
]);
}

Expand Down
14 changes: 14 additions & 0 deletions tests/PHPStan/Rules/PhpDoc/data/incompatible-self-out-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,17 @@ public function three();
*/
public function four();
}

/**
* @template T
*/
class Foo
{

/** @phpstan-self-out self<int> */
public static function selfOutStatic(): void
{

}

}

0 comments on commit 0dfd821

Please sign in to comment.