1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Add closure-use termination for byref flows

This commit is contained in:
Matt Brown 2020-11-13 13:37:27 -05:00
parent e7e5904d2d
commit d97c8b750a
2 changed files with 37 additions and 12 deletions

View File

@ -412,24 +412,36 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$use_var_id = '$' . $use->var->name;
$use_location = new CodeLocation($this, $use);
$use_assignment = null;
if ($statements_analyzer->data_flow_graph) {
$use_assignment = DataFlowNode::getForAssignment(
$use_var_id,
$use_location
);
$statements_analyzer->data_flow_graph->addNode($use_assignment);
$context->vars_in_scope[$use_var_id]->parent_nodes += [$use_assignment->id => $use_assignment];
}
if ($use->byRef) {
$byref_uses[$use_var_id] = true;
} else {
$use_location = new CodeLocation($this, $use);
$statements_analyzer->registerVariable($use_var_id, $use_location, null);
if ($statements_analyzer->data_flow_graph && isset($context->vars_in_scope[$use_var_id])) {
$use_assignment = DataFlowNode::getForAssignment(
$use_var_id,
$use_location
if ($statements_analyzer->data_flow_graph && $use_assignment) {
$statements_analyzer->data_flow_graph->addPath(
$use_assignment,
new DataFlowNode('closure-use', 'closure use', null),
'closure-use'
);
$statements_analyzer->data_flow_graph->addNode($use_assignment);
$context->vars_in_scope[$use_var_id]->parent_nodes += [$use_assignment->id => $use_assignment];
}
} else {
$statements_analyzer->registerVariable($use_var_id, $use_location, null);
}
}
$statements_analyzer->setByRefUses($byref_uses);

View File

@ -2255,6 +2255,19 @@ class UnusedVariableTest extends TestCase
return $output;
}'
],
'allowedUseByRefArrayAssignment' => [
'<?php
$output_rows = [];
$a = function() use (&$output_rows) : void {
$output_row = 5;
/** @psalm-suppress MixedArrayAssignment */
$output_rows[] = $output_row;
};
$a();
print_r($output_rows);'
],
];
}