1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix checks for existing vars used in by-ref assignments

This commit is contained in:
Matthew Brown 2019-03-03 18:21:12 -05:00
parent 9e8c3b8c6e
commit a31420be5b
4 changed files with 27 additions and 6 deletions

View File

@ -977,8 +977,12 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer implements Statements
/**
* @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) {
foreach ($context->possible_param_types as $var_id => $type) {
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, '
. $actual_type->getId() . ' type found. Use @param-out to specify '
. 'a different output type',
$param->location
$stmt
? new CodeLocation($this, $stmt )
: $param->location
),
$statements_analyzer->getSuppressedIssues()
)) {

View File

@ -703,7 +703,7 @@ class ExpressionAnalyzer
);
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()) {
$stmt->inferredType = clone $by_ref_type;
@ -1295,7 +1295,7 @@ class ExpressionAnalyzer
if ($source instanceof FunctionLikeAnalyzer
&& !($source->getSource() instanceof TraitAnalyzer)
) {
$source->examineParamTypes($statements_analyzer, $context, $codebase);
$source->examineParamTypes($statements_analyzer, $context, $codebase, $stmt);
$storage = $source->getFunctionLikeStorage($statements_analyzer);

View File

@ -124,7 +124,7 @@ class ReturnAnalyzer
$context
);
$source->examineParamTypes($statements_analyzer, $context, $codebase);
$source->examineParamTypes($statements_analyzer, $context, $codebase, $stmt);
$storage = $source->getFunctionLikeStorage($statements_analyzer);

View File

@ -116,6 +116,21 @@ class ReferenceConstraintTest extends TestCase
'$a' => 'int',
],
],
'paramOutReturn' => [
'<?php
/**
* @param-out bool $s
*/
function foo(?bool &$s) : void {
$s = true;
}
$b = false;
foo($b);',
'assertions' => [
'$b' => 'bool',
],
],
];
}