Skip to content

Commit 6838669

Browse files
committed
Bleeding edge - check existing classes in @phpstan-self-out
1 parent 7fc5ab8 commit 6838669

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

src/Rules/FunctionDefinitionCheck.php

+34-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public function checkClassMethod(
246246
/** @var ParametersAcceptorWithPhpDocs $parametersAcceptor */
247247
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
248248

249-
return $this->checkParametersAcceptor(
249+
$errors = $this->checkParametersAcceptor(
250250
$parametersAcceptor,
251251
$methodNode,
252252
$parameterMessage,
@@ -256,6 +256,39 @@ public function checkClassMethod(
256256
$unresolvableParameterTypeMessage,
257257
$unresolvableReturnTypeMessage,
258258
);
259+
260+
$selfOutType = $methodReflection->getSelfOutType();
261+
if ($selfOutType !== null && $this->absentTypeChecks) {
262+
$selfOutTypeReferencedClasses = $selfOutType->getReferencedClasses();
263+
264+
foreach ($selfOutTypeReferencedClasses as $class) {
265+
if (!$this->reflectionProvider->hasClass($class)) {
266+
$errors[] = RuleErrorBuilder::message(sprintf($returnMessage, $class))
267+
->line($methodNode->getStartLine())
268+
->identifier('class.notFound')
269+
->build();
270+
continue;
271+
}
272+
if (!$this->reflectionProvider->getClass($class)->isTrait()) {
273+
continue;
274+
}
275+
276+
$errors[] = RuleErrorBuilder::message(sprintf($returnMessage, $class))
277+
->line($methodNode->getStartLine())
278+
->identifier('selfOut.trait')
279+
->build();
280+
}
281+
282+
$errors = array_merge(
283+
$errors,
284+
$this->classCheck->checkClassNames(
285+
array_map(static fn (string $class): ClassNameNodePair => new ClassNameNodePair($class, $methodNode), $selfOutTypeReferencedClasses),
286+
$this->checkClassCaseSensitivity,
287+
),
288+
);
289+
}
290+
291+
return $errors;
259292
}
260293

261294
/**

tests/PHPStan/Rules/Methods/ExistingClassesInTypehintsRuleTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -508,4 +508,22 @@ public function testParamClosureThisClasses(): void
508508
]);
509509
}
510510

511+
public function testSelfOut(): void
512+
{
513+
$this->analyse([__DIR__ . '/data/self-out.php'], [
514+
[
515+
'Method SelfOutClasses\Foo::doFoo() has invalid return type SelfOutClasses\Nonexistent.',
516+
16,
517+
],
518+
[
519+
'Method SelfOutClasses\Foo::doBar() has invalid return type SelfOutClasses\FooTrait.',
520+
24,
521+
],
522+
[
523+
'Class SelfOutClasses\Foo referenced with incorrect case: SelfOutClasses\fOO.',
524+
32,
525+
],
526+
]);
527+
}
528+
511529
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace SelfOutClasses;
4+
5+
trait FooTrait
6+
{
7+
8+
}
9+
10+
class Foo
11+
{
12+
13+
/**
14+
* @phpstan-self-out Nonexistent
15+
*/
16+
public function doFoo(): void
17+
{
18+
19+
}
20+
21+
/**
22+
* @phpstan-self-out FooTrait
23+
*/
24+
public function doBar(): void
25+
{
26+
27+
}
28+
29+
/**
30+
* @phpstan-self-out fOO
31+
*/
32+
public function doBaz(): void
33+
{
34+
35+
}
36+
37+
}

0 commit comments

Comments
 (0)