Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b7dd96a

Browse files
kamil-zacekondrejmirtes
authored andcommitted
Strict operator type check for assign operations
1 parent 66b378f commit b7dd96a

15 files changed

+317
-90
lines changed

‎phpstan-baseline.neon‎

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,61 +107,31 @@ parameters:
107107
count: 1
108108
path: src/Rules/Operators/OperandsInArithmeticAdditionRule.php
109109

110-
-
111-
message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\BinaryOp\\\\BooleanAnd\\) of method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticAdditionRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\<PhpParser\\\\Node\\>\\:\\:processNode\\(\\)$#"
112-
count: 1
113-
path: src/Rules/Operators/OperandsInArithmeticAdditionRule.php
114-
115110
-
116111
message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticDivisionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#"
117112
count: 1
118113
path: src/Rules/Operators/OperandsInArithmeticDivisionRule.php
119114

120-
-
121-
message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\BinaryOp\\\\BooleanAnd\\) of method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticDivisionRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\<PhpParser\\\\Node\\>\\:\\:processNode\\(\\)$#"
122-
count: 1
123-
path: src/Rules/Operators/OperandsInArithmeticDivisionRule.php
124-
125115
-
126116
message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticExponentiationRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#"
127117
count: 1
128118
path: src/Rules/Operators/OperandsInArithmeticExponentiationRule.php
129119

130-
-
131-
message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\BinaryOp\\\\BooleanAnd\\) of method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticExponentiationRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\<PhpParser\\\\Node\\>\\:\\:processNode\\(\\)$#"
132-
count: 1
133-
path: src/Rules/Operators/OperandsInArithmeticExponentiationRule.php
134-
135120
-
136121
message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticModuloRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#"
137122
count: 1
138123
path: src/Rules/Operators/OperandsInArithmeticModuloRule.php
139124

140-
-
141-
message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\BinaryOp\\\\BooleanAnd\\) of method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticModuloRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\<PhpParser\\\\Node\\>\\:\\:processNode\\(\\)$#"
142-
count: 1
143-
path: src/Rules/Operators/OperandsInArithmeticModuloRule.php
144-
145125
-
146126
message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticMultiplicationRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#"
147127
count: 1
148128
path: src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php
149129

150-
-
151-
message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\BinaryOp\\\\BooleanAnd\\) of method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticMultiplicationRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\<PhpParser\\\\Node\\>\\:\\:processNode\\(\\)$#"
152-
count: 1
153-
path: src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php
154-
155130
-
156131
message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticSubtractionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#"
157132
count: 1
158133
path: src/Rules/Operators/OperandsInArithmeticSubtractionRule.php
159134

160-
-
161-
message: "#^Parameter \\#1 \\$node \\(PhpParser\\\\Node\\\\Expr\\\\BinaryOp\\\\BooleanAnd\\) of method PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticSubtractionRule\\:\\:processNode\\(\\) should be contravariant with parameter \\$node \\(PhpParser\\\\Node\\) of method PHPStan\\\\Rules\\\\Rule\\<PhpParser\\\\Node\\>\\:\\:processNode\\(\\)$#"
162-
count: 1
163-
path: src/Rules/Operators/OperandsInArithmeticSubtractionRule.php
164-
165135
-
166136
message: "#^Class PHPStan\\\\Rules\\\\StrictCalls\\\\DynamicCallOnStaticMethodsRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#"
167137
count: 1

‎rules.neon‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,21 +204,33 @@ services:
204204

205205
-
206206
class: PHPStan\Rules\Operators\OperandsInArithmeticAdditionRule
207+
arguments:
208+
bleedingEdge: %featureToggles.bleedingEdge%
207209

208210
-
209211
class: PHPStan\Rules\Operators\OperandsInArithmeticDivisionRule
212+
arguments:
213+
bleedingEdge: %featureToggles.bleedingEdge%
210214

211215
-
212216
class: PHPStan\Rules\Operators\OperandsInArithmeticExponentiationRule
217+
arguments:
218+
bleedingEdge: %featureToggles.bleedingEdge%
213219

214220
-
215221
class: PHPStan\Rules\Operators\OperandsInArithmeticModuloRule
222+
arguments:
223+
bleedingEdge: %featureToggles.bleedingEdge%
216224

217225
-
218226
class: PHPStan\Rules\Operators\OperandsInArithmeticMultiplicationRule
227+
arguments:
228+
bleedingEdge: %featureToggles.bleedingEdge%
219229

220230
-
221231
class: PHPStan\Rules\Operators\OperandsInArithmeticSubtractionRule
232+
arguments:
233+
bleedingEdge: %featureToggles.bleedingEdge%
222234

223235
-
224236
class: PHPStan\Rules\StrictCalls\DynamicCallOnStaticMethodsRule

