Skip to content

Commit 3d6bbe4

Browse files
committed
InvalidIncDecOperationRule - make aware of more deprecations
1 parent 0ff7e44 commit 3d6bbe4

File tree

4 files changed

+94
-7
lines changed

4 files changed

+94
-7
lines changed

src/Rules/Operators/InvalidIncDecOperationRule.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use PHPStan\Type\ObjectType;
2121
use PHPStan\Type\StringType;
2222
use PHPStan\Type\Type;
23+
use PHPStan\Type\TypeCombinator;
2324
use PHPStan\Type\UnionType;
2425
use PHPStan\Type\VerbosityLevel;
2526
use function get_class;
@@ -112,7 +113,27 @@ public function processNode(Node $node, Scope $scope): array
112113
$deprecatedString = true;
113114
}
114115

115-
$allowedTypes = new UnionType([new BooleanType(), new FloatType(), new IntegerType(), $string, new NullType(), new ObjectType('SimpleXMLElement')]);
116+
$allowedTypes = [new FloatType(), new IntegerType(), $string, new ObjectType('SimpleXMLElement')];
117+
$deprecatedNull = false;
118+
if (
119+
!$this->phpVersion->deprecatesDecOnNonNumericString()
120+
|| $node instanceof Node\Expr\PreInc
121+
|| $node instanceof Node\Expr\PostInc
122+
) {
123+
$allowedTypes[] = new NullType();
124+
} else {
125+
$deprecatedNull = true;
126+
}
127+
128+
$deprecatedBool = false;
129+
if (!$this->phpVersion->deprecatesDecOnNonNumericString()) {
130+
$allowedTypes[] = new BooleanType();
131+
} else {
132+
$deprecatedBool = true;
133+
}
134+
135+
$allowedTypes = new UnionType($allowedTypes);
136+
116137
$varType = $this->ruleLevelHelper->findTypeToCheck(
117138
$scope,
118139
$node->var,
@@ -133,12 +154,19 @@ public function processNode(Node $node, Scope $scope): array
133154
->identifier(sprintf('%s.type', $nodeType));
134155

135156
if (!$varType->isString()->no() && $deprecatedString) {
136-
$errorBuilder->tip(sprintf(
157+
$errorBuilder->addTip(sprintf(
137158
'Operator %s is deprecated for non-numeric-strings. Either narrow the type to numeric-string, or use %s().',
138159
$operatorString,
139160
$node instanceof Node\Expr\PreDec || $node instanceof Node\Expr\PostDec ? 'str_decrement' : 'str_increment',
140161
));
141162
}
163+
if (!$varType->isNull()->no() && $deprecatedNull) {
164+
$errorBuilder->addTip(sprintf('Operator %s is deprecated for null.', $operatorString));
165+
}
166+
167+
if (!$varType->isBoolean()->no() && $deprecatedBool) {
168+
$errorBuilder->addTip(sprintf('Operator %s is deprecated for %s.', $operatorString, TypeCombinator::intersect($varType, new BooleanType())->describe(VerbosityLevel::value())));
169+
}
142170

143171
return [
144172
$errorBuilder->build(),

tests/PHPStan/Rules/Operators/InvalidIncDecOperationRuleTest.php

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPStan\Rules\RuleLevelHelper;
88
use PHPStan\Testing\RuleTestCase;
99
use PHPUnit\Framework\Attributes\RequiresPhp;
10+
use const PHP_EOL;
1011
use const PHP_VERSION_ID;
1112

1213
/**
@@ -29,7 +30,7 @@ protected function getRule(): Rule
2930

3031
public function testRule(): void
3132
{
32-
$this->analyse([__DIR__ . '/data/invalid-inc-dec.php'], [
33+
$errors = [
3334
[
3435
'Cannot use ++ on a non-variable.',
3536
11,
@@ -66,7 +67,27 @@ public function testRule(): void
6667
'Cannot use -- on resource.',
6768
32,
6869
],
69-
]);
70+
];
71+
72+
if (PHP_VERSION_ID >= 80300) {
73+
$errors[] = [
74+
'Cannot use ++ on true.',
75+
36,
76+
'Operator ++ is deprecated for true.',
77+
];
78+
$errors[] = [
79+
'Cannot use -- on false.',
80+
38,
81+
'Operator -- is deprecated for false.',
82+
];
83+
$errors[] = [
84+
'Cannot use -- on null.',
85+
42,
86+
'Operator -- is deprecated for null.',
87+
];
88+
}
89+
90+
$this->analyse([__DIR__ . '/data/invalid-inc-dec.php'], $errors);
7091
}
7192

7293
#[RequiresPhp('>= 8.0')]
@@ -132,12 +153,19 @@ public function testUnion(): void
132153
[
133154
'Cannot use ++ on array|bool|float|int|object|string|null.',
134155
24,
135-
'Operator ++ is deprecated for non-numeric-strings. Either narrow the type to numeric-string, or use str_increment().',
156+
PHP_VERSION_ID >= 80500 ?
157+
'• Operator ++ is deprecated for non-numeric-strings. Either narrow the type to numeric-string, or use str_increment().' . PHP_EOL .
158+
'• Operator ++ is deprecated for bool.'
159+
: (PHP_VERSION_ID >= 80300 ? 'Operator ++ is deprecated for bool.' : null),
136160
],
137161
[
138162
'Cannot use -- on array|bool|float|int|object|string|null.',
139163
26,
140-
'Operator -- is deprecated for non-numeric-strings. Either narrow the type to numeric-string, or use str_decrement().',
164+
PHP_VERSION_ID >= 80300 ?
165+
'• Operator -- is deprecated for non-numeric-strings. Either narrow the type to numeric-string, or use str_decrement().' . PHP_EOL .
166+
'• Operator -- is deprecated for null.' . PHP_EOL .
167+
'• Operator -- is deprecated for bool.'
168+
: null,
141169
],
142170
[
143171
'Cannot use ++ on (array|object).',
@@ -165,6 +193,21 @@ public function testDecNonNumericString(): void
165193
23,
166194
'Operator -- is deprecated for non-numeric-strings. Either narrow the type to numeric-string, or use str_decrement().',
167195
],
196+
[
197+
'Cannot use -- on null.',
198+
30,
199+
'Operator -- is deprecated for null.',
200+
],
201+
[
202+
'Cannot use ++ on bool.',
203+
32,
204+
'Operator ++ is deprecated for bool.',
205+
],
206+
[
207+
'Cannot use -- on bool.',
208+
40,
209+
'Operator -- is deprecated for bool.',
210+
],
168211
];
169212
}
170213

tests/PHPStan/Rules/Operators/data/dec-non-numeric-string.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,20 @@ public function doFoo(
2424
$t--;
2525
}
2626

27+
public function doBar(bool $b): void
28+
{
29+
$null = null;
30+
$null--;
31+
32+
$b++;
33+
}
34+
35+
public function doBaz(bool $b): void
36+
{
37+
$null = null;
38+
$null++;
39+
40+
$b--;
41+
}
42+
2743
}

tests/PHPStan/Rules/Operators/data/invalid-inc-dec-union.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
/**
66
* @param __benevolent<scalar|null|array|object> $benevolentUnion
7-
* @param numeric-string|int|float|bool|null $okUnion
7+
* @param numeric-string|int|float $okUnion
88
* @param scalar|null|array|object $union
99
* @param __benevolent<array|object> $badBenevolentUnion
1010
*/

0 commit comments

Comments
 (0)