Skip to content

Commit

Permalink
fix(#265): allow for multiple rules to be applied to the same node
Browse files Browse the repository at this point in the history
  • Loading branch information
Geert Broekmans committed Feb 20, 2024
1 parent 77d8373 commit bd8ad36
Showing 1 changed file with 31 additions and 65 deletions.
96 changes: 31 additions & 65 deletions src/Rule/Assertion/Declaration/DeclarationAssertion.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

Check failure on line 51 in src/Rule/Assertion/Declaration/DeclarationAssertion.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (7.4, highest)

Strict comparison using === between PHPStan\Reflection\ClassReflection and null will always evaluate to false.

Check failure on line 51 in src/Rule/Assertion/Declaration/DeclarationAssertion.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (8.0, highest)

Strict comparison using === between PHPStan\Reflection\ClassReflection and null will always evaluate to false.

Check failure on line 51 in src/Rule/Assertion/Declaration/DeclarationAssertion.php

View workflow job for this annotation

GitHub Actions / Static Code Analysis (8.1, highest)

Strict comparison using === between PHPStan\Reflection\ClassReflection and null will always evaluate to false.
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
Expand All @@ -84,57 +103,4 @@ abstract protected function getMessage(string $ruleName, string $subject, array
* @return array<RuleError>
*/
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<RuleError>
* @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;
}
}

0 comments on commit bd8ad36

Please sign in to comment.