From bd8ad366d5acddc519bd640d411ec7f24a1a503d Mon Sep 17 00:00:00 2001 From: Geert Broekmans Date: Tue, 20 Feb 2024 08:37:58 +0100 Subject: [PATCH] fix(#265): allow for multiple rules to be applied to the same node --- .../Declaration/DeclarationAssertion.php | 96 ++++++------------- 1 file changed, 31 insertions(+), 65 deletions(-) diff --git a/src/Rule/Assertion/Declaration/DeclarationAssertion.php b/src/Rule/Assertion/Declaration/DeclarationAssertion.php index 0bd36380..d22cf95a 100644 --- a/src/Rule/Assertion/Declaration/DeclarationAssertion.php +++ b/src/Rule/Assertion/Declaration/DeclarationAssertion.php @@ -43,26 +43,45 @@ public function __construct( */ public function processNode(Node $node, Scope $scope): array { - if (!is_string($ruleName = $this->ruleApplies($scope))) { + if (!$scope->isInClass()) { return []; } - $meetsDeclaration = $this->meetsDeclaration($node, $scope, $this->getParams($ruleName)); + $subject = $scope->getClassReflection(); + if ($subject === null) { + return []; + } - return $this->validateGetErrors($scope, $meetsDeclaration, $ruleName); - } + $applicableStatements = array_filter( + $this->statements, + static function (array $statement) use ($subject): bool { + [$ruleName, $selector, $subjectExcludes, $tips, $params] = $statement; - public function getParams(string $ruleName): array - { - foreach ($this->statements as $statement) { - if ($statement[0] !== $ruleName) { - continue; + if ($subject->isBuiltin() || !$selector->matches($subject)) { + return false; + } + foreach ($subjectExcludes as $exclude) { + if ($exclude->matches($subject)) { + return false; + } + } + + return true; } + ); - return $statement[4]; - } + return array_reduce( + $applicableStatements, + function (array $errors, array $statement) use ($node, $scope, $subject): array { + [$ruleName, $selector, $subjectExcludes, $tips, $params] = $statement; + + $meetsDeclaration = $this->meetsDeclaration($node, $scope, $statement[4]); + array_push($errors, ...$this->applyValidation($ruleName, $subject, $meetsDeclaration, $tips, $params)); - return []; + return $errors; + }, + [] + ); } public function prepareMessage(string $ruleName, string $message): string @@ -84,57 +103,4 @@ abstract protected function getMessage(string $ruleName, string $subject, array * @return array */ abstract protected function applyValidation(string $ruleName, ClassReflection $subject, bool $meetsDeclaration, array $tips, array $params = []): array; - - /** - * @return bool|string false on failure, ruleName otherwise - */ - protected function ruleApplies(Scope $scope) - { - if (!$scope->isInClass()) { - return false; - } - - $subject = $scope->getClassReflection(); - if ($subject === null) { - return false; - } - - foreach ($this->statements as [$ruleName, $selector, $subjectExcludes, $tips, $params]) { - if ($subject->isBuiltin() || !$selector->matches($subject)) { - continue; - } - foreach ($subjectExcludes as $exclude) { - if ($exclude->matches($subject)) { - continue 2; - } - } - - return $ruleName; - } - - return false; - } - - /** - * @return array - * @throws ShouldNotHappenException - */ - protected function validateGetErrors(Scope $scope, bool $meetsDeclaration, string $matchedRuleName): array - { - $errors = []; - $subject = $scope->getClassReflection(); - if ($subject === null) { - throw new ShouldNotHappenException(); - } - - foreach ($this->statements as [$ruleName, $selector, $subjectExcludes, $tips, $params]) { - if ($ruleName !== $matchedRuleName) { - continue; - } - - array_push($errors, ...$this->applyValidation($ruleName, $subject, $meetsDeclaration, $tips, $params)); - } - - return $errors; - } }