Skip to content

Commit

Permalink
Fix union-type handling in PublicStaticPropertyFetchCollector (#121)
Browse files Browse the repository at this point in the history
* Fix union-type handling in PublicStaticPropertyFetchCollector

* another test

* fix namespace

* Update UnusedPublicPropertyRuleTest.php
  • Loading branch information
staabm authored Jul 15, 2024
1 parent da62379 commit 5da0ca6
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 9 deletions.
33 changes: 24 additions & 9 deletions src/Collectors/PublicStaticPropertyFetchCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use PhpParser\Node\Name;
use PHPStan\Analyser\Scope;
use PHPStan\Collectors\Collector;
use PHPStan\Reflection\ClassReflection;
use TomasVotruba\UnusedPublic\ClassTypeDetector;
use TomasVotruba\UnusedPublic\Configuration;

/**
Expand All @@ -18,7 +20,8 @@
final readonly class PublicStaticPropertyFetchCollector implements Collector
{
public function __construct(
private Configuration $configuration
private Configuration $configuration,
private ClassTypeDetector $classTypeDetector,
) {
}

Expand All @@ -33,26 +36,38 @@ public function getNodeType(): string
*/
public function processNode(Node $node, Scope $scope): ?array
{
if (! $this->configuration->isUnusedPropertyEnabled()) {
if (!$this->configuration->isUnusedPropertyEnabled()) {
return null;
}

if (! $node->class instanceof Name) {
if (!$node->name instanceof Identifier) {
return null;
}

if (! $node->name instanceof Identifier) {
if (
$node->class instanceof Name
&& ($node->class->toString() === 'self' || $node->class->toString() === 'static')
) {
// self fetch is allowed
return null;
}

if ($node->class->toString() === 'self') {
// self fetch is allowed
$classReflection = $scope->getClassReflection();
if ($classReflection instanceof ClassReflection && $this->classTypeDetector->isTestClass($classReflection)) {
return null;
}

$className = $node->class->toString();
$propertyName = $node->name->toString();
if ($node->class instanceof Name) {
$classType = $scope->resolveTypeByName($node->class);
} else {
$classType = $scope->getType($node->class);
}
$result = [];
foreach($classType->getObjectClassNames() as $className) {
$propertyName = $node->name->toString();
$result[] = $className . '::' . $propertyName;
}

return [$className . '::' . $propertyName];
return $result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Fixture;

final class StaticUsedInTestCaseOnly
{
static public $property = 'public static';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Rules\UnusedPublicPropertyRule\Fixture;

class StaticUsedInUnionA {
static public float $amount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Rules\UnusedPublicPropertyRule\Fixture;

class StaticUsedInUnionB {
static public float $amount;
}
13 changes: 13 additions & 0 deletions tests/Rules/UnusedPublicPropertyRule/Source/StaticUsedInUnion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Source;

use Rules\UnusedPublicPropertyRule\Fixture\StaticUsedInUnionA;
use Rules\UnusedPublicPropertyRule\Fixture\StaticUsedInUnionB;

function doFooBar(StaticUsedInUnionA|StaticUsedInUnionB $aOrB): void {
echo $aOrB::$amount;
}

4 changes: 4 additions & 0 deletions tests/Rules/UnusedPublicPropertyRule/Source/TestCaseUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Source;

use PHPUnit\Framework\TestCase;
use Rules\UnusedPublicPropertyRule\Fixture\StaticUsedInTestCaseOnly;
use TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Fixture\UsedInTestCaseOnly;

final class TestCaseUser extends TestCase
Expand All @@ -13,5 +14,8 @@ private function go()
{
$o = new UsedInTestCaseOnly();
$o->property = 'a value';

$o = new StaticUsedInTestCaseOnly();
$o::$property = 'a value';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Fixture\LocallyUsedStaticPropertyViaStatic;
use TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Fixture\LocalyUsedPublicProperty;
use TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Fixture\UsedInTestCaseOnly;
use TomasVotruba\UnusedPublic\Tests\Rules\UnusedPublicPropertyRule\Fixture\StaticUsedInTestCaseOnly;

final class UnusedPublicPropertyRuleTest extends RuleTestCase
{
Expand Down Expand Up @@ -99,6 +100,12 @@ public static function provideData(): Iterator
[[$errorMessage1, 7, RuleTips::SOLUTION_MESSAGE]],
];

$errorMessage1 = sprintf(UnusedPublicPropertyRule::ERROR_MESSAGE, StaticUsedInTestCaseOnly::class, 'property');
yield [
[__DIR__ . '/Fixture/StaticUsedInTestCaseOnly.php', __DIR__ . '/Source/TestCaseUser.php'],
[[$errorMessage1, 7, RuleTips::SOLUTION_MESSAGE]],
];

yield [[__DIR__ . '/Fixture/plain.php', __DIR__ . '/Source/PublicPropertyClass.php'], []];

yield [
Expand All @@ -112,6 +119,7 @@ public static function provideData(): Iterator

yield [[__DIR__ . '/Fixture/UsedInUnionA.php', __DIR__ . '/Fixture/UsedInUnionB.php', __DIR__ . '/Source/UsedInUnion.php'], []];
yield [[__DIR__ . '/Fixture/UsedInUnionA.php', __DIR__ . '/Fixture/UsedInUnionB.php', __DIR__ . '/Source/UsedInUnionPhpdoc.php'], []];
yield [[__DIR__ . '/Fixture/StaticUsedInUnionA.php', __DIR__ . '/Fixture/StaticUsedInUnionB.php', __DIR__ . '/Source/StaticUsedInUnion.php'], []];

}

Expand Down

0 comments on commit 5da0ca6

Please sign in to comment.