From c161122581e22f26a93de7de00cf92926d21a982 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 1/9] Update selectors.md Signed-off-by: Nathanael Esayeas --- docs/documentation/selectors.md | 80 +++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/docs/documentation/selectors.md b/docs/documentation/selectors.md index c2fdc175..fff524eb 100644 --- a/docs/documentation/selectors.md +++ b/docs/documentation/selectors.md @@ -89,3 +89,83 @@ Selector::NOT( ``` This will select all classes that are not in the `App\User` namespace. + +## Selector::AllOf(...$selectors) + +Selects classes that match all the inner Selectors. (and operator) + +```php +Selector::AllOf( + Selector::namespace('App\User'), + Selector::isAbstract() +) +``` + +This will select all abstract classes in the `App\User` namespace. + +## Selector::AnyOf(...$selectors) + +Selects classes that match any of the inner Selectors. (or operator) + +```php +Selector::AnyOf( + Selector::namespace('App\User'), + Selector::isAbstract() +) +``` + +This will select all classes in the `App\User` namespace and all abstract classes. + +## Selector::NoneOf(...$selectors) + +Selects classes that do not match any of the inner Selectors. (not of operator) + +```php +Selector::NoneOf( + Selector::namespace('App\User'), + Selector::isAbstract() +) +``` + +This will select all classes that are not in the `App\User` namespace and are not abstract. + +## Selector::OneOf(...$selectors) + +Selects classes that match exactly one of the inner Selectors. (xor operator) + +```php +Selector::OneOf( + Selector::namespace('App\User'), + Selector::isAbstract(), + Selector::isTrait() +) +``` + +This will select all classes that are in the `App\User` namespace or are abstract or are traits, but not more than one of them. + + +## Selector::AtLeastXOf(int $min, ...$selectors) + +Selects classes that match at least X of the inner Selectors. (at least x of operator) + +```php +Selector::AtLeastCountOf(2, + Selector::namespace('App\User'), + Selector::isAbstract() +) +``` + +This will select all classes that are in the `App\User` namespace and are abstract. + +## Selector::AtMostXOf(int $max, ...$selectors) + +Selects classes that match at most X of the inner Selectors. (at most x of operator) + +```php +Selector::AtMostCountOf(1, + Selector::namespace('App\User'), + Selector::isAbstract() +) +``` + +This will select all classes that are in the `App\User` namespace or are abstract, but not both. From 5737a29a0d81b48a712080f3f8a0a13679149fa0 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 2/9] Add AllOfSelectorModifier.php Signed-off-by: Nathanael Esayeas --- .../Modifier/AllOfSelectorModifier.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/Selector/Modifier/AllOfSelectorModifier.php diff --git a/src/Selector/Modifier/AllOfSelectorModifier.php b/src/Selector/Modifier/AllOfSelectorModifier.php new file mode 100644 index 00000000..cf772966 --- /dev/null +++ b/src/Selector/Modifier/AllOfSelectorModifier.php @@ -0,0 +1,35 @@ + */ + private array $selectors; + + public function __construct(SelectorInterface ...$selectors) + { + $this->selectors = $selectors; + } + + #[\Override] + public function getName(): string + { + return \implode(' and ', \array_map(static fn ($selector) => $selector->getName(), $this->selectors)); + } + + #[\Override] + public function matches(ClassReflection $classReflection): bool + { + foreach ($this->selectors as $selector) { + if (!$selector->matches($classReflection)) { + return false; + } + } + + return true; + } +} From 92129fb241abeabf80d1e389a32a2037562350fc Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 3/9] Add AnyOfSelectorModifier.php Signed-off-by: Nathanael Esayeas --- .../Modifier/AnyOfSelectorModifier.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/Selector/Modifier/AnyOfSelectorModifier.php diff --git a/src/Selector/Modifier/AnyOfSelectorModifier.php b/src/Selector/Modifier/AnyOfSelectorModifier.php new file mode 100644 index 00000000..e96cb9b5 --- /dev/null +++ b/src/Selector/Modifier/AnyOfSelectorModifier.php @@ -0,0 +1,35 @@ + */ + private array $selectors; + + public function __construct(SelectorInterface ...$selectors) + { + $this->selectors = $selectors; + } + + #[\Override] + public function getName(): string + { + return \implode(' or ', \array_map(static fn ($selector) => $selector->getName(), $this->selectors)); + } + + #[\Override] + public function matches(ClassReflection $classReflection): bool + { + foreach ($this->selectors as $selector) { + if ($selector->matches($classReflection)) { + return true; + } + } + + return false; + } +} From fd4dc8407008ffc68bafd9ccbd181cac5f39abe8 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 4/9] Add AtLeastCountOfSelectorModifier.php Signed-off-by: Nathanael Esayeas --- .../AtLeastCountOfSelectorModifier.php | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/Selector/Modifier/AtLeastCountOfSelectorModifier.php diff --git a/src/Selector/Modifier/AtLeastCountOfSelectorModifier.php b/src/Selector/Modifier/AtLeastCountOfSelectorModifier.php new file mode 100644 index 00000000..c457c44e --- /dev/null +++ b/src/Selector/Modifier/AtLeastCountOfSelectorModifier.php @@ -0,0 +1,47 @@ + */ + private array $selectors; + + public function __construct(int $count, SelectorInterface ...$selectors) + { + $this->count = $count; + $this->selectors = $selectors; + } + + #[\Override] + public function getName(): string + { + return \sprintf( + 'at least %d of %s', + $this->count, + \implode(' and ', \array_map(static fn ($selector) => $selector->getName(), $this->selectors)), + ); + } + + #[\Override] + public function matches(ClassReflection $classReflection): bool + { + $matches = 0; + foreach ($this->selectors as $selector) { + if ($selector->matches($classReflection)) { + ++$matches; + } + + if ($matches >= $this->count) { + return true; + } + } + + return $matches >= $this->count; + } +} From 691838ad4fe3dc6c4c6f131c3b32d4ee5007a7c1 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 5/9] Add AtMostCountOfSelectorModifier.php Signed-off-by: Nathanael Esayeas --- .../AtMostCountOfSelectorModifier.php | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/Selector/Modifier/AtMostCountOfSelectorModifier.php diff --git a/src/Selector/Modifier/AtMostCountOfSelectorModifier.php b/src/Selector/Modifier/AtMostCountOfSelectorModifier.php new file mode 100644 index 00000000..7b74599e --- /dev/null +++ b/src/Selector/Modifier/AtMostCountOfSelectorModifier.php @@ -0,0 +1,47 @@ + */ + private array $selectors; + + public function __construct(int $count, SelectorInterface ...$selectors) + { + $this->count = $count; + $this->selectors = $selectors; + } + + #[\Override] + public function getName(): string + { + return \sprintf( + 'at most %d of %s', + $this->count, + \implode(' and ', \array_map(static fn ($selector) => $selector->getName(), $this->selectors)), + ); + } + + #[\Override] + public function matches(ClassReflection $classReflection): bool + { + $matches = 0; + foreach ($this->selectors as $selector) { + if ($selector->matches($classReflection)) { + ++$matches; + } + + if ($matches > $this->count) { + return false; + } + } + + return $matches <= $this->count; + } +} From 42f12042e3ea774fc2bd5ab29d3f560c03f3548c Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 6/9] Add NoneOfSelectorModifier.php Signed-off-by: Nathanael Esayeas --- .../Modifier/NoneOfSelectorModifier.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/Selector/Modifier/NoneOfSelectorModifier.php diff --git a/src/Selector/Modifier/NoneOfSelectorModifier.php b/src/Selector/Modifier/NoneOfSelectorModifier.php new file mode 100644 index 00000000..e73f1203 --- /dev/null +++ b/src/Selector/Modifier/NoneOfSelectorModifier.php @@ -0,0 +1,38 @@ + */ + private array $selectors; + + public function __construct(SelectorInterface ...$selectors) + { + $this->selectors = $selectors; + } + + #[\Override] + public function getName(): string + { + return \sprintf( + 'none of: %s', + \implode(' and ', \array_map(static fn ($selector) => $selector->getName(), $this->selectors)), + ); + } + + #[\Override] + public function matches(ClassReflection $classReflection): bool + { + foreach ($this->selectors as $selector) { + if ($selector->matches($classReflection)) { + return false; + } + } + + return true; + } +} From 4b88c83d16a640288a5b70dba1b5ec8ee5c6e32b Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 7/9] Add OneOfSelectorModifier.php Signed-off-by: Nathanael Esayeas --- .../Modifier/OneOfSelectorModifier.php | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/Selector/Modifier/OneOfSelectorModifier.php diff --git a/src/Selector/Modifier/OneOfSelectorModifier.php b/src/Selector/Modifier/OneOfSelectorModifier.php new file mode 100644 index 00000000..8ebb5461 --- /dev/null +++ b/src/Selector/Modifier/OneOfSelectorModifier.php @@ -0,0 +1,43 @@ + */ + private array $selectors; + + public function __construct(SelectorInterface ...$selectors) + { + $this->selectors = $selectors; + } + + #[\Override] + public function getName(): string + { + return \sprintf( + 'one of: [ %s ]', + \implode(' and ', \array_map(static fn ($selector) => $selector->getName(), $this->selectors)), + ); + } + + #[\Override] + public function matches(ClassReflection $classReflection): bool + { + $matches = 0; + foreach ($this->selectors as $selector) { + if ($selector->matches($classReflection)) { + ++$matches; + } + + if ($matches > 1) { + return false; + } + } + + return $matches === 1; + } +} From 46e8a010a8534c9b8bce8be0be126eb1be6078c1 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 13:06:45 -0500 Subject: [PATCH 8/9] Update Selector.php Signed-off-by: Nathanael Esayeas --- src/Selector/Selector.php | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/Selector/Selector.php b/src/Selector/Selector.php index e89e8a29..582d96cc 100644 --- a/src/Selector/Selector.php +++ b/src/Selector/Selector.php @@ -2,8 +2,14 @@ namespace PHPat\Selector; +use PHPat\Selector\Modifier\AllOfSelectorModifier; use PHPat\Selector\Modifier\AndModifier; +use PHPat\Selector\Modifier\AnyOfSelectorModifier; +use PHPat\Selector\Modifier\AtLeastCountOfSelectorModifier; +use PHPat\Selector\Modifier\AtMostCountOfSelectorModifier; +use PHPat\Selector\Modifier\NoneOfSelectorModifier; use PHPat\Selector\Modifier\NotModifier; +use PHPat\Selector\Modifier\OneOfSelectorModifier; final class Selector extends SelectorPrimitive { @@ -16,4 +22,34 @@ public static function NOT(SelectorInterface $selector): NotModifier { return new NotModifier($selector); } + + public static function AllOf(SelectorInterface ...$selectors): AllOfSelectorModifier + { + return new AllOfSelectorModifier(...$selectors); + } + + public static function AnyOf(SelectorInterface ...$selectors): AnyOfSelectorModifier + { + return new AnyOfSelectorModifier(...$selectors); + } + + public static function NoneOf(SelectorInterface ...$selectors): NoneOfSelectorModifier + { + return new NoneOfSelectorModifier(...$selectors); + } + + public static function AtLeastCountOf(int $count, SelectorInterface ...$selectors): AtLeastCountOfSelectorModifier + { + return new AtLeastCountOfSelectorModifier($count, ...$selectors); + } + + public static function AtMostCountOf(int $count, SelectorInterface ...$selectors): AtMostCountOfSelectorModifier + { + return new AtMostCountOfSelectorModifier($count, ...$selectors); + } + + public static function OneOf(SelectorInterface ...$selectors): OneOfSelectorModifier + { + return new OneOfSelectorModifier(...$selectors); + } } From c1b3f7a3e20255fec0d5e70a6436d60738044e44 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Sun, 1 Sep 2024 19:38:51 -0500 Subject: [PATCH 9/9] Update selectors.md Signed-off-by: Nathanael Esayeas --- docs/documentation/selectors.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/documentation/selectors.md b/docs/documentation/selectors.md index fff524eb..29409db5 100644 --- a/docs/documentation/selectors.md +++ b/docs/documentation/selectors.md @@ -144,7 +144,7 @@ Selector::OneOf( This will select all classes that are in the `App\User` namespace or are abstract or are traits, but not more than one of them. -## Selector::AtLeastXOf(int $min, ...$selectors) +## Selector::AtLeastCountOf(int $min, ...$selectors) Selects classes that match at least X of the inner Selectors. (at least x of operator) @@ -157,7 +157,7 @@ Selector::AtLeastCountOf(2, This will select all classes that are in the `App\User` namespace and are abstract. -## Selector::AtMostXOf(int $max, ...$selectors) +## Selector::AtMostCountOf(int $max, ...$selectors) Selects classes that match at most X of the inner Selectors. (at most x of operator)