mirror of
https://github.com/danog/psalm.git
synced 2024-12-02 09:37:59 +01:00
parent
578b90c2da
commit
5c45221bdc
@ -295,45 +295,70 @@ class BinaryOpAnalyzer
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pre_referenced_var_ids = $context->referenced_var_ids;
|
if (!$stmt->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr
|
||||||
$context->referenced_var_ids = [];
|
&& !($stmt->left instanceof PhpParser\Node\Expr\BooleanNot
|
||||||
|
&& $stmt->left->expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd)
|
||||||
|
) {
|
||||||
|
$if_scope = new \Psalm\Internal\Scope\IfScope();
|
||||||
|
|
||||||
$pre_assigned_var_ids = $context->assigned_var_ids;
|
try {
|
||||||
|
$if_conditional_scope = IfAnalyzer::analyzeIfConditional(
|
||||||
$left_context = clone $context;
|
$statements_analyzer,
|
||||||
$left_context->parent_context = $context;
|
$stmt->left,
|
||||||
$left_context->if_context = null;
|
$context,
|
||||||
$left_context->assigned_var_ids = [];
|
$codebase,
|
||||||
|
$if_scope,
|
||||||
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, $left_context) === false) {
|
$context->branch_point ?: (int) $stmt->getAttribute('startFilePos')
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($left_context->vars_in_scope as $var_id => $type) {
|
|
||||||
if (!isset($context->vars_in_scope[$var_id])) {
|
|
||||||
if (isset($left_context->assigned_var_ids[$var_id])) {
|
|
||||||
$context->vars_in_scope[$var_id] = clone $type;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$context->vars_in_scope[$var_id] = Type::combineUnionTypes(
|
|
||||||
$context->vars_in_scope[$var_id],
|
|
||||||
$type,
|
|
||||||
$codebase
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$left_context = $if_conditional_scope->if_context;
|
||||||
|
|
||||||
|
$left_referenced_var_ids = $if_conditional_scope->cond_referenced_var_ids;
|
||||||
|
$left_assigned_var_ids = $if_conditional_scope->cond_assigned_var_ids;
|
||||||
|
} catch (\Psalm\Exception\ScopeAnalysisException $e) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$pre_referenced_var_ids = $context->referenced_var_ids;
|
||||||
|
$context->referenced_var_ids = [];
|
||||||
|
|
||||||
|
$pre_assigned_var_ids = $context->assigned_var_ids;
|
||||||
|
|
||||||
|
$left_context = clone $context;
|
||||||
|
$left_context->parent_context = $context;
|
||||||
|
$left_context->if_context = null;
|
||||||
|
$left_context->assigned_var_ids = [];
|
||||||
|
|
||||||
|
if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, $left_context) === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($left_context->vars_in_scope as $var_id => $type) {
|
||||||
|
if (!isset($context->vars_in_scope[$var_id])) {
|
||||||
|
if (isset($left_context->assigned_var_ids[$var_id])) {
|
||||||
|
$context->vars_in_scope[$var_id] = clone $type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$context->vars_in_scope[$var_id] = Type::combineUnionTypes(
|
||||||
|
$context->vars_in_scope[$var_id],
|
||||||
|
$type,
|
||||||
|
$codebase
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($context->collect_references) {
|
||||||
|
$context->unreferenced_vars = $left_context->unreferenced_vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
$left_referenced_var_ids = $left_context->referenced_var_ids;
|
||||||
|
$left_context->referenced_var_ids = array_merge($pre_referenced_var_ids, $left_referenced_var_ids);
|
||||||
|
|
||||||
|
$left_assigned_var_ids = array_diff_key($left_context->assigned_var_ids, $pre_assigned_var_ids);
|
||||||
|
|
||||||
|
$left_referenced_var_ids = array_diff_key($left_referenced_var_ids, $left_assigned_var_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($context->collect_references) {
|
|
||||||
$context->unreferenced_vars = $left_context->unreferenced_vars;
|
|
||||||
}
|
|
||||||
|
|
||||||
$left_referenced_var_ids = $left_context->referenced_var_ids;
|
|
||||||
$left_context->referenced_var_ids = array_merge($pre_referenced_var_ids, $left_referenced_var_ids);
|
|
||||||
|
|
||||||
$left_assigned_var_ids = array_diff_key($left_context->assigned_var_ids, $pre_assigned_var_ids);
|
|
||||||
|
|
||||||
$left_referenced_var_ids = array_diff_key($left_referenced_var_ids, $left_assigned_var_ids);
|
|
||||||
|
|
||||||
$left_clauses = Algebra::getFormula(
|
$left_clauses = Algebra::getFormula(
|
||||||
\spl_object_id($stmt->left),
|
\spl_object_id($stmt->left),
|
||||||
$stmt->left,
|
$stmt->left,
|
||||||
|
@ -2498,7 +2498,7 @@ class ConditionalTest extends \Psalm\Tests\TestCase
|
|||||||
return 0;
|
return 0;
|
||||||
}',
|
}',
|
||||||
],
|
],
|
||||||
'SKIPPED-assertHardConditional' => [
|
'assertHardConditionalWithString' => [
|
||||||
'<?php
|
'<?php
|
||||||
interface Convertor {
|
interface Convertor {
|
||||||
function maybeConvert(string $value): ?SomeObject;
|
function maybeConvert(string $value): ?SomeObject;
|
||||||
@ -2508,19 +2508,12 @@ class ConditionalTest extends \Psalm\Tests\TestCase
|
|||||||
function isValid(): bool;
|
function isValid(): bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function exampleWithOr(Convertor $convertor, string $value): SomeObject {
|
||||||
* @param mixed $value
|
if (($value = $convertor->maybeConvert($value)) === null || !$value->isValid()) {
|
||||||
*/
|
|
||||||
function exampleWithOr(Convertor $convertor, $value): SomeObject
|
|
||||||
{
|
|
||||||
if (!\is_string($value)
|
|
||||||
|| ($value = $convertor->maybeConvert($value)) === null
|
|
||||||
|| !$value->isValid()
|
|
||||||
) {
|
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value; // $value is SomeObject here and cannot be a string
|
||||||
}'
|
}'
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user