Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,11 @@ parameters:
- %currentWorkingDirectory%/tests
```

With such setup, members used only in tests will be reported with corresponding message, e.g:
With such setup, members used only in tests will be reported with a corresponding tip, e.g:

```
Unused AddressValidator::isValidPostalCode (all usages excluded by tests excluder)
Unused AddressValidator::isValidPostalCode
💡 All usages excluded by tests excluder
```

> [!TIP]
Expand Down
6 changes: 3 additions & 3 deletions src/Error/BlackMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,16 @@ public function getErrorIdentifier(): string
}
}

public function getExclusionMessage(): string
public function getExclusionTip(): ?string
{
if (count($this->excludedUsages) === 0) {
return '';
return null;
}

$excluderNames = implode(', ', array_keys($this->excludedUsages));
$plural = count($this->excludedUsages) > 1 ? 's' : '';

return " (all usages excluded by {$excluderNames} excluder{$plural})";
return "All usages excluded by {$excluderNames} excluder{$plural}";
}

/**
Expand Down
16 changes: 12 additions & 4 deletions src/Rule/DeadCodeRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -839,12 +839,11 @@ private function buildError(array $blackMembersGroup): IdentifierRuleError
{
$representative = $blackMembersGroup[0];

$exclusionMessage = $representative->getExclusionMessage();
$excludedUsages = $representative->getExcludedUsages();

$mainErrorMessage = $this->buildMainErrorMessages($representative);

$builder = RuleErrorBuilder::message("{$mainErrorMessage}{$exclusionMessage}")
$builder = RuleErrorBuilder::message($mainErrorMessage)
->file($representative->getFile())
->line($representative->getLine())
->identifier($representative->getErrorIdentifier());
Expand All @@ -856,13 +855,22 @@ private function buildError(array $blackMembersGroup): IdentifierRuleError
'excludedUsages' => $excludedUsages,
];

$representativeExclusionTip = $representative->getExclusionTip();

if ($representativeExclusionTip !== null) {
$builder->addTip($representativeExclusionTip);
}

$tips = [];

foreach (array_slice($blackMembersGroup, 1) as $transitivelyDeadMember) {
$exclusionMessage = $transitivelyDeadMember->getExclusionMessage();
$exclusionTip = $transitivelyDeadMember->getExclusionTip();
$excludedUsages = $transitivelyDeadMember->getExcludedUsages();

$tips[] = $this->buildTransitiveErrorMessages($transitivelyDeadMember) . $exclusionMessage;
$transitiveMessage = $this->buildTransitiveErrorMessages($transitivelyDeadMember);
$tips[] = $exclusionTip !== null
? "{$transitiveMessage}. {$exclusionTip}"
: $transitiveMessage;
$metadata[] = [
'blackMember' => $transitivelyDeadMember,
'transitive' => true,
Expand Down
3 changes: 2 additions & 1 deletion tests/Rule/DeadCodeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,9 @@ public function testDebugUsageWithExcludedMixed(): void
$this->debugMembers = ['DebugMixed\Foo::any'];
$this->analyse([__DIR__ . '/data/debug/mixed.php'], [
[
'Unused DebugMixed\Foo::any (all usages excluded by usageOverMixed excluder)',
'Unused DebugMixed\Foo::any',
7,
'All usages excluded by usageOverMixed excluder',
],
]);
$rule = $this->getRule();
Expand Down
18 changes: 9 additions & 9 deletions tests/Rule/data/constants/mixed/untracked.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

class Clazz {

const CONST1 = 1; // error: Unused DeadConstMixed2\Clazz::CONST1 (all usages excluded by usageOverMixed excluder)
const CONST2 = 1; // error: Unused DeadConstMixed2\Clazz::CONST2 (all usages excluded by usageOverMixed excluder)
const CONST3 = 1; // error: Unused DeadConstMixed2\Clazz::CONST3 (all usages excluded by usageOverMixed excluder)
const CONST1 = 1; // error: Unused DeadConstMixed2\Clazz::CONST1
const CONST2 = 1; // error: Unused DeadConstMixed2\Clazz::CONST2
const CONST3 = 1; // error: Unused DeadConstMixed2\Clazz::CONST3
const CONST4 = 1; // error: Unused DeadConstMixed2\Clazz::CONST4
const CONST5 = 1;
const CONST6 = 1; // error: Unused DeadConstMixed2\Clazz::CONST6
Expand All @@ -18,19 +18,19 @@ class Clazz {

interface IFace {

const CONST1 = 1; // error: Unused DeadConstMixed2\IFace::CONST1 (all usages excluded by usageOverMixed excluder)
const CONST2 = 1; // error: Unused DeadConstMixed2\IFace::CONST2 (all usages excluded by usageOverMixed excluder)
const CONST3 = 1; // error: Unused DeadConstMixed2\IFace::CONST3 (all usages excluded by usageOverMixed excluder)
const CONST1 = 1; // error: Unused DeadConstMixed2\IFace::CONST1
const CONST2 = 1; // error: Unused DeadConstMixed2\IFace::CONST2
const CONST3 = 1; // error: Unused DeadConstMixed2\IFace::CONST3
const CONST4 = 1;
const CONST5 = 1; // error: Unused DeadConstMixed2\IFace::CONST5

}

class Implementor implements IFace {

const CONST1 = 1; // error: Unused DeadConstMixed2\Implementor::CONST1 (all usages excluded by usageOverMixed excluder)
const CONST2 = 1; // error: Unused DeadConstMixed2\Implementor::CONST2 (all usages excluded by usageOverMixed excluder)
const CONST3 = 1; // error: Unused DeadConstMixed2\Implementor::CONST3 (all usages excluded by usageOverMixed excluder)
const CONST1 = 1; // error: Unused DeadConstMixed2\Implementor::CONST1
const CONST2 = 1; // error: Unused DeadConstMixed2\Implementor::CONST2
const CONST3 = 1; // error: Unused DeadConstMixed2\Implementor::CONST3
const CONST4 = 1;
const CONST5 = 1; // error: Unused DeadConstMixed2\Implementor::CONST5
const CONST6 = 1;
Expand Down
4 changes: 2 additions & 2 deletions tests/Rule/data/debug/exclude.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

class Foo
{
public static function mixedExcluder1() {} // error: Unused DebugExclude\Foo::mixedExcluder1 (all usages excluded by mixedPrefix excluder)
public static function mixedExcluder2() {} // error: Unused DebugExclude\Foo::mixedExcluder2 (all usages excluded by mixedPrefix excluder)
public static function mixedExcluder1() {} // error: Unused DebugExclude\Foo::mixedExcluder1
public static function mixedExcluder2() {} // error: Unused DebugExclude\Foo::mixedExcluder2
}

class Chld extends Foo {
Expand Down
4 changes: 2 additions & 2 deletions tests/Rule/data/excluders/mixed/code.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
namespace MixedExcluder;

class SomeParent {
public function mixed1() {} // error: Unused MixedExcluder\SomeParent::mixed1 (all usages excluded by mixedPrefix excluder)
public function mixed1() {} // error: Unused MixedExcluder\SomeParent::mixed1
}

class Some extends SomeParent {
public function mixed2() {} // error: Unused MixedExcluder\Some::mixed2 (all usages excluded by mixedPrefix excluder)
public function mixed2() {} // error: Unused MixedExcluder\Some::mixed2
}

function test(Some $some) {
Expand Down
2 changes: 1 addition & 1 deletion tests/Rule/data/excluders/tests/src/code.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

class DeclaredInSrcUsedInTests {
const CONST = 1; // error: Unused DeclaredInSrcUsedInTests::CONST (all usages excluded by tests excluder)
const CONST = 1; // error: Unused DeclaredInSrcUsedInTests::CONST
const MIXED = 2;
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Rule/data/methods/mixed/tracked.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function getter3() {}
public function getter4() {}
public function getter5() {} // error: Unused DeadMixed1\Implementor::getter5
public function getter6() {}
public function mixedGetter7() {} // error: Unused DeadMixed1\Implementor::mixedGetter7 (all usages excluded by mixedPrefix excluder)
public function mixedGetter7() {} // error: Unused DeadMixed1\Implementor::mixedGetter7

}

Expand Down
20 changes: 10 additions & 10 deletions tests/Rule/data/methods/mixed/untracked.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,34 @@

class Clazz {

public function getter1() {} // error: Unused DeadMixed2\Clazz::getter1 (all usages excluded by usageOverMixed excluder)
public function getter2() {} // error: Unused DeadMixed2\Clazz::getter2 (all usages excluded by usageOverMixed excluder)
public function getter3() {} // error: Unused DeadMixed2\Clazz::getter3 (all usages excluded by usageOverMixed excluder)
public function getter1() {} // error: Unused DeadMixed2\Clazz::getter1
public function getter2() {} // error: Unused DeadMixed2\Clazz::getter2
public function getter3() {} // error: Unused DeadMixed2\Clazz::getter3
public function getter4() {} // error: Unused DeadMixed2\Clazz::getter4
public function getter5() {}
public function getter6() {} // error: Unused DeadMixed2\Clazz::getter6

public function someMethod() {} // error: Unused DeadMixed2\Clazz::someMethod
public function nonStaticMethod() {} // error: Unused DeadMixed2\Clazz::nonStaticMethod
public static function staticMethod() {} // error: Unused DeadMixed2\Clazz::staticMethod (all usages excluded by usageOverMixed excluder)
public static function staticMethod() {} // error: Unused DeadMixed2\Clazz::staticMethod

}

interface IFace {

public function getter1(); // error: Unused DeadMixed2\IFace::getter1 (all usages excluded by usageOverMixed excluder)
public function getter2(); // error: Unused DeadMixed2\IFace::getter2 (all usages excluded by usageOverMixed excluder)
public function getter3(); // error: Unused DeadMixed2\IFace::getter3 (all usages excluded by usageOverMixed excluder)
public function getter1(); // error: Unused DeadMixed2\IFace::getter1
public function getter2(); // error: Unused DeadMixed2\IFace::getter2
public function getter3(); // error: Unused DeadMixed2\IFace::getter3
public function getter4();
public function getter5(); // error: Unused DeadMixed2\IFace::getter5

}

class Implementor implements IFace {

public function getter1() {} // error: Unused DeadMixed2\Implementor::getter1 (all usages excluded by usageOverMixed excluder)
public function getter2() {} // error: Unused DeadMixed2\Implementor::getter2 (all usages excluded by usageOverMixed excluder)
public function getter3() {} // error: Unused DeadMixed2\Implementor::getter3 (all usages excluded by usageOverMixed excluder)
public function getter1() {} // error: Unused DeadMixed2\Implementor::getter1
public function getter2() {} // error: Unused DeadMixed2\Implementor::getter2
public function getter3() {} // error: Unused DeadMixed2\Implementor::getter3
public function getter4() {}
public function getter5() {} // error: Unused DeadMixed2\Implementor::getter5
public function getter6() {}
Expand Down
12 changes: 6 additions & 6 deletions tests/Rule/data/properties/mixed/untracked.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

class Clazz {

public string $prop1; // error: Property DeadPropertyMixed2\Clazz::$prop1 is never read (all usages excluded by usageOverMixed excluder) // error: Property DeadPropertyMixed2\Clazz::$prop1 is never written
public string $prop2; // error: Property DeadPropertyMixed2\Clazz::$prop2 is never read (all usages excluded by usageOverMixed excluder) // error: Property DeadPropertyMixed2\Clazz::$prop2 is never written
public string $prop3; // error: Property DeadPropertyMixed2\Clazz::$prop3 is never read (all usages excluded by usageOverMixed excluder) // error: Property DeadPropertyMixed2\Clazz::$prop3 is never written
public string $prop1; // error: Property DeadPropertyMixed2\Clazz::$prop1 is never read // error: Property DeadPropertyMixed2\Clazz::$prop1 is never written
public string $prop2; // error: Property DeadPropertyMixed2\Clazz::$prop2 is never read // error: Property DeadPropertyMixed2\Clazz::$prop2 is never written
public string $prop3; // error: Property DeadPropertyMixed2\Clazz::$prop3 is never read // error: Property DeadPropertyMixed2\Clazz::$prop3 is never written
public string $prop4; // error: Property DeadPropertyMixed2\Clazz::$prop4 is never read // error: Property DeadPropertyMixed2\Clazz::$prop4 is never written
public string $prop5; // error: Property DeadPropertyMixed2\Clazz::$prop5 is never written
public string $prop6; // error: Property DeadPropertyMixed2\Clazz::$prop6 is never read // error: Property DeadPropertyMixed2\Clazz::$prop6 is never written
Expand All @@ -22,9 +22,9 @@ interface IFace {

class Implementor implements IFace {

public string $prop1; // error: Property DeadPropertyMixed2\Implementor::$prop1 is never read (all usages excluded by usageOverMixed excluder) // error: Property DeadPropertyMixed2\Implementor::$prop1 is never written
public string $prop2; // error: Property DeadPropertyMixed2\Implementor::$prop2 is never read (all usages excluded by usageOverMixed excluder) // error: Property DeadPropertyMixed2\Implementor::$prop2 is never written
public string $prop3; // error: Property DeadPropertyMixed2\Implementor::$prop3 is never read (all usages excluded by usageOverMixed excluder) // error: Property DeadPropertyMixed2\Implementor::$prop3 is never written
public string $prop1; // error: Property DeadPropertyMixed2\Implementor::$prop1 is never read // error: Property DeadPropertyMixed2\Implementor::$prop1 is never written
public string $prop2; // error: Property DeadPropertyMixed2\Implementor::$prop2 is never read // error: Property DeadPropertyMixed2\Implementor::$prop2 is never written
public string $prop3; // error: Property DeadPropertyMixed2\Implementor::$prop3 is never read // error: Property DeadPropertyMixed2\Implementor::$prop3 is never written
public string $prop4; // error: Property DeadPropertyMixed2\Implementor::$prop4 is never written
public string $prop5; // error: Property DeadPropertyMixed2\Implementor::$prop5 is never read // error: Property DeadPropertyMixed2\Implementor::$prop5 is never written
public string $prop6; // error: Property DeadPropertyMixed2\Implementor::$prop6 is never written
Expand Down
2 changes: 1 addition & 1 deletion tests/Rule/data/providers/custom.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function __construct(

public function method(): void {}

public function mixedTestThatExcludersCanExcludeProvidedUsage(): void {} // error: Unused CustomProvider\Methods::mixedTestThatExcludersCanExcludeProvidedUsage (all usages excluded by mixedPrefix excluder)
public function mixedTestThatExcludersCanExcludeProvidedUsage(): void {} // error: Unused CustomProvider\Methods::mixedTestThatExcludersCanExcludeProvidedUsage
}

class Constants
Expand Down
Loading