mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix #4547 - mark unused uses
This commit is contained in:
parent
c1d57ba6a5
commit
ad840e4b7a
@ -123,8 +123,6 @@ class ClosureAnalyzer extends FunctionLikeAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
$byref_uses = [];
|
||||
|
||||
if ($stmt instanceof PhpParser\Node\Expr\Closure) {
|
||||
foreach ($stmt->uses as $use) {
|
||||
if (!is_string($use->var->name)) {
|
||||
@ -133,10 +131,6 @@ class ClosureAnalyzer extends FunctionLikeAnalyzer
|
||||
|
||||
$use_var_id = '$' . $use->var->name;
|
||||
|
||||
if ($use->byRef) {
|
||||
$byref_uses[$use_var_id] = true;
|
||||
}
|
||||
|
||||
// insert the ref into the current context if passed by ref, as whatever we're passing
|
||||
// the closure to could execute it straight away.
|
||||
if (!$context->hasVariable($use_var_id) && $use->byRef) {
|
||||
@ -206,7 +200,7 @@ class ClosureAnalyzer extends FunctionLikeAnalyzer
|
||||
|
||||
$use_context->calling_method_id = $context->calling_method_id;
|
||||
|
||||
$closure_analyzer->analyze($use_context, $statements_analyzer->node_data, $context, false, $byref_uses);
|
||||
$closure_analyzer->analyze($use_context, $statements_analyzer->node_data, $context, false);
|
||||
|
||||
if ($closure_analyzer->inferred_impure
|
||||
&& $statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
|
||||
|
@ -144,8 +144,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
|
||||
Context $context,
|
||||
\Psalm\Internal\Provider\NodeDataProvider $type_provider,
|
||||
?Context $global_context = null,
|
||||
bool $add_mutations = false,
|
||||
?array $byref_uses = null
|
||||
bool $add_mutations = false
|
||||
): ?bool {
|
||||
$storage = $this->storage;
|
||||
|
||||
@ -403,7 +402,36 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
|
||||
|
||||
$statements_analyzer = new StatementsAnalyzer($this, $type_provider);
|
||||
|
||||
if ($byref_uses) {
|
||||
if ($this->function instanceof Closure) {
|
||||
$byref_uses = [];
|
||||
|
||||
foreach ($this->function->uses as $use) {
|
||||
if (!\is_string($use->var->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$use_var_id = '$' . $use->var->name;
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
$statements_analyzer->data_flow_graph->addNode($use_assignment);
|
||||
|
||||
$context->vars_in_scope[$use_var_id]->parent_nodes += [$use_assignment->id => $use_assignment];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$statements_analyzer->setByRefUses($byref_uses);
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ use Psalm\Type\Atomic\TTemplateParam;
|
||||
use Psalm\Type\Atomic\TTrue;
|
||||
use Psalm\Type\Atomic\TVoid;
|
||||
use Psalm\Type\Union;
|
||||
use function get_class;
|
||||
use function stripos;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
|
@ -3060,6 +3060,15 @@ class UnusedVariableTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'PossiblyNullArgument'
|
||||
],
|
||||
'useArrayAssignmentNeverUsed' => [
|
||||
'<?php
|
||||
$data = [];
|
||||
|
||||
return function () use ($data) {
|
||||
$data[] = 1;
|
||||
};',
|
||||
'error_message' => 'UnusedVariable',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user