Skip to content

Commit

Permalink
Check unresolvable types in @phpstan-self-out
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Aug 23, 2024
1 parent 0dfd821 commit e182c06
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/PhpDoc/StubValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ private function getRuleRegistry(Container $container): RuleRegistry
$container->getParameter('featureToggles')['invalidPhpDocTagLine'],
),
new IncompatibleParamImmediatelyInvokedCallableRule($fileTypeMapper),
new IncompatibleSelfOutTypeRule(),
new IncompatibleSelfOutTypeRule($unresolvableTypeHelper),
new IncompatibleClassConstantPhpDocTypeRule($genericObjectTypeCheck, $unresolvableTypeHelper),
new InvalidThrowsPhpDocValueRule($fileTypeMapper),

Expand Down
14 changes: 13 additions & 1 deletion src/Rules/PhpDoc/IncompatibleSelfOutTypeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
final class IncompatibleSelfOutTypeRule implements Rule
{

public function __construct(private UnresolvableTypeHelper $unresolvableTypeHelper)
{
}

public function getNodeType(): string
{
return InClassMethodNode::class;
Expand All @@ -39,7 +43,7 @@ public function processNode(Node $node, Scope $scope): array
$errors[] = RuleErrorBuilder::message(sprintf(
'Self-out type %s of method %s::%s is not subtype of %s.',
$selfOutType->describe(VerbosityLevel::precise()),
$classReflection->getName(),
$classReflection->getDisplayName(),
$method->getName(),
$classType->describe(VerbosityLevel::precise()),
))->identifier('selfOut.type')->build();
Expand All @@ -51,6 +55,14 @@ public function processNode(Node $node, Scope $scope): array
->build();
}

if ($this->unresolvableTypeHelper->containsUnresolvableType($selfOutType)) {
$errors[] = RuleErrorBuilder::message(sprintf(
'PHPDoc tag @phpstan-self-out for method %s::%s() contains unresolvable type.',
$classReflection->getDisplayName(),
$method->getName(),
))->identifier('parameter.unresolvableType')->build();
}

return $errors;
}

Expand Down
10 changes: 9 additions & 1 deletion tests/PHPStan/Rules/PhpDoc/IncompatibleSelfOutTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class IncompatibleSelfOutTypeRuleTest extends RuleTestCase

protected function getRule(): Rule
{
return new IncompatibleSelfOutTypeRule();
return new IncompatibleSelfOutTypeRule(new UnresolvableTypeHelper());
}

public function testRule(): void
Expand All @@ -31,6 +31,14 @@ public function testRule(): void
'PHPDoc tag @phpstan-self-out is not supported above static method IncompatibleSelfOutType\Foo::selfOutStatic().',
38,
],
[
'PHPDoc tag @phpstan-self-out for method IncompatibleSelfOutType\Foo::doFoo() contains unresolvable type.',
46,
],
[
'PHPDoc tag @phpstan-self-out for method IncompatibleSelfOutType\Foo::doBar() contains unresolvable type.',
54,
],
]);
}

Expand Down
16 changes: 16 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 @@ -40,4 +40,20 @@ public static function selfOutStatic(): void

}

/**
* @phpstan-self-out int&string
*/
public function doFoo(): void
{

}

/**
* @phpstan-self-out self<int&string>
*/
public function doBar(): void
{

}

}

0 comments on commit e182c06

Please sign in to comment.