Skip to content

Commit 58da2ff

Browse files
authored
Fix unused class ignores (#39)
1 parent fe882e6 commit 58da2ff

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

src/Analyser.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ public function run(): AnalysisResult
130130
if (!$this->isInClassmap($usedSymbol)) {
131131
if (
132132
!$this->isConstOrFunction($usedSymbol)
133-
&& !$ignoreList->shouldIgnoreUnknownClass($usedSymbol)
134-
&& !$ignoreList->shouldIgnoreError(ErrorType::UNKNOWN_CLASS, $filePath, null)
133+
&& !$ignoreList->shouldIgnoreUnknownClass($usedSymbol, $filePath)
135134
) {
136135
foreach ($lineNumbers as $lineNumber) {
137136
$classmapErrors[$usedSymbol][] = new SymbolUsage($filePath, $lineNumber);

src/Config/Ignore/IgnoreList.php

+17-2
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,28 @@ public function getUnusedIgnores(): array
132132
return $unused;
133133
}
134134

135-
public function shouldIgnoreUnknownClass(string $class): bool
135+
public function shouldIgnoreUnknownClass(string $class, string $filePath): bool
136+
{
137+
$ignoredGlobally = $this->shouldIgnoreErrorGlobally(ErrorType::UNKNOWN_CLASS);
138+
$ignoredByPath = $this->shouldIgnoreErrorOnPath(ErrorType::UNKNOWN_CLASS, $filePath);
139+
$ignoredByRegex = $this->shouldIgnoreUnknownClassByRegex($class);
140+
$ignoredByBlacklist = $this->shouldIgnoreUnknownClassByBlacklist($class);
141+
142+
return $ignoredGlobally || $ignoredByPath || $ignoredByRegex || $ignoredByBlacklist;
143+
}
144+
145+
private function shouldIgnoreUnknownClassByBlacklist(string $class): bool
136146
{
137147
if (isset($this->ignoredUnknownClasses[$class])) {
138148
$this->ignoredUnknownClasses[$class] = true;
139149
return true;
140150
}
141151

152+
return false;
153+
}
154+
155+
private function shouldIgnoreUnknownClassByRegex(string $class): bool
156+
{
142157
foreach ($this->ignoredUnknownClassesRegexes as $regex => $ignoreUsed) {
143158
$matches = preg_match($regex, $class);
144159

@@ -156,7 +171,7 @@ public function shouldIgnoreUnknownClass(string $class): bool
156171
}
157172

158173
/**
159-
* @param ErrorType::* $errorType
174+
* @param ErrorType::SHADOW_DEPENDENCY|ErrorType::UNUSED_DEPENDENCY|ErrorType::DEV_DEPENDENCY_IN_PROD|ErrorType::PROD_DEPENDENCY_ONLY_IN_DEV $errorType
160175
*/
161176
public function shouldIgnoreError(string $errorType, ?string $realPath, ?string $packageName): bool
162177
{

tests/ConfigurationTest.php

+47-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPUnit\Framework\TestCase;
66
use ShipMonk\ComposerDependencyAnalyser\Config\Configuration;
77
use ShipMonk\ComposerDependencyAnalyser\Config\ErrorType;
8+
use ShipMonk\ComposerDependencyAnalyser\Config\Ignore\UnusedClassIgnore;
89
use ShipMonk\ComposerDependencyAnalyser\Config\Ignore\UnusedErrorIgnore;
910
use ShipMonk\ComposerDependencyAnalyser\Exception\InvalidConfigException;
1011
use ShipMonk\ComposerDependencyAnalyser\Exception\InvalidPathException;
@@ -17,13 +18,18 @@ class ConfigurationTest extends TestCase
1718
public function testShouldIgnore(): void
1819
{
1920
$configuration = new Configuration();
20-
$configuration->ignoreErrors([ErrorType::UNUSED_DEPENDENCY]);
21+
$configuration->ignoreUnknownClasses(['Unknown\Clazz']);
22+
$configuration->ignoreErrors([ErrorType::UNUSED_DEPENDENCY, ErrorType::UNKNOWN_CLASS]);
2123
$configuration->ignoreErrorsOnPath(__DIR__ . '/app/../', [ErrorType::SHADOW_DEPENDENCY]);
2224
$configuration->ignoreErrorsOnPackage('my/package', [ErrorType::PROD_DEPENDENCY_ONLY_IN_DEV]);
2325
$configuration->ignoreErrorsOnPackageAndPath('vendor/package', __DIR__ . '/../tests/app', [ErrorType::DEV_DEPENDENCY_IN_PROD]);
2426

2527
$ignoreList = $configuration->getIgnoreList();
2628

29+
self::assertTrue($ignoreList->shouldIgnoreUnknownClass('Unknown\Clazz', __DIR__));
30+
self::assertTrue($ignoreList->shouldIgnoreUnknownClass('Unknown\Clazz', __DIR__ . '/app'));
31+
self::assertTrue($ignoreList->shouldIgnoreUnknownClass('Any\Clazz', __DIR__));
32+
2733
self::assertTrue($ignoreList->shouldIgnoreError(ErrorType::UNUSED_DEPENDENCY, null, null));
2834
self::assertTrue($ignoreList->shouldIgnoreError(ErrorType::UNUSED_DEPENDENCY, null, 'some/package'));
2935
self::assertTrue($ignoreList->shouldIgnoreError(ErrorType::UNUSED_DEPENDENCY, __DIR__, null));
@@ -87,6 +93,46 @@ public function testOverlappingUnusedIgnores(): void
8793
], $ignoreList3->getUnusedIgnores());
8894
}
8995

96+
public function testOverlappingUnusedIgnoresOfUnknownClass(): void
97+
{
98+
$configuration = new Configuration();
99+
$configuration->ignoreErrors([ErrorType::UNKNOWN_CLASS]);
100+
$configuration->ignoreErrorsOnPath(__DIR__, [ErrorType::UNKNOWN_CLASS]);
101+
$configuration->ignoreUnknownClasses(['Unknown\Clazz']);
102+
$configuration->ignoreUnknownClassesRegex('~^Unknown~');
103+
104+
$ignoreList1 = $configuration->getIgnoreList();
105+
$ignoreList2 = $configuration->getIgnoreList();
106+
$ignoreList3 = $configuration->getIgnoreList();
107+
108+
$parentDir = realpath(__DIR__ . '/..');
109+
self::assertNotFalse($parentDir);
110+
111+
foreach ([$ignoreList1, $ignoreList2, $ignoreList3] as $ignoreList) {
112+
self::assertEquals([
113+
new UnusedErrorIgnore(ErrorType::UNKNOWN_CLASS, null, null),
114+
new UnusedErrorIgnore(ErrorType::UNKNOWN_CLASS, __DIR__, null),
115+
new UnusedClassIgnore('Unknown\Clazz', false),
116+
new UnusedClassIgnore('~^Unknown~', true),
117+
], $ignoreList->getUnusedIgnores());
118+
}
119+
120+
self::assertTrue($ignoreList1->shouldIgnoreUnknownClass('Unknown\Clazz', __DIR__));
121+
self::assertEquals([], $ignoreList1->getUnusedIgnores());
122+
123+
self::assertTrue($ignoreList2->shouldIgnoreUnknownClass('Unknown\Clazz', $parentDir));
124+
self::assertEquals([
125+
new UnusedErrorIgnore(ErrorType::UNKNOWN_CLASS, __DIR__, null),
126+
], $ignoreList2->getUnusedIgnores());
127+
128+
self::assertTrue($ignoreList3->shouldIgnoreUnknownClass('Another\Clazz', $parentDir));
129+
self::assertEquals([
130+
new UnusedErrorIgnore(ErrorType::UNKNOWN_CLASS, __DIR__, null),
131+
new UnusedClassIgnore('Unknown\Clazz', false),
132+
new UnusedClassIgnore('~^Unknown~', true),
133+
], $ignoreList3->getUnusedIgnores());
134+
}
135+
90136
/**
91137
* @param callable(Configuration): void $configure
92138
* @dataProvider provideInvalidConfigs

0 commit comments

Comments
 (0)