Skip to content

Commit 337b299

Browse files
authored
Fix mixed calls diagstics when custom excluder is used (#196)
1 parent 549f225 commit 337b299

File tree

7 files changed

+30
-32
lines changed

7 files changed

+30
-32
lines changed

rules.neon

-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ services:
1313

1414
-
1515
class: ShipMonk\PHPStan\DeadCode\Debug\DebugUsagePrinter
16-
arguments:
17-
mixedExcluderEnabled: %shipmonkDeadCode.usageExcluders.usageOverMixed.enabled%
1816

1917
-
2018
class: ShipMonk\PHPStan\DeadCode\Provider\VendorUsageProvider

src/Debug/DebugUsagePrinter.php

+17-18
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,14 @@ class DebugUsagePrinter
4444
*/
4545
private array $debugMembers;
4646

47-
private bool $mixedExcluderEnabled;
48-
4947
public function __construct(
5048
Container $container,
5149
OutputEnhancer $outputEnhancer,
52-
ReflectionProvider $reflectionProvider,
53-
bool $mixedExcluderEnabled
50+
ReflectionProvider $reflectionProvider
5451
)
5552
{
5653
$this->outputEnhancer = $outputEnhancer;
5754
$this->reflectionProvider = $reflectionProvider;
58-
$this->mixedExcluderEnabled = $mixedExcluderEnabled;
5955
$this->debugMembers = $this->buildDebugMemberKeys(
6056
// @phpstan-ignore offsetAccess.nonOffsetAccessible, offsetAccess.nonOffsetAccessible, missingType.checkedException, argument.type
6157
$container->getParameter('shipmonkDeadCode')['debug']['usagesOf'], // prevents https://github.com/phpstan/phpstan/issues/12740
@@ -71,31 +67,34 @@ public function printMixedMemberUsages(Output $output, array $mixedMemberUsages)
7167
return;
7268
}
7369

74-
$fullyMixedUsages = [];
70+
$mixedEverythingUsages = [];
71+
$mixedClassNameUsages = [];
7572

76-
foreach ($mixedMemberUsages as $memberType => $collectedUsages) {
77-
if (isset($collectedUsages[self::ANY_MEMBER])) {
78-
foreach ($collectedUsages[self::ANY_MEMBER] as $collectedUsage) {
79-
$fullyMixedUsages[$memberType][] = $collectedUsage;
80-
}
73+
foreach ($mixedMemberUsages as $memberType => $collectedUsagesByMemberName) {
74+
foreach ($collectedUsagesByMemberName as $memberName => $collectedUsages) {
75+
foreach ($collectedUsages as $collectedUsage) {
76+
if ($collectedUsage->isExcluded()) {
77+
continue;
78+
}
8179

82-
unset($mixedMemberUsages[$memberType][self::ANY_MEMBER]);
80+
if ($memberName === self::ANY_MEMBER) {
81+
$mixedEverythingUsages[$memberType][] = $collectedUsage;
82+
} else {
83+
$mixedClassNameUsages[$memberType][$memberName][] = $collectedUsage;
84+
}
85+
}
8386
}
8487
}
8588

86-
$this->printMixedEverythingUsages($output, $fullyMixedUsages);
87-
$this->printMixedClassNameUsages($output, $mixedMemberUsages);
89+
$this->printMixedEverythingUsages($output, $mixedEverythingUsages);
90+
$this->printMixedClassNameUsages($output, $mixedClassNameUsages);
8891
}
8992

9093
/**
9194
* @param array<MemberType::*, array<string, non-empty-list<CollectedUsage>>> $mixedMemberUsages
9295
*/
9396
private function printMixedClassNameUsages(Output $output, array $mixedMemberUsages): void
9497
{
95-
if ($this->mixedExcluderEnabled) {
96-
return;
97-
}
98-
9998
$totalCount = array_sum(array_map('count', $mixedMemberUsages));
10099

101100
if ($totalCount === 0) {

tests/Rule/DeadCodeRuleTest.php

+5-6
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ protected function getRule(): DeadCodeRule
9393
$container,
9494
$this->createOutputEnhancer(),
9595
self::createReflectionProvider(),
96-
!$this->trackMixedAccess,
9796
),
9897
new ClassHierarchy(),
9998
!$this->emitErrorsInGroups,
@@ -221,10 +220,10 @@ public function testDiagnoseMixedCalls(): void
221220
$ec = ''; // hack editorconfig checker to ignore wrong indentation
222221
$expectedOutput = <<<"OUTPUT"
223222
<fg=yellow>Found 4 usages over unknown type</>:
224-
$ec • <fg=white>getter1</> method, for example in <fg=white>data/methods/mixed/tracked.php:46</>
225-
$ec • <fg=white>getter2</> method, for example in <fg=white>data/methods/mixed/tracked.php:49</>
226-
$ec • <fg=white>getter3</> method, for example in <fg=white>data/methods/mixed/tracked.php:52</>
227-
$ec • <fg=white>staticMethod</> method, for example in <fg=white>data/methods/mixed/tracked.php:57</>
223+
$ec • <fg=white>getter1</> method, for example in <fg=white>data/methods/mixed/tracked.php:47</>
224+
$ec • <fg=white>getter2</> method, for example in <fg=white>data/methods/mixed/tracked.php:51</>
225+
$ec • <fg=white>getter3</> method, for example in <fg=white>data/methods/mixed/tracked.php:54</>
226+
$ec • <fg=white>staticMethod</> method, for example in <fg=white>data/methods/mixed/tracked.php:59</>
228227
229228
Thus, any member named the same is considered used, no matter its declaring class!
230229
@@ -856,7 +855,7 @@ private function getMemberUsageExcluders(): array
856855

857856
public function getIdentifier(): string
858857
{
859-
return 'mixed';
858+
return 'mixedPrefix';
860859
}
861860

862861
public function shouldExclude(ClassMemberUsage $usage, Node $node, Scope $scope): bool

tests/Rule/data/debug/exclude.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
class Foo
66
{
7-
public static function mixedExcluder1() {} // error: Unused DebugExclude\Foo::mixedExcluder1 (all usages excluded by mixed excluder)
8-
public static function mixedExcluder2() {} // error: Unused DebugExclude\Foo::mixedExcluder2 (all usages excluded by mixed excluder)
7+
public static function mixedExcluder1() {} // error: Unused DebugExclude\Foo::mixedExcluder1 (all usages excluded by mixedPrefix excluder)
8+
public static function mixedExcluder2() {} // error: Unused DebugExclude\Foo::mixedExcluder2 (all usages excluded by mixedPrefix excluder)
99
}
1010

1111
class Chld extends Foo {

tests/Rule/data/debug/expected_output.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ DebugExclude\Foo::mixedExcluder1
3939
| all usages are excluded
4040
|
4141
| Found 1 usage:
42-
| • data/debug/exclude.php:15 - excluded by mixed excluder
42+
| • data/debug/exclude.php:15 - excluded by mixedPrefix excluder
4343

4444

4545
DebugExclude\Foo::mixedExcluder2
@@ -48,7 +48,7 @@ DebugExclude\Foo::mixedExcluder2
4848
| all usages are excluded
4949
|
5050
| Found 1 usage:
51-
| • data/debug/exclude.php:16 - excluded by mixed excluder
51+
| • data/debug/exclude.php:16 - excluded by mixedPrefix excluder
5252

5353

5454
DebugNever\Foo::__get

tests/Rule/data/excluders/mixed/code.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
namespace MixedExcluder;
44

55
class SomeParent {
6-
public function mixed1() {} // error: Unused MixedExcluder\SomeParent::mixed1 (all usages excluded by mixed excluder)
6+
public function mixed1() {} // error: Unused MixedExcluder\SomeParent::mixed1 (all usages excluded by mixedPrefix excluder)
77
}
88

99
class Some extends SomeParent {
10-
public function mixed2() {} // error: Unused MixedExcluder\Some::mixed2 (all usages excluded by mixed excluder)
10+
public function mixed2() {} // error: Unused MixedExcluder\Some::mixed2 (all usages excluded by mixedPrefix excluder)
1111
}
1212

1313
function test(Some $some) {

tests/Rule/data/methods/mixed/tracked.php

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function getter3() {}
3636
public function getter4() {}
3737
public function getter5() {} // error: Unused DeadMixed1\Implementor::getter5
3838
public function getter6() {}
39+
public function mixedGetter7() {} // error: Unused DeadMixed1\Implementor::mixedGetter7 (all usages excluded by mixedPrefix excluder)
3940

4041
}
4142

@@ -44,6 +45,7 @@ class Tester
4445
function __construct($mixed, string $notClass, object $object, IFace $iface, int|Clazz $maybeClass)
4546
{
4647
$mixed->getter1(); // may be valid call
48+
$mixed->mixedGetter7(); // excluded call
4749

4850
if (!$mixed instanceof Clazz) {
4951
$mixed->getter2(); // ideally, should mark only IFace, not Clazz (not implemented)

0 commit comments

Comments
 (0)