Skip to content

Commit 46f4af6

Browse files
committed
Detect numeric strings, enable by default, allow to switch on/off
1 parent 51042a9 commit 46f4af6

33 files changed

+209
-32
lines changed

rules.neon

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,104 @@
11
parameters:
22
sidzIgnoreMagicNumbers: [0, 1]
3+
sidzIgnoreNumericStrings: false
34

45
parametersSchema:
56
sidzIgnoreMagicNumbers: arrayOf(number())
7+
sidzIgnoreNumericStrings: boolean()
68

79
services:
810
NoMagicNumberAsFunctionArgumentRule:
911
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberAsFunctionArgumentRule
1012
arguments:
1113
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
14+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
1215
tags:
1316
- phpstan.rules.rule
1417

1518
NoMagicNumberAssignedToPropertyRule:
1619
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberAssignedToPropertyRule
1720
arguments:
1821
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
22+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
1923
tags:
2024
- phpstan.rules.rule
2125

2226
NoMagicNumberInArithmeticOperatorRule:
2327
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInArithmeticOperatorRule
2428
arguments:
2529
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
30+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
2631
tags:
2732
- phpstan.rules.rule
2833

2934
NoMagicNumberInBitwiseOperatorRule:
3035
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInBitwiseOperatorRule
3136
arguments:
3237
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
38+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
3339
tags:
3440
- phpstan.rules.rule
3541

3642
NoMagicNumberInComparisonOperatorRule:
3743
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInComparisonOperatorRule
3844
arguments:
3945
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
46+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
4047
tags:
4148
- phpstan.rules.rule
4249

4350
NoMagicNumberInDefaultParameterRule:
4451
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInDefaultParameterRule
4552
arguments:
4653
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
54+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
4755
tags:
4856
- phpstan.rules.rule
4957

5058
NoMagicNumberInLogicalOperatorRule:
5159
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInLogicalOperatorRule
5260
arguments:
5361
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
62+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
5463
tags:
5564
- phpstan.rules.rule
5665

5766
NoMagicNumberInMatchRule:
5867
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInMatchRule
5968
arguments:
6069
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
70+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
6171
tags:
6272
- phpstan.rules.rule
6373

6474
NoMagicNumberInReturnStatementRule:
6575
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInReturnStatementRule
6676
arguments:
6777
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
78+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
6879
tags:
6980
- phpstan.rules.rule
7081

7182
NoMagicNumberInSwitchCaseRule:
7283
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInSwitchCaseRule
7384
arguments:
7485
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
86+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
7587
tags:
7688
- phpstan.rules.rule
7789

7890
NoMagicNumberInTernaryOperatorRule:
7991
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberInTernaryOperatorRule
8092
arguments:
8193
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
94+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
8295
tags:
8396
- phpstan.rules.rule
8497

8598
NoMagicNumberVariableAssignmentRule:
8699
class: Sid\PHPStan\Rules\MagicNumber\NoMagicNumberVariableAssignmentRule
87100
arguments:
88101
ignoreMagicNumbers: %sidzIgnoreMagicNumbers%
102+
ignoreNumericStrings: %sidzIgnoreNumericStrings%
89103
tags:
90104
- phpstan.rules.rule

src/Rules/MagicNumber/AbstractMagicNumberRule.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,28 @@
88
use PhpParser\Node\Expr;
99
use PhpParser\Node\Scalar\DNumber;
1010
use PhpParser\Node\Scalar\LNumber;
11+
use PhpParser\Node\Scalar\String_;
1112
use PHPStan\Rules\Rule;
1213

