diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 9aac5db4..84faab10 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -107,61 +107,31 @@ parameters: count: 1 path: src/Rules/Operators/OperandsInArithmeticAdditionRule.php - - - 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\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticAdditionRule.php - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticDivisionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" count: 1 path: src/Rules/Operators/OperandsInArithmeticDivisionRule.php - - - 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\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticDivisionRule.php - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticExponentiationRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" count: 1 path: src/Rules/Operators/OperandsInArithmeticExponentiationRule.php - - - 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\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticExponentiationRule.php - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticModuloRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" count: 1 path: src/Rules/Operators/OperandsInArithmeticModuloRule.php - - - 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\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticModuloRule.php - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticMultiplicationRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" count: 1 path: src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php - - - 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\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php - - message: "#^Class PHPStan\\\\Rules\\\\Operators\\\\OperandsInArithmeticSubtractionRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" count: 1 path: src/Rules/Operators/OperandsInArithmeticSubtractionRule.php - - - 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\\\\:\\:processNode\\(\\)$#" - count: 1 - path: src/Rules/Operators/OperandsInArithmeticSubtractionRule.php - - message: "#^Class PHPStan\\\\Rules\\\\StrictCalls\\\\DynamicCallOnStaticMethodsRule implements generic interface PHPStan\\\\Rules\\\\Rule but does not specify its types\\: TNodeType$#" count: 1 diff --git a/rules.neon b/rules.neon index a7635f6d..46632c0c 100644 --- a/rules.neon +++ b/rules.neon @@ -204,21 +204,33 @@ services: - class: PHPStan\Rules\Operators\OperandsInArithmeticAdditionRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticDivisionRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticExponentiationRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticModuloRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticMultiplicationRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\Operators\OperandsInArithmeticSubtractionRule + arguments: + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\Rules\StrictCalls\DynamicCallOnStaticMethodsRule diff --git a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php index 47323ffc..ba29b5a7 100644 --- a/src/Rules/Operators/OperandsInArithmeticAdditionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticAdditionRule.php @@ -3,8 +3,9 @@ namespace PHPStan\Rules\Operators; use PhpParser\Node; -use PhpParser\Node\Expr\BinaryOp\BooleanAnd; -use PhpParser\Node\Expr\BinaryOp\Plus; +use PhpParser\Node\Expr; +use PhpParser\Node\Expr\AssignOp\Plus as AssignOpPlus; +use PhpParser\Node\Expr\BinaryOp\Plus as BinaryOpPlus; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Type\VerbosityLevel; @@ -17,36 +18,49 @@ class OperandsInArithmeticAdditionRule implements Rule /** @var OperatorRuleHelper */ private $helper; - public function __construct(OperatorRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string { - return Plus::class; + return Expr::class; } /** - * @param BooleanAnd $node * @return string[] errors */ public function processNode(Node $node, Scope $scope): array { - $leftType = $scope->getType($node->left); - $rightType = $scope->getType($node->right); + if ($node instanceof BinaryOpPlus) { + $left = $node->left; + $right = $node->right; + } elseif ($node instanceof AssignOpPlus && $this->bleedingEdge) { + $left = $node->var; + $right = $node->expr; + } else { + return []; + } + + $leftType = $scope->getType($left); + $rightType = $scope->getType($right); if (count($leftType->getArrays()) > 0 && count($rightType->getArrays()) > 0) { return []; } $messages = []; - if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) { + if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = sprintf( 'Only numeric types are allowed in +, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) ); } - if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) { + if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { $messages[] = sprintf( 'Only numeric types are allowed in +, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) diff --git a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php index 43656eaa..663ff36e 100644 --- a/src/Rules/Operators/OperandsInArithmeticDivisionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticDivisionRule.php @@ -3,8 +3,9 @@ namespace PHPStan\Rules\Operators; use PhpParser\Node; -use PhpParser\Node\Expr\BinaryOp\BooleanAnd; -use PhpParser\Node\Expr\BinaryOp\Div; +use PhpParser\Node\Expr; +use PhpParser\Node\Expr\AssignOp\Div as AssignOpDiv; +use PhpParser\Node\Expr\BinaryOp\Div as BinaryOpDiv; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Type\VerbosityLevel; @@ -16,33 +17,46 @@ class OperandsInArithmeticDivisionRule implements Rule /** @var OperatorRuleHelper */ private $helper; - public function __construct(OperatorRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string { - return Div::class; + return Expr::class; } /** - * @param BooleanAnd $node * @return string[] errors */ public function processNode(Node $node, Scope $scope): array { + if ($node instanceof BinaryOpDiv) { + $left = $node->left; + $right = $node->right; + } elseif ($node instanceof AssignOpDiv && $this->bleedingEdge) { + $left = $node->var; + $right = $node->expr; + } else { + return []; + } + $messages = []; - $leftType = $scope->getType($node->left); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) { + $leftType = $scope->getType($left); + if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = sprintf( 'Only numeric types are allowed in /, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) ); } - $rightType = $scope->getType($node->right); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) { + $rightType = $scope->getType($right); + if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { $messages[] = sprintf( 'Only numeric types are allowed in /, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) diff --git a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php index 59e55f14..40f7ae7e 100644 --- a/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticExponentiationRule.php @@ -3,8 +3,9 @@ namespace PHPStan\Rules\Operators; use PhpParser\Node; -use PhpParser\Node\Expr\BinaryOp\BooleanAnd; -use PhpParser\Node\Expr\BinaryOp\Pow; +use PhpParser\Node\Expr; +use PhpParser\Node\Expr\AssignOp\Pow as AssignOpPow; +use PhpParser\Node\Expr\BinaryOp\Pow as BinaryOpPow; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Type\VerbosityLevel; @@ -16,33 +17,46 @@ class OperandsInArithmeticExponentiationRule implements Rule /** @var OperatorRuleHelper */ private $helper; - public function __construct(OperatorRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string { - return Pow::class; + return Expr::class; } /** - * @param BooleanAnd $node * @return string[] errors */ public function processNode(Node $node, Scope $scope): array { + if ($node instanceof BinaryOpPow) { + $left = $node->left; + $right = $node->right; + } elseif ($node instanceof AssignOpPow && $this->bleedingEdge) { + $left = $node->var; + $right = $node->expr; + } else { + return []; + } + $messages = []; - $leftType = $scope->getType($node->left); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) { + $leftType = $scope->getType($left); + if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = sprintf( 'Only numeric types are allowed in **, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) ); } - $rightType = $scope->getType($node->right); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) { + $rightType = $scope->getType($right); + if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { $messages[] = sprintf( 'Only numeric types are allowed in **, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) diff --git a/src/Rules/Operators/OperandsInArithmeticModuloRule.php b/src/Rules/Operators/OperandsInArithmeticModuloRule.php index b89c8515..38e0d38d 100644 --- a/src/Rules/Operators/OperandsInArithmeticModuloRule.php +++ b/src/Rules/Operators/OperandsInArithmeticModuloRule.php @@ -3,8 +3,9 @@ namespace PHPStan\Rules\Operators; use PhpParser\Node; -use PhpParser\Node\Expr\BinaryOp\BooleanAnd; -use PhpParser\Node\Expr\BinaryOp\Mod; +use PhpParser\Node\Expr; +use PhpParser\Node\Expr\AssignOp\Mod as AssignOpMod; +use PhpParser\Node\Expr\BinaryOp\Mod as BinaryOpMod; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Type\VerbosityLevel; @@ -16,33 +17,46 @@ class OperandsInArithmeticModuloRule implements Rule /** @var OperatorRuleHelper */ private $helper; - public function __construct(OperatorRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string { - return Mod::class; + return Expr::class; } /** - * @param BooleanAnd $node * @return string[] errors */ public function processNode(Node $node, Scope $scope): array { + if ($node instanceof BinaryOpMod) { + $left = $node->left; + $right = $node->right; + } elseif ($node instanceof AssignOpMod && $this->bleedingEdge) { + $left = $node->var; + $right = $node->expr; + } else { + return []; + } + $messages = []; - $leftType = $scope->getType($node->left); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) { + $leftType = $scope->getType($left); + if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = sprintf( 'Only numeric types are allowed in %%, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) ); } - $rightType = $scope->getType($node->right); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) { + $rightType = $scope->getType($right); + if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { $messages[] = sprintf( 'Only numeric types are allowed in %%, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) diff --git a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php index c1e16ae8..f1e4c064 100644 --- a/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php +++ b/src/Rules/Operators/OperandsInArithmeticMultiplicationRule.php @@ -3,8 +3,9 @@ namespace PHPStan\Rules\Operators; use PhpParser\Node; -use PhpParser\Node\Expr\BinaryOp\BooleanAnd; -use PhpParser\Node\Expr\BinaryOp\Mul; +use PhpParser\Node\Expr; +use PhpParser\Node\Expr\AssignOp\Mul as AssignOpMul; +use PhpParser\Node\Expr\BinaryOp\Mul as BinaryOpMul; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Type\VerbosityLevel; @@ -16,33 +17,46 @@ class OperandsInArithmeticMultiplicationRule implements Rule /** @var OperatorRuleHelper */ private $helper; - public function __construct(OperatorRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string { - return Mul::class; + return Expr::class; } /** - * @param BooleanAnd $node * @return string[] errors */ public function processNode(Node $node, Scope $scope): array { + if ($node instanceof BinaryOpMul) { + $left = $node->left; + $right = $node->right; + } elseif ($node instanceof AssignOpMul && $this->bleedingEdge) { + $left = $node->var; + $right = $node->expr; + } else { + return []; + } + $messages = []; - $leftType = $scope->getType($node->left); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) { + $leftType = $scope->getType($left); + if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = sprintf( 'Only numeric types are allowed in *, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) ); } - $rightType = $scope->getType($node->right); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) { + $rightType = $scope->getType($right); + if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { $messages[] = sprintf( 'Only numeric types are allowed in *, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) diff --git a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php index d5907ae5..5333c2a1 100644 --- a/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php +++ b/src/Rules/Operators/OperandsInArithmeticSubtractionRule.php @@ -3,8 +3,9 @@ namespace PHPStan\Rules\Operators; use PhpParser\Node; -use PhpParser\Node\Expr\BinaryOp\BooleanAnd; -use PhpParser\Node\Expr\BinaryOp\Minus; +use PhpParser\Node\Expr; +use PhpParser\Node\Expr\AssignOp\Minus as AssignOpMinus; +use PhpParser\Node\Expr\BinaryOp\Minus as BinaryOpMinus; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; use PHPStan\Type\VerbosityLevel; @@ -16,33 +17,46 @@ class OperandsInArithmeticSubtractionRule implements Rule /** @var OperatorRuleHelper */ private $helper; - public function __construct(OperatorRuleHelper $helper) + /** @var bool */ + private $bleedingEdge; + + public function __construct(OperatorRuleHelper $helper, bool $bleedingEdge) { $this->helper = $helper; + $this->bleedingEdge = $bleedingEdge; } public function getNodeType(): string { - return Minus::class; + return Expr::class; } /** - * @param BooleanAnd $node * @return string[] errors */ public function processNode(Node $node, Scope $scope): array { + if ($node instanceof BinaryOpMinus) { + $left = $node->left; + $right = $node->right; + } elseif ($node instanceof AssignOpMinus && $this->bleedingEdge) { + $left = $node->var; + $right = $node->expr; + } else { + return []; + } + $messages = []; - $leftType = $scope->getType($node->left); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->left)) { + $leftType = $scope->getType($left); + if (!$this->helper->isValidForArithmeticOperation($scope, $left)) { $messages[] = sprintf( 'Only numeric types are allowed in -, %s given on the left side.', $leftType->describe(VerbosityLevel::typeOnly()) ); } - $rightType = $scope->getType($node->right); - if (!$this->helper->isValidForArithmeticOperation($scope, $node->right)) { + $rightType = $scope->getType($right); + if (!$this->helper->isValidForArithmeticOperation($scope, $right)) { $messages[] = sprintf( 'Only numeric types are allowed in -, %s given on the right side.', $rightType->describe(VerbosityLevel::typeOnly()) diff --git a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php index 95b92b39..892db77f 100644 --- a/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticAdditionRuleTest.php @@ -5,6 +5,7 @@ use PHPStan\Rules\Rule; use PHPStan\Rules\RuleLevelHelper; use PHPStan\Testing\RuleTestCase; +use function array_merge; use const PHP_VERSION_ID; class OperandsInArithmeticAdditionRuleTest extends RuleTestCase @@ -15,7 +16,8 @@ protected function getRule(): Rule return new OperandsInArithmeticAdditionRule( new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -31,12 +33,28 @@ public function testRule(): void 29, ], ]; + if (PHP_VERSION_ID < 80000) { $messages[] = [ 'Only numeric types are allowed in +, (array|false) given on the left side.', 110, ]; } + + $messages = array_merge( + $messages, + [ + [ + 'Only numeric types are allowed in +, null given on the right side.', + 132, + ], + [ + 'Only numeric types are allowed in +, null given on the right side.', + 133, + ], + ] + ); + $this->analyse([__DIR__ . '/data/operators.php'], $messages); } diff --git a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php index 4e2d3055..0571e38d 100644 --- a/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticDivisionRuleTest.php @@ -14,7 +14,8 @@ protected function getRule(): Rule return new OperandsInArithmeticDivisionRule( new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -29,6 +30,14 @@ public function testRule(): void 'Only numeric types are allowed in /, null given on the right side.', 68, ], + [ + 'Only numeric types are allowed in /, null given on the right side.', + 171, + ], + [ + 'Only numeric types are allowed in /, null given on the right side.', + 172, + ], ]); } diff --git a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php index 53b8d1b8..56492a36 100644 --- a/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticExponentiationRuleTest.php @@ -14,7 +14,8 @@ protected function getRule(): Rule return new OperandsInArithmeticExponentiationRule( new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -29,6 +30,14 @@ public function testRule(): void 'Only numeric types are allowed in **, null given on the right side.', 81, ], + [ + 'Only numeric types are allowed in **, null given on the right side.', + 184, + ], + [ + 'Only numeric types are allowed in **, null given on the right side.', + 185, + ], ]); } diff --git a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php index f8490466..953732ca 100644 --- a/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticModuloRuleTest.php @@ -14,7 +14,8 @@ protected function getRule(): Rule return new OperandsInArithmeticModuloRule( new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -29,6 +30,14 @@ public function testRule(): void 'Only numeric types are allowed in %, null given on the right side.', 94, ], + [ + 'Only numeric types are allowed in %, null given on the right side.', + 197, + ], + [ + 'Only numeric types are allowed in %, null given on the right side.', + 198, + ], ]); } diff --git a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php index c4b6f25b..a0015d27 100644 --- a/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticMultiplicationRuleTest.php @@ -14,7 +14,8 @@ protected function getRule(): Rule return new OperandsInArithmeticMultiplicationRule( new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -29,6 +30,14 @@ public function testRule(): void 'Only numeric types are allowed in *, null given on the right side.', 55, ], + [ + 'Only numeric types are allowed in *, null given on the right side.', + 158, + ], + [ + 'Only numeric types are allowed in *, null given on the right side.', + 159, + ], ]); } diff --git a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php index f7643fd5..cbe8e08d 100644 --- a/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php +++ b/tests/Rules/Operators/OperandsInArithmeticSubtractionRuleTest.php @@ -14,7 +14,8 @@ protected function getRule(): Rule return new OperandsInArithmeticSubtractionRule( new OperatorRuleHelper( self::getContainer()->getByType(RuleLevelHelper::class) - ) + ), + true ); } @@ -29,6 +30,14 @@ public function testRule(): void 'Only numeric types are allowed in -, null given on the right side.', 42, ], + [ + 'Only numeric types are allowed in -, null given on the right side.', + 145, + ], + [ + 'Only numeric types are allowed in -, null given on the right side.', + 146, + ], ]); } diff --git a/tests/Rules/Operators/data/operators.php b/tests/Rules/Operators/data/operators.php index 92ec5930..f3e75598 100644 --- a/tests/Rules/Operators/data/operators.php +++ b/tests/Rules/Operators/data/operators.php @@ -117,3 +117,101 @@ function (array $array, int $int, $mixed) { function (\ReflectionClass $ref): void { print_r(class_parents($ref->getName()) + class_implements($ref->getName())); }; + +$int += $int; +$int += $float; +$float += $int; +$float += $float; +$int += $float + $int; +$intOrFloat += $int; +$array += $array; +$array += $array + $array; +$int += $string; +$int += $array; +$int += $object; +$int += $null; +$int += $float + $string + $null; +$array += $float + $array + $int; + +$int -= $int; +$int -= $float; +$float -= $int; +$float -= $float; +$int -= $float - $int; +$intOrFloat -= $int; +$int -= $string; +$int -= $array; +$int -= $object; +$int -= $null; +$int -= $float - $string - $null; +$array -= $float - $array - $int; + +$int *= $int; +$int *= $float; +$float *= $int; +$float *= $float; +$int *= $float * $int; +$intOrFloat *= $int; +$int *= $string; +$int *= $array; +$int *= $object; +$int *= $null; +$int *= $float * $string * $null; +$array *= $float * $array * $int; + +$int /= $int; +$int /= $float; +$float /= $int; +$float /= $float; +$int /= $float /= $int; +$intOrFloat /= $int; +$int /= $string; +$int /= $array; +$int /= $object; +$int /= $null; +$int /= $float / $string / $null; +$array /= $float / $array / $int; + +$int **= $int; +$int **= $float; +$float **= $int; +$float **= $float; +$int **= $float **= $int; +$intOrFloat **= $int; +$int **= $string; +$int **= $array; +$int **= $object; +$int **= $null; +$int **= $float ** $string ** $null; +$array **= $float ** $array ** $int; + +$int %= $int; +$int %= $float; +$float %= $int; +$float %= $float; +$int %= $float %= $int; +$intOrFloat %= $int; +$int %= $string; +$int %= $array; +$int %= $object; +$int %= $null; +$int %= $float % $string % $null; +$array %= $float % $array % $int; + +function ($mixed, int $a, string $b) { + $mixed += $mixed; + $mixed += $a; + $a += $mixed; + $mixed += $b; + $b += $mixed; +}; + +function (array $array, int $int, $mixed) { + foreach ($array as $i => $val) { + $i += $int; + } +}; + +/** @var numeric-string $numericString */ +$numericString = doFoo(); +$numericString += 1;