diff --git a/CHANGELOG.md b/CHANGELOG.md index 4acb200..03e59b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # CHANGELOG +## v2.0 to v2.1 + +### New Requirements + +None + +### New features + +- The `InheritsAttributes` attribute can be used on classes that inherit their attributes from traits, properties, or methods, and were previously ignored by the collection process. + +### Backward Incompatible Changes + +None + +### Deprecated Features + +None + +### Other Changes + +- Just like interfaces, traits are excluded from the collection. + + + ## v1.2 to v2.0 ### New Requirements diff --git a/README.md b/README.md index a1c44fb..36e91d2 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,11 @@ watchers][phpstorm-watchers]. You could also use [spatie/file-system-watcher][], PHP. If the plugin is too slow for your liking, try running the command with `COMPOSER_ATTRIBUTE_COLLECTOR_USE_CACHE=yes`, it will enable caching and speed up consecutive runs. +**How do I include a class that inherits its attributes?** + +To speed up the collection process, the plugin first looks at PHP files as plain text for hints of attribute usage. If a +class inherits its attributes from traits, properties, or methods, it is ignored. Use the attribute +`[#\olvlvl\ComposerAttributeCollector\InheritsAttributes]` to force the collection. ---------- diff --git a/src/ClassAttributeCollector.php b/src/ClassAttributeCollector.php index dee4e13..323c3f1 100644 --- a/src/ClassAttributeCollector.php +++ b/src/ClassAttributeCollector.php @@ -120,6 +120,7 @@ private static function isAttributeIgnored(ReflectionAttribute $attribute): bool { static $ignored = [ \ReturnTypeWillChange::class => true, + InheritsAttributes::class => true, ]; return isset($ignored[$attribute->getName()]); // @phpstan-ignore offsetAccess.nonOffsetAccessible diff --git a/src/Filter/InterfaceFilter.php b/src/Filter/ClassFilter.php similarity index 79% rename from src/Filter/InterfaceFilter.php rename to src/Filter/ClassFilter.php index 9008f1b..784313b 100644 --- a/src/Filter/InterfaceFilter.php +++ b/src/Filter/ClassFilter.php @@ -8,12 +8,15 @@ use function interface_exists; -final class InterfaceFilter implements Filter +/** + * Filters classes—removes interfaces and traits. + */ +final class ClassFilter implements Filter { public function filter(string $filepath, string $class, IOInterface $io): bool { try { - if (interface_exists($class)) { + if (!class_exists($class)) { return false; } } catch (Throwable $e) { diff --git a/src/InheritsAttributes.php b/src/InheritsAttributes.php new file mode 100644 index 0000000..49edd57 --- /dev/null +++ b/src/InheritsAttributes.php @@ -0,0 +1,13 @@ + - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace tests\olvlvl\ComposerAttributeCollector; use Acme\Attribute\ActiveRecord\Boolean; @@ -21,6 +14,7 @@ use Acme\Attribute\Permission; use Acme\Attribute\Resource; use Acme\Attribute\Route; +use Acme\Attribute\Routing\UrlGetter; use Acme\Attribute\Subscribe; use Acme\PSR4\Presentation\ArticleController; use Composer\IO\NullIO; @@ -44,9 +38,6 @@ final class PluginTest extends TestCase { private static bool $initialized = false; - /** - * @throws ReflectionException - */ protected function setUp(): void { parent::setUp(); @@ -184,6 +175,12 @@ public static function provideTargetMethods(): array [ new Subscribe(), 'Acme\PSR4\SubscriberB::onEventA' ], ] ], + [ + UrlGetter::class, + [ + [ new UrlGetter(), 'Acme\PSR4\InheritedAttributeSample::get_url' ] + ] + ], ]; }