From bd0f004bd5c6b2214eb6a5fa273b0227745e0568 Mon Sep 17 00:00:00 2001 From: Maksim Tiugaev Date: Thu, 29 Feb 2024 23:13:14 +0300 Subject: [PATCH 1/2] Support attributes --- src/ComposerRequireChecker/Cli/Options.php | 13 ++++++++++- .../NodeVisitor/UsedSymbolCollector.php | 10 +++++++++ .../ComposerRequireCheckerTest/BinaryTest.php | 2 +- .../Cli/CheckCommandTest.php | 17 +++++++++++++- .../Cli/OptionsTest.php | 10 +++++++++ .../noUnknownAttributeSymbols/composer.json | 11 ++++++++++ .../src/SomeClass.php | 22 +++++++++++++++++++ .../src/WellKnownAttribute.php | 12 ++++++++++ .../vendor/composer/installed.json | 1 + .../unknownSymbols/src/AttributeThing.php | 11 ++++++++++ 10 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/noUnknownAttributeSymbols/composer.json create mode 100644 test/fixtures/noUnknownAttributeSymbols/src/SomeClass.php create mode 100644 test/fixtures/noUnknownAttributeSymbols/src/WellKnownAttribute.php create mode 100644 test/fixtures/noUnknownAttributeSymbols/vendor/composer/installed.json create mode 100644 test/fixtures/unknownSymbols/src/AttributeThing.php diff --git a/src/ComposerRequireChecker/Cli/Options.php b/src/ComposerRequireChecker/Cli/Options.php index db11fa43..8334c95e 100644 --- a/src/ComposerRequireChecker/Cli/Options.php +++ b/src/ComposerRequireChecker/Cli/Options.php @@ -36,8 +36,16 @@ class Options 'never', ]; + private const PHP_ATTRIBUTES = [ + 'AllowDynamicProperties', + 'Attribute', + 'Override', + 'ReturnTypeWillChange', + 'SensitiveParameter', + ]; + /** @var array */ - private array $symbolWhitelist = self::PHP_LANGUAGE_TYPES; + private array $symbolWhitelist; /** @var array */ private array $phpCoreExtensions = [ @@ -63,6 +71,8 @@ class Options /** @param array $options */ public function __construct(array $options = []) { + $this->symbolWhitelist = array_merge(self::PHP_LANGUAGE_TYPES, self::PHP_ATTRIBUTES); + /** @var mixed $option */ foreach ($options as $key => $option) { $methodName = 'set' . $this->getCamelCase($key); @@ -97,6 +107,7 @@ public function setSymbolWhitelist(array $symbolWhitelist): void */ $this->symbolWhitelist = array_unique(array_merge( self::PHP_LANGUAGE_TYPES, + self::PHP_ATTRIBUTES, $symbolWhitelist, )); } diff --git a/src/ComposerRequireChecker/NodeVisitor/UsedSymbolCollector.php b/src/ComposerRequireChecker/NodeVisitor/UsedSymbolCollector.php index 3ee6c8ce..5ce44120 100644 --- a/src/ComposerRequireChecker/NodeVisitor/UsedSymbolCollector.php +++ b/src/ComposerRequireChecker/NodeVisitor/UsedSymbolCollector.php @@ -47,6 +47,7 @@ public function enterNode(Node $node) $this->recordConstantFetchUsage($node); $this->recordTraitUsage($node); $this->recordPropertyTypeUsage($node); + $this->recordAttributeUsage($node); return parent::enterNode($node); } @@ -204,6 +205,15 @@ private function recordPropertyTypeUsage(Node $node): void $this->recordUsageOf($node->type); } + private function recordAttributeUsage(Node $node): void + { + if (! $node instanceof Node\Attribute) { + return; + } + + $this->recordUsageOf($node->name); + } + private function recordUsageOf(Node\Name $symbol): void { $this->recordUsageOfByString($symbol->toString()); diff --git a/test/ComposerRequireCheckerTest/BinaryTest.php b/test/ComposerRequireCheckerTest/BinaryTest.php index ad774e48..7a4e2d3a 100644 --- a/test/ComposerRequireCheckerTest/BinaryTest.php +++ b/test/ComposerRequireCheckerTest/BinaryTest.php @@ -37,7 +37,7 @@ public function testUnknownSymbols(): void $path = __DIR__ . '/../fixtures/unknownSymbols/composer.json'; exec(sprintf('%s check %s 2>&1', $this->bin, $path), $output, $return); $this->assertSame(1, $return); - $this->assertStringContainsString('The following 6 unknown symbols were found', implode("\n", $output)); + $this->assertStringContainsString('The following 7 unknown symbols were found', implode("\n", $output)); } public function testInvalidConfiguration(): void diff --git a/test/ComposerRequireCheckerTest/Cli/CheckCommandTest.php b/test/ComposerRequireCheckerTest/Cli/CheckCommandTest.php index 0d9f0635..5be6963f 100644 --- a/test/ComposerRequireCheckerTest/Cli/CheckCommandTest.php +++ b/test/ComposerRequireCheckerTest/Cli/CheckCommandTest.php @@ -70,13 +70,14 @@ public function testUnknownSymbolsFound(): void $this->assertSame(Command::FAILURE, $this->commandTester->getStatusCode()); $display = $this->commandTester->getDisplay(); - $this->assertStringContainsString('The following 6 unknown symbols were found:', $display); + $this->assertStringContainsString('The following 7 unknown symbols were found:', $display); $this->assertStringContainsString('Doctrine\Common\Collections\ArrayCollection', $display); $this->assertStringContainsString('Example\Library\Dependency', $display); $this->assertStringContainsString('FILTER_VALIDATE_URL', $display); $this->assertStringContainsString('filter_var', $display); $this->assertStringContainsString('Foo\Bar\Baz', $display); $this->assertStringContainsString('libxml_clear_errors', $display); + $this->assertStringContainsString('Vendor\UnknownAttribute ', $display); } public function testInvalidOutputOptionValue(): void @@ -111,6 +112,7 @@ public function testUnknownSymbolsFoundJsonReport(): void 'filter_var' => ['ext-filter'], 'Foo\Bar\Baz' => [], 'libxml_clear_errors' => ['ext-libxml'], + 'Vendor\UnknownAttribute' => [], ], $actual['unknown-symbols'], ); @@ -349,4 +351,17 @@ public function testNoUnknownEnumSymbolsFound(): void $this->commandTester->getDisplay(), ); } + + public function testNoUnknownAttributeSymbolsFound(): void + { + $this->commandTester->execute([ + 'composer-json' => dirname(__DIR__, 2) . '/fixtures/noUnknownAttributeSymbols/composer.json', + ]); + + self::assertSame(Command::SUCCESS, $this->commandTester->getStatusCode()); + self::assertStringContainsString( + 'There were no unknown symbols found.', + $this->commandTester->getDisplay(), + ); + } } diff --git a/test/ComposerRequireCheckerTest/Cli/OptionsTest.php b/test/ComposerRequireCheckerTest/Cli/OptionsTest.php index ec1ddbbb..a625c4cd 100644 --- a/test/ComposerRequireCheckerTest/Cli/OptionsTest.php +++ b/test/ComposerRequireCheckerTest/Cli/OptionsTest.php @@ -46,6 +46,11 @@ public function testOptionsAcceptSymbolWhitelistAndFiltersDuplicates(): void 'object', 'mixed', 'never', + 'AllowDynamicProperties', + 'Attribute', + 'Override', + 'ReturnTypeWillChange', + 'SensitiveParameter', 'foo', 'bar', ], $options->getSymbolWhitelist()); @@ -100,6 +105,11 @@ public function testPublicSetters(): void 'object', 'mixed', 'never', + 'AllowDynamicProperties', + 'Attribute', + 'Override', + 'ReturnTypeWillChange', + 'SensitiveParameter', 'foo', 'bar', ], $options->getSymbolWhitelist()); diff --git a/test/fixtures/noUnknownAttributeSymbols/composer.json b/test/fixtures/noUnknownAttributeSymbols/composer.json new file mode 100644 index 00000000..65aeb1d4 --- /dev/null +++ b/test/fixtures/noUnknownAttributeSymbols/composer.json @@ -0,0 +1,11 @@ +{ + "name": "example/library", + "require": { + "php": "8.1.*" + }, + "autoload": { + "psr-4": { + "Example\\Library\\": "src/" + } + } +} diff --git a/test/fixtures/noUnknownAttributeSymbols/src/SomeClass.php b/test/fixtures/noUnknownAttributeSymbols/src/SomeClass.php new file mode 100644 index 00000000..54c42500 --- /dev/null +++ b/test/fixtures/noUnknownAttributeSymbols/src/SomeClass.php @@ -0,0 +1,22 @@ + Date: Tue, 5 Mar 2024 11:54:29 +0300 Subject: [PATCH 2/2] Refernce php core attr via ::class --- src/ComposerRequireChecker/Cli/Options.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/ComposerRequireChecker/Cli/Options.php b/src/ComposerRequireChecker/Cli/Options.php index 8334c95e..2759c836 100644 --- a/src/ComposerRequireChecker/Cli/Options.php +++ b/src/ComposerRequireChecker/Cli/Options.php @@ -4,8 +4,13 @@ namespace ComposerRequireChecker\Cli; +use AllowDynamicProperties; +use Attribute; use ComposerRequireChecker\FileLocator\LocateComposerPackageSourceFiles; use InvalidArgumentException; +use Override; +use ReturnTypeWillChange; +use SensitiveParameter; use function array_merge; use function array_unique; @@ -37,11 +42,11 @@ class Options ]; private const PHP_ATTRIBUTES = [ - 'AllowDynamicProperties', - 'Attribute', - 'Override', - 'ReturnTypeWillChange', - 'SensitiveParameter', + AllowDynamicProperties::class, + Attribute::class, + Override::class, + ReturnTypeWillChange::class, + SensitiveParameter::class, ]; /** @var array */