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; $var_type = isset($stmt->var->inferredType) ? clone $stmt->var->inferredType : null;
$expr_type = isset($stmt->expr->inferredType) ? $stmt->expr->inferredType : null; $expr_type = isset($stmt->expr->inferredType) ? $stmt->expr->inferredType : null;
if ($stmt instanceof PhpParser\Node\Expr\AssignOp\Plus || if ($stmt instanceof PhpParser\Node\Expr\AssignOp\Plus
$stmt instanceof PhpParser\Node\Expr\AssignOp\Minus || || $stmt instanceof PhpParser\Node\Expr\AssignOp\Minus
$stmt instanceof PhpParser\Node\Expr\AssignOp\Mod || || $stmt instanceof PhpParser\Node\Expr\AssignOp\Mod
$stmt instanceof PhpParser\Node\Expr\AssignOp\Mul || || $stmt instanceof PhpParser\Node\Expr\AssignOp\Mul
$stmt instanceof PhpParser\Node\Expr\AssignOp\Pow || $stmt instanceof PhpParser\Node\Expr\AssignOp\Pow
) { ) {
BinaryOpAnalyzer::analyzeNonDivArithmenticOp( BinaryOpAnalyzer::analyzeNonDivArithmenticOp(
$statements_analyzer, $statements_analyzer,
@ -698,6 +698,29 @@ class AssignmentAnalyzer
$result_type $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) { if ($result_type && $array_var_id) {
$context->vars_in_scope[$array_var_id] = $result_type; $context->vars_in_scope[$array_var_id] = $result_type;
$stmt->inferredType = clone $context->vars_in_scope[$array_var_id]; $stmt->inferredType = clone $context->vars_in_scope[$array_var_id];

View File

@ -36,6 +36,15 @@ class AssignmentTest extends TestCase
echo $w; echo $w;
echo $e;', 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"])) {}
}'
],
]; ];
} }