‎src/Rules/Operators/OperandsInArithmeticAdditionRule.php‎

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace PHPStan\Rules\Operators;
44

55
use PhpParser\Node;
6-
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
7-
use PhpParser\Node\Expr\BinaryOp\Plus;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\AssignOp\Plus as AssignOpPlus;
8+
use PhpParser\Node\Expr\BinaryOp\Plus as BinaryOpPlus;
89
use PHPStan\Analyser\Scope;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Type\VerbosityLevel;
@@ -17,36 +18,49 @@ class OperandsInArithmeticAdditionRule implements Rule
1718
/** @var OperatorRuleHelper */
1819
private $helper;
1920

20-
public function __construct(OperatorRuleHelper $helper)
21+
/** @var bool */
22+
private $bleedingEdge;
23+
24+
public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge)
2125
{
2226
$this->helper = $helper;
27+
$this->bleedingEdge = $bleedingEdge;
2328
}
2429

2530
public function getNodeType(): string
2631
{
27-
return Plus::class;
32+
return Expr::class;
2833
}
2934

3035
/**
31-
* @param BooleanAnd $node
3236
* @return string[] errors
3337
*/
3438
public function processNode(Node $node, Scope $scope): array
3539
{
36-
$leftType = $scope->getType($node->left);
37-
$rightType = $scope->getType($node->right);
40+
if ($node instanceof BinaryOpPlus) {
41+
$left = $node->left;
42+
$right = $node->right;
43+
} elseif ($node instanceof AssignOpPlus && $this->bleedingEdge) {
44+
$left = $node->var;
45+
$right = $node->expr;
46+
} else {
47+
return [];
48+
}
49+
50+
$leftType = $scope->getType($left);
51+
$rightType = $scope->getType($right);
3852
if (count($leftType->getArrays()) > 0 && count($rightType->getArrays()) > 0) {
3953
return [];
4054
}
4155

4256
$messages = [];
43-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) {
57+
if (!$this->helper->isValidForArithmeticOperation($scope, $left)) {
4458
$messages[] = sprintf(
4559
'Only numeric types are allowed in +, %s given on the left side.',
4660
$leftType->describe(VerbosityLevel::typeOnly())
4761
);
4862
}
49-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) {
63+
if (!$this->helper->isValidForArithmeticOperation($scope, $right)) {
5064
$messages[] = sprintf(
5165
'Only numeric types are allowed in +, %s given on the right side.',
5266
$rightType->describe(VerbosityLevel::typeOnly())

‎src/Rules/Operators/OperandsInArithmeticDivisionRule.php‎

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace PHPStan\Rules\Operators;
44

55
use PhpParser\Node;
6-
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
7-
use PhpParser\Node\Expr\BinaryOp\Div;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\AssignOp\Div as AssignOpDiv;
8+
use PhpParser\Node\Expr\BinaryOp\Div as BinaryOpDiv;
89
use PHPStan\Analyser\Scope;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Type\VerbosityLevel;
@@ -16,33 +17,46 @@ class OperandsInArithmeticDivisionRule implements Rule
1617
/** @var OperatorRuleHelper */
1718
private $helper;
1819

19-
public function __construct(OperatorRuleHelper $helper)
20+
/** @var bool */
21+
private $bleedingEdge;
22+
23+
public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge)
2024
{
2125
$this->helper = $helper;
26+
$this->bleedingEdge = $bleedingEdge;
2227
}
2328

2429
public function getNodeType(): string
2530
{
26-
return Div::class;
31+
return Expr::class;
2732
}
2833

2934
/**
30-
* @param BooleanAnd $node
3135
* @return string[] errors
3236
*/
3337
public function processNode(Node $node, Scope $scope): array
3438
{
39+
if ($node instanceof BinaryOpDiv) {
40+
$left = $node->left;
41+
$right = $node->right;
42+
} elseif ($node instanceof AssignOpDiv && $this->bleedingEdge) {
43+
$left = $node->var;
44+
$right = $node->expr;
45+
} else {
46+
return [];
47+
}
48+
3549
$messages = [];
36-
$leftType = $scope->getType($node->left);
37-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) {
50+
$leftType = $scope->getType($left);
51+
if (!$this->helper->isValidForArithmeticOperation($scope, $left)) {
3852
$messages[] = sprintf(
3953
'Only numeric types are allowed in /, %s given on the left side.',
4054
$leftType->describe(VerbosityLevel::typeOnly())
4155
);
4256
}
4357

44-
$rightType = $scope->getType($node->right);
45-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) {
58+
$rightType = $scope->getType($right);
59+
if (!$this->helper->isValidForArithmeticOperation($scope, $right)) {
4660
$messages[] = sprintf(
4761
'Only numeric types are allowed in /, %s given on the right side.',
4862
$rightType->describe(VerbosityLevel::typeOnly())

‎src/Rules/Operators/OperandsInArithmeticExponentiationRule.php‎

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace PHPStan\Rules\Operators;
44

55
use PhpParser\Node;
6-
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
7-
use PhpParser\Node\Expr\BinaryOp\Pow;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\AssignOp\Pow as AssignOpPow;
8+
use PhpParser\Node\Expr\BinaryOp\Pow as BinaryOpPow;
89
use PHPStan\Analyser\Scope;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Type\VerbosityLevel;
@@ -16,33 +17,46 @@ class OperandsInArithmeticExponentiationRule implements Rule
1617
/** @var OperatorRuleHelper */
1718
private $helper;
1819

19-
public function __construct(OperatorRuleHelper $helper)
20+
/** @var bool */
21+
private $bleedingEdge;
22+
23+
public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge)
2024
{
2125
$this->helper = $helper;
26+
$this->bleedingEdge = $bleedingEdge;
2227
}
2328

2429
public function getNodeType(): string
2530
{
26-
return Pow::class;
31+
return Expr::class;
2732
}
2833

2934
/**
30-
* @param BooleanAnd $node
3135
* @return string[] errors
3236
*/
3337
public function processNode(Node $node, Scope $scope): array
3438
{
39+
if ($node instanceof BinaryOpPow) {
40+
$left = $node->left;
41+
$right = $node->right;
42+
} elseif ($node instanceof AssignOpPow && $this->bleedingEdge) {
43+
$left = $node->var;
44+
$right = $node->expr;
45+
} else {
46+
return [];
47+
}
48+
3549
$messages = [];
36-
$leftType = $scope->getType($node->left);
37-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) {
50+
$leftType = $scope->getType($left);
51+
if (!$this->helper->isValidForArithmeticOperation($scope, $left)) {
3852
$messages[] = sprintf(
3953
'Only numeric types are allowed in **, %s given on the left side.',
4054
$leftType->describe(VerbosityLevel::typeOnly())
4155
);
4256
}
4357

44-
$rightType = $scope->getType($node->right);
45-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) {
58+
$rightType = $scope->getType($right);
59+
if (!$this->helper->isValidForArithmeticOperation($scope, $right)) {
4660
$messages[] = sprintf(
4761
'Only numeric types are allowed in **, %s given on the right side.',
4862
$rightType->describe(VerbosityLevel::typeOnly())

‎src/Rules/Operators/OperandsInArithmeticModuloRule.php‎

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace PHPStan\Rules\Operators;
44

55
use PhpParser\Node;
6-
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
7-
use PhpParser\Node\Expr\BinaryOp\Mod;
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\AssignOp\Mod as AssignOpMod;
8+
use PhpParser\Node\Expr\BinaryOp\Mod as BinaryOpMod;
89
use PHPStan\Analyser\Scope;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Type\VerbosityLevel;
@@ -16,33 +17,46 @@ class OperandsInArithmeticModuloRule implements Rule
1617
/** @var OperatorRuleHelper */
1718
private $helper;
1819

19-
public function __construct(OperatorRuleHelper $helper)
20+
/** @var bool */
21+
private $bleedingEdge;
22+
23+
public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge)
2024
{
2125
$this->helper = $helper;
26+
$this->bleedingEdge = $bleedingEdge;
2227
}
2328

2429
public function getNodeType(): string
2530
{
26-
return Mod::class;
31+
return Expr::class;
2732
}
2833

2934
/**
30-
* @param BooleanAnd $node
3135
* @return string[] errors
3236
*/
3337
public function processNode(Node $node, Scope $scope): array
3438
{
39+
if ($node instanceof BinaryOpMod) {
40+
$left = $node->left;
41+
$right = $node->right;
42+
} elseif ($node instanceof AssignOpMod && $this->bleedingEdge) {
43+
$left = $node->var;
44+
$right = $node->expr;
45+
} else {
46+
return [];
47+
}
48+
3549
$messages = [];
36-
$leftType = $scope->getType($node->left);
37-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) {
50+
$leftType = $scope->getType($left);
51+
if (!$this->helper->isValidForArithmeticOperation($scope, $left)) {
3852
$messages[] = sprintf(
3953
'Only numeric types are allowed in %%, %s given on the left side.',
4054
$leftType->describe(VerbosityLevel::typeOnly())
4155
);
4256
}
4357

44-
$rightType = $scope->getType($node->right);
45-
if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) {
58+
$rightType = $scope->getType($right);
59+
if (!$this->helper->isValidForArithmeticOperation($scope, $right)) {
4660
$messages[] = sprintf(
4761
'Only numeric types are allowed in %%, %s given on the right side.',
4862
$rightType->describe(VerbosityLevel::typeOnly())

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /