mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
parent
578b90c2da
commit
5c45221bdc
@ -295,45 +295,70 @@ class BinaryOpAnalyzer
|
||||
return null;
|
||||
}
|
||||
|
||||
$pre_referenced_var_ids = $context->referenced_var_ids;
|
||||
$context->referenced_var_ids = [];
|
||||
if (!$stmt->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr
|
||||
&& !($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;
|
||||
|
||||
$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
|
||||
try {
|
||||
$if_conditional_scope = IfAnalyzer::analyzeIfConditional(
|
||||
$statements_analyzer,
|
||||
$stmt->left,
|
||||
$context,
|
||||
$codebase,
|
||||
$if_scope,
|
||||
$context->branch_point ?: (int) $stmt->getAttribute('startFilePos')
|
||||
);
|
||||
|
||||
$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(
|
||||
\spl_object_id($stmt->left),
|
||||
$stmt->left,
|
||||
|
@ -2498,7 +2498,7 @@ class ConditionalTest extends \Psalm\Tests\TestCase
|
||||
return 0;
|
||||
}',
|
||||
],
|
||||
'SKIPPED-assertHardConditional' => [
|
||||
'assertHardConditionalWithString' => [
|
||||
'<?php
|
||||
interface Convertor {
|
||||
function maybeConvert(string $value): ?SomeObject;
|
||||
@ -2508,19 +2508,12 @@ class ConditionalTest extends \Psalm\Tests\TestCase
|
||||
function isValid(): bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
function exampleWithOr(Convertor $convertor, $value): SomeObject
|
||||
{
|
||||
if (!\is_string($value)
|
||||
|| ($value = $convertor->maybeConvert($value)) === null
|
||||
|| !$value->isValid()
|
||||
) {
|
||||
function exampleWithOr(Convertor $convertor, string $value): SomeObject {
|
||||
if (($value = $convertor->maybeConvert($value)) === null || !$value->isValid()) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
return $value;
|
||||
return $value; // $value is SomeObject here and cannot be a string
|
||||
}'
|
||||
],
|
||||
];
|
||||
|
Loading…
Reference in New Issue
Block a user