1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Allow bitwise or ops to change type

Ref #1340
This commit is contained in:
Matthew Brown 2019-02-18 12:53:55 -05:00
parent 5aaa68c214
commit 709a5c31da
3 changed files with 52 additions and 5 deletions

View File

@ -653,11 +653,11 @@ class AssignmentAnalyzer
$var_type = isset($stmt->var->inferredType) ? clone $stmt->var->inferredType : null;
$expr_type = isset($stmt->expr->inferredType) ? $stmt->expr->inferredType : null;
if ($stmt instanceof PhpParser\Node\Expr\AssignOp\Plus ||
$stmt instanceof PhpParser\Node\Expr\AssignOp\Minus ||
$stmt instanceof PhpParser\Node\Expr\AssignOp\Mod ||
$stmt instanceof PhpParser\Node\Expr\AssignOp\Mul ||
$stmt instanceof PhpParser\Node\Expr\AssignOp\Pow
if ($stmt instanceof PhpParser\Node\Expr\AssignOp\Plus
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\Minus
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\Mod
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\Mul
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\Pow
) {
BinaryOpAnalyzer::analyzeNonDivArithmenticOp(
$statements_analyzer,
@ -698,6 +698,29 @@ class AssignmentAnalyzer
$result_type
);
if ($result_type && $array_var_id) {
$context->vars_in_scope[$array_var_id] = $result_type;
$stmt->inferredType = clone $context->vars_in_scope[$array_var_id];
}
} elseif (isset($stmt->var->inferredType)
&& isset($stmt->expr->inferredType)
&& ($stmt->var->inferredType->hasInt() || $stmt->expr->inferredType->hasInt())
&& ($stmt instanceof PhpParser\Node\Expr\AssignOp\BitwiseOr
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\BitwiseXor
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\BitwiseAnd
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\ShiftLeft
|| $stmt instanceof PhpParser\Node\Expr\AssignOp\ShiftRight
)
) {
BinaryOpAnalyzer::analyzeNonDivArithmenticOp(
$statements_analyzer,
$stmt->var,
$stmt->expr,
$stmt,
$result_type,
$context
);
if ($result_type && $array_var_id) {
$context->vars_in_scope[$array_var_id] = $result_type;
$stmt->inferredType = clone $context->vars_in_scope[$array_var_id];

View File

@ -36,6 +36,15 @@ class AssignmentTest extends TestCase
echo $w;
echo $e;',
],
'bitwiseAssignment' => [
'<?php
$x = 0;
$x |= (int) (rand(0, 1) !== 2);
$x |= 1;
if ($x) {
echo $x;
}',
],
];
}

View File

@ -310,6 +310,21 @@ class EmptyTest extends TestCase
}
}',
],
'doubleEmptyCheckTwoArrays' => [
'<?php
function foo(array $a, array $b) : void {
if (empty($a) && empty($b)) {}
}'
],
'SKIPPED-doubleEmptyCheckOnObjectLike' => [
'<?php
/**
* @param array{a: array, b: array} $arr
*/
function foo(array $arr) : void {
if (empty($arr["a"]) && empty($arr["b"])) {}
}'
],
];
}