mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix checks for existing vars used in by-ref assignments
This commit is contained in:
parent
9e8c3b8c6e
commit
a31420be5b
@ -977,8 +977,12 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer implements Statements
|
|||||||
/**
|
/**
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function examineParamTypes(StatementsAnalyzer $statements_analyzer, Context $context, Codebase $codebase)
|
public function examineParamTypes(
|
||||||
{
|
StatementsAnalyzer $statements_analyzer,
|
||||||
|
Context $context,
|
||||||
|
Codebase $codebase,
|
||||||
|
PhpParser\Node $stmt = null
|
||||||
|
) {
|
||||||
if ($context->infer_types) {
|
if ($context->infer_types) {
|
||||||
foreach ($context->possible_param_types as $var_id => $type) {
|
foreach ($context->possible_param_types as $var_id => $type) {
|
||||||
if (isset($this->possible_param_types[$var_id])) {
|
if (isset($this->possible_param_types[$var_id])) {
|
||||||
@ -1019,7 +1023,9 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer implements Statements
|
|||||||
. ' because it is passed by reference, '
|
. ' because it is passed by reference, '
|
||||||
. $actual_type->getId() . ' type found. Use @param-out to specify '
|
. $actual_type->getId() . ' type found. Use @param-out to specify '
|
||||||
. 'a different output type',
|
. 'a different output type',
|
||||||
$param->location
|
$stmt
|
||||||
|
? new CodeLocation($this, $stmt )
|
||||||
|
: $param->location
|
||||||
),
|
),
|
||||||
$statements_analyzer->getSuppressedIssues()
|
$statements_analyzer->getSuppressedIssues()
|
||||||
)) {
|
)) {
|
||||||
|
@ -703,7 +703,7 @@ class ExpressionAnalyzer
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ($existing_type->getId() !== 'array<empty, empty>') {
|
if ($existing_type->getId() !== 'array<empty, empty>') {
|
||||||
$context->vars_in_scope[$var_id] = clone $by_ref_type;
|
$context->vars_in_scope[$var_id] = clone $by_ref_out_type;
|
||||||
|
|
||||||
if (!isset($stmt->inferredType) || $stmt->inferredType->isEmpty()) {
|
if (!isset($stmt->inferredType) || $stmt->inferredType->isEmpty()) {
|
||||||
$stmt->inferredType = clone $by_ref_type;
|
$stmt->inferredType = clone $by_ref_type;
|
||||||
@ -1295,7 +1295,7 @@ class ExpressionAnalyzer
|
|||||||
if ($source instanceof FunctionLikeAnalyzer
|
if ($source instanceof FunctionLikeAnalyzer
|
||||||
&& !($source->getSource() instanceof TraitAnalyzer)
|
&& !($source->getSource() instanceof TraitAnalyzer)
|
||||||
) {
|
) {
|
||||||
$source->examineParamTypes($statements_analyzer, $context, $codebase);
|
$source->examineParamTypes($statements_analyzer, $context, $codebase, $stmt);
|
||||||
|
|
||||||
$storage = $source->getFunctionLikeStorage($statements_analyzer);
|
$storage = $source->getFunctionLikeStorage($statements_analyzer);
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ class ReturnAnalyzer
|
|||||||
$context
|
$context
|
||||||
);
|
);
|
||||||
|
|
||||||
$source->examineParamTypes($statements_analyzer, $context, $codebase);
|
$source->examineParamTypes($statements_analyzer, $context, $codebase, $stmt);
|
||||||
|
|
||||||
$storage = $source->getFunctionLikeStorage($statements_analyzer);
|
$storage = $source->getFunctionLikeStorage($statements_analyzer);
|
||||||
|
|
||||||
|
@ -116,6 +116,21 @@ class ReferenceConstraintTest extends TestCase
|
|||||||
'$a' => 'int',
|
'$a' => 'int',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'paramOutReturn' => [
|
||||||
|
'<?php
|
||||||
|
/**
|
||||||
|
* @param-out bool $s
|
||||||
|
*/
|
||||||
|
function foo(?bool &$s) : void {
|
||||||
|
$s = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$b = false;
|
||||||
|
foo($b);',
|
||||||
|
'assertions' => [
|
||||||
|
'$b' => 'bool',
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user