1314
abstract class AbstractMagicNumberRule implements Rule
1415
{
15-
/**
16-
* @var list<numeric>
17-
*/
18-
private $ignoreMagicNumbers;
19-
2016
/**
2117
* @param list<numeric> $ignoreMagicNumbers
2218
*/
23-
public function __construct(array $ignoreMagicNumbers = [])
24-
{
25-
$this->ignoreMagicNumbers = $ignoreMagicNumbers;
19+
public function __construct(
20+
private readonly array $ignoreMagicNumbers = [],
21+
private readonly bool $ignoreNumericStrings = false,
22+
) {
2623
}
2724

28-
protected function isNumber(?Expr $expr): bool
25+
protected function isNumeric(?Expr $expr): bool
2926
{
3027
$isNumber = $expr instanceof LNumber
3128
|| $expr instanceof DNumber
32-
|| ($expr instanceof Expr\UnaryMinus && $this->isNumber($expr->expr))
33-
|| ($expr instanceof Expr\UnaryPlus && $this->isNumber($expr->expr));
29+
|| ($expr instanceof Expr\UnaryMinus && $this->isNumeric($expr->expr))
30+
|| ($expr instanceof Expr\UnaryPlus && $this->isNumeric($expr->expr))
31+
|| ($expr instanceof Expr\Cast\String_ && $this->isNumeric($expr->expr))
32+
|| $this->isNumericString($expr);
3433

3534
return $isNumber && !$this->ignoreNumber($expr);
3635
}
@@ -42,4 +41,11 @@ private function ignoreNumber(Expr $scalar): bool
4241
{
4342
return in_array($scalar->value, $this->ignoreMagicNumbers, true);
4443
}
44+
45+
private function isNumericString(?Expr $expr): bool
46+
{
47+
return !$this->ignoreNumericStrings
48+
&& $expr instanceof String_
49+
&& is_numeric($expr->value);
50+
}
4551
}

src/Rules/MagicNumber/NoMagicNumberAsFunctionArgumentRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function getNodeType(): string
2626
*/
2727
public function processNode(Node $node, Scope $scope): array
2828
{
29-
if ($this->isNumber($node->value)) {
29+
if ($this->isNumeric($node->value)) {
3030
return [
3131
RuleErrorBuilder::message(self::ERROR_MESSAGE)->line($node->getLine())->build(),
3232
];

src/Rules/MagicNumber/NoMagicNumberAssignedToPropertyRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function getNodeType(): string
2626
*/
2727
public function processNode(Node $node, Scope $scope): array
2828
{
29-
if ($node->default === null || !$this->isNumber($node->default)) {
29+
if ($node->default === null || !$this->isNumeric($node->default)) {
3030
return [];
3131
}
3232

src/Rules/MagicNumber/NoMagicNumberInArithmeticOperatorRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function processNode(Node $node, Scope $scope): array
3131
return [];
3232
}
3333

34-
if (!$this->isNumber($node->left) && !$this->isNumber($node->right)) {
34+
if (!$this->isNumeric($node->left) && !$this->isNumeric($node->right)) {
3535
return [];
3636
}
3737

src/Rules/MagicNumber/NoMagicNumberInBitwiseOperatorRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function processNode(Node $node, Scope $scope): array
2828
return [];
2929
}
3030

31-
if (!$this->isNumber($node->left) && !$this->isNumber($node->right)) {
31+
if (!$this->isNumeric($node->left) && !$this->isNumeric($node->right)) {
3232
return [];
3333
}
3434

src/Rules/MagicNumber/NoMagicNumberInComparisonOperatorRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function processNode(Node $node, Scope $scope): array
3131
return [];
3232
}
3333

34-
if (!$this->isNumber($node->left) && !$this->isNumber($node->right)) {
34+
if (!$this->isNumeric($node->left) && !$this->isNumeric($node->right)) {
3535
return [];
3636
}
3737

src/Rules/MagicNumber/NoMagicNumberInDefaultParameterRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function getNodeType(): string
2626
*/
2727
public function processNode(Node $node, Scope $scope): array
2828
{
29-
if ($node->default === null || !$this->isNumber($node->default)) {
29+
if ($node->default === null || !$this->isNumeric($node->default)) {
3030
return [];
3131
}
3232

src/Rules/MagicNumber/NoMagicNumberInLogicalOperatorRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function processNode(Node $node, Scope $scope): array
2727
return [];
2828
}
2929

30-
if (!$this->isNumber($node->left) && !$this->isNumber($node->right)) {
30+
if (!$this->isNumeric($node->left) && !$this->isNumeric($node->right)) {
3131
return [];
3232
}
3333

src/Rules/MagicNumber/NoMagicNumberInMatchRule.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ public function processNode(Node $node, Scope $scope): array
2929
{
3030
$messages = [];
3131

32-
if ($this->isNumber($node->cond)) {
32+
if ($this->isNumeric($node->cond)) {
3333
$messages[] = RuleErrorBuilder::message(self::MATCH_MESSAGE)->line($node->cond->getLine())->build();
3434
}
3535

3636
foreach ($node->arms as $arm) {
3737
foreach ($arm->conds as $case) {
38-
if (!$this->isNumber($case)) {
38+
if (!$this->isNumeric($case)) {
3939
continue;
4040
}
4141

0 commit comments

Comments
 (0)