Skip to content

Commit 54dc323

Browse files
Refactoring the ControlStructureNestingRule
1 parent 818d7d2 commit 54dc323

File tree

4 files changed

+82
-30
lines changed

4 files changed

+82
-30
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
/bin/
22
/vendor/
3+
/tmp/
4+
/var/
35
.idea
6+
/.phpunit.cache/

composer.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,16 @@
1818
],
1919
"config": {
2020
"bin-dir": "bin"
21+
},
22+
"scripts": {
23+
"test": [
24+
"phpunit"
25+
],
26+
"test-coverage": [
27+
"phpunit --coverage-text"
28+
],
29+
"test-coverage-html": [
30+
"phpunit --coverage-html tmp/coverage/"
31+
]
2132
}
2233
}

phpunit.xml.dist

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.3/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
cacheDirectory=".phpunit.cache"
6+
cacheResult="true"
7+
executionOrder="random"
8+
resolveDependencies="false"
9+
requireCoverageMetadata="false"
10+
beStrictAboutChangesToGlobalState="true"
11+
beStrictAboutCoverageMetadata="true"
12+
beStrictAboutOutputDuringTests="false"
13+
failOnRisky="true"
14+
failOnWarning="false">
15+
16+
<php>
17+
<env name="APP_ENV" value="test" />
18+
</php>
19+
20+
<testsuites>
21+
<testsuite name="default">
22+
<directory>tests</directory>
23+
</testsuite>
24+
</testsuites>
25+
26+
<source restrictNotices="true" restrictWarnings="true" ignoreIndirectDeprecations="true">
27+
<include>
28+
<directory>src</directory>
29+
</include>
30+
</source>
31+
32+
</phpunit>

src/ControlStructureNestingRule.php

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function processNode(Node $node, Scope $scope): array
3737
{
3838
$this->setParentAttributesToEnableCorrectNestingDetection($node);
3939

40-
if (!$this->nodeIsAControllerStructure($node)) {
40+
if (!$this->nodeIsAControlStructure($node)) {
4141
return [];
4242
}
4343

@@ -50,7 +50,7 @@ public function processNode(Node $node, Scope $scope): array
5050
return $errors;
5151
}
5252

53-
private function nodeIsAControllerStructure(Node $node): bool
53+
private function nodeIsAControlStructure(Node $node): bool
5454
{
5555
return $node instanceof If_ ||
5656
$node instanceof Else_ ||
@@ -62,7 +62,7 @@ private function nodeIsAControllerStructure(Node $node): bool
6262
private function getNestingLevel(Node $node, int $currentLevel = 1): int
6363
{
6464
$parent = $node->getAttribute('parent');
65-
if ($this->nodeIsAControllerStructure($parent)) {
65+
if ($this->nodeIsAControlStructure($parent)) {
6666
return $this->getNestingLevel($parent, $currentLevel + 1);
6767
}
6868

@@ -76,26 +76,7 @@ private function getNestingLevel(Node $node, int $currentLevel = 1): int
7676
public function setParentAttributesToEnableCorrectNestingDetection(Node $node): void
7777
{
7878
$traverser = new NodeTraverser();
79-
$traverser->addVisitor(
80-
new class extends NodeVisitorAbstract {
81-
public function enterNode(Node $node)
82-
{
83-
foreach ($node->getSubNodeNames() as $subNodeName) {
84-
$subNode = $node->$subNodeName;
85-
if (is_array($subNode)) {
86-
foreach ($subNode as $childNode) {
87-
if ($childNode instanceof Node) {
88-
$childNode->setAttribute('parent', $node);
89-
}
90-
}
91-
} elseif ($subNode instanceof Node) {
92-
$subNode->setAttribute('parent', $node);
93-
}
94-
}
95-
}
96-
}
97-
);
98-
79+
$traverser->addVisitor($this->createNodeVisitor());
9980
$traverser->traverse([$node]);
10081
}
10182

@@ -107,13 +88,38 @@ public function enterNode(Node $node)
10788
*/
10889
public function addError(int $nestingLevel, Else_|If_|Catch_|ElseIf_|TryCatch $node, array $errors): array
10990
{
110-
$errors[] = RuleErrorBuilder::message(
111-
sprintf(
112-
'Nesting level of %d exceeded. Maximum allowed is %d.',
113-
$nestingLevel,
114-
$this->maxNestingLevel
115-
)
116-
)->line($node->getLine())->build();
91+
$errorMessage = sprintf(
92+
'Nesting level of %d exceeded. Maximum allowed is %d.',
93+
$nestingLevel,
94+
$this->maxNestingLevel
95+
);
96+
97+
$errors[] = RuleErrorBuilder::message($errorMessage)->line($node->getLine())->build();
98+
11799
return $errors;
118100
}
101+
102+
public function createNodeVisitor(): object
103+
{
104+
return new class extends NodeVisitorAbstract {
105+
public function enterNode(Node $node)
106+
{
107+
foreach ($node->getSubNodeNames() as $subNodeName) {
108+
$subNode = $node->$subNodeName;
109+
if (is_array($subNode)) {
110+
foreach ($subNode as $childNode) {
111+
if ($childNode instanceof Node) {
112+
$childNode->setAttribute('parent', $node);
113+
}
114+
}
115+
continue;
116+
}
117+
118+
if ($subNode instanceof Node) {
119+
$subNode->setAttribute('parent', $node);
120+
}
121+
}
122+
}
123+
};
124+
}
119125
}

0 commit comments

Comments
 (0)