Skip to content

Commit

Permalink
Merge pull request #895 from ergebnis/fix/annotation
Browse files Browse the repository at this point in the history
Fix: Do not require methods with `phpunit/phpunit` annotations to be `private`
  • Loading branch information
localheinz authored Jan 7, 2025
2 parents 117fe51 + 778beac commit 5380c1c
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ For a full diff see [`2.5.0...main`][2.5.0...main].
- Adjusted `Methods\PrivateInFinalClassRule` to use more appropriate message when detecting a `protected` method in an anonymous class ([#890]), by [@localheinz]
- Adjusted `Methods\PrivateInFinalClassRule` to ignore `protected` methods from traits ([#891]), by [@localheinz]
- Adjusted `Methods\PrivateInFinalClassRule` to ignore `protected` methods with `phpunit/phpunit` attributes requiring methods to be `protected` ([#863]), by [@cosmastech]
- Adjusted `Methods\PrivateInFinalClassRule` to ignore `protected` methods with `phpunit/phpunit` annotations requiring methods to be `protected` ([#895]), by [@cosmastech]

## [`2.5.0`][2.5.0]

Expand Down Expand Up @@ -558,6 +559,7 @@ For a full diff see [`362c7ea...0.1.0`][362c7ea...0.1.0].
[#889]: https://github.com/ergebnis/phpstan-rules/pull/889
[#890]: https://github.com/ergebnis/phpstan-rules/pull/890
[#891]: https://github.com/ergebnis/phpstan-rules/pull/891
[#895]: https://github.com/ergebnis/phpstan-rules/pull/895

[@enumag]: https://github.com/enumag
[@cosmastech]: https://github.com/cosmastech
Expand Down
1 change: 1 addition & 0 deletions composer-require-checker.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"PHPStan\\Rules\\Rule",
"PHPStan\\Rules\\RuleError",
"PHPStan\\Rules\\RuleErrorBuilder",
"PHPStan\\Type\\FileTypeMapper",
"PHPUnit\\Framework\\Attributes\\After",
"PHPUnit\\Framework\\Attributes\\Before",
"PHPUnit\\Framework\\Attributes\\PostCondition",
Expand Down
49 changes: 49 additions & 0 deletions src/Methods/PrivateInFinalClassRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,26 @@
namespace Ergebnis\PHPStan\Rules\Methods;

use Ergebnis\PHPStan\Rules\ErrorIdentifier;
use PhpParser\Comment;
use PhpParser\Node;
use PHPStan\Analyser;
use PHPStan\Reflection;
use PHPStan\Rules;
use PHPStan\Type;
use PHPUnit\Framework;

/**
* @implements Rules\Rule<Node\Stmt\ClassMethod>
*/
final class PrivateInFinalClassRule implements Rules\Rule
{
private Type\FileTypeMapper $fileTypeMapper;

public function __construct(Type\FileTypeMapper $fileTypeMapper)
{
$this->fileTypeMapper = $fileTypeMapper;
}

public function getNodeType(): string
{
return Node\Stmt\ClassMethod::class;
Expand All @@ -49,6 +58,10 @@ public function processNode(
return [];
}

if ($this->methodHasPhpUnitAnnotationWhichRequiresProtectedVisibility($node, $containingClass)) {
return [];
}

if (self::methodHasPhpUnitAttributeWhichRequiresProtectedVisibility($node)) {
return [];
}
Expand Down Expand Up @@ -92,6 +105,42 @@ public function processNode(
];
}

private function methodHasPhpUnitAnnotationWhichRequiresProtectedVisibility(
Node\Stmt\ClassMethod $node,
Reflection\ClassReflection $containingClass
): bool {
$docComment = $node->getDocComment();

if (!$docComment instanceof Comment\Doc) {
return false;
}

$resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc(
null,
$containingClass->getName(),
null,
null,
$docComment->getText(),
);

$annotations = [
'@after',
'@before',
'@postCondition',
'@preCondition',
];

foreach ($resolvedPhpDoc->getPhpDocNodes() as $phpDocNode) {
foreach ($phpDocNode->getTags() as $tag) {
if (\in_array($tag->name, $annotations, true)) {
return true;
}
}
}

return false;
}

private static function methodHasPhpUnitAttributeWhichRequiresProtectedVisibility(Node\Stmt\ClassMethod $node): bool
{
$attributes = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Ergebnis\PHPStan\Rules\Test\Fixture\Methods\PrivateInFinalClassRule;

use PHPUnit\Framework;

final class FinalClassWithProtectedMethodsWithPhpUnitAnnotations extends Framework\TestCase
{
/**
* @after
*/
protected function methodWithAfterAnnotation(): void
{
}

/**
* @before
*/
protected function methodWithBeforeAnnotation(): void
{
}

/**
* @preCondition
*/
protected function methodWithPreConditionAnnotation(): void
{
}

/**
* @postCondition
*/
protected function methodWithPostConditionAnnotation(): void
{
}
}
5 changes: 4 additions & 1 deletion test/Integration/Methods/PrivateInFinalClassRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Ergebnis\PHPStan\Rules\Test;
use PHPStan\Rules;
use PHPStan\Testing;
use PHPStan\Type;

/**
* @covers \Ergebnis\PHPStan\Rules\Methods\PrivateInFinalClassRule
Expand Down Expand Up @@ -51,6 +52,8 @@ public function testPrivateInFinalClassRule(): void

protected function getRule(): Rules\Rule
{
return new Methods\PrivateInFinalClassRule();
$fileTypeMapper = self::getContainer()->getByType(Type\FileTypeMapper::class);

return new Methods\PrivateInFinalClassRule($fileTypeMapper);
}
}

0 comments on commit 5380c1c

Please sign in to comment.