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

Fix #2632 - detect invalid by-ref assignments in pure functions

This commit is contained in:
Brown 2020-01-23 14:21:34 -05:00
parent 0ac20e76c4
commit da43b8188f
4 changed files with 33 additions and 0 deletions

View File

@ -981,6 +981,10 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
];
}
if ($function_param->by_ref) {
$context->vars_in_scope['$' . $function_param->name]->by_ref = true;
}
$parser_param = $this->function->getParams()[$offset];
if (!$function_param->type_location || !$function_param->location) {

View File

@ -15,6 +15,7 @@ use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Issue\AssignmentToVoid;
use Psalm\Issue\ImpureByReferenceAssignment;
use Psalm\Issue\ImpurePropertyAssignment;
use Psalm\Issue\InvalidArrayOffset;
use Psalm\Issue\InvalidDocblock;
@ -280,6 +281,17 @@ class AssignmentAnalyzer
if ($array_var_id && isset($context->vars_in_scope[$array_var_id])) {
if ($context->vars_in_scope[$array_var_id]->by_ref) {
if ($context->mutation_free) {
if (IssueBuffer::accepts(
new ImpureByReferenceAssignment(
'Variable ' . $array_var_id . ' cannot be assigned to as it is passed by reference',
new CodeLocation($statements_analyzer->getSource(), $assign_var)
)
)) {
// fall through
}
}
$assign_value_type->by_ref = true;
}

View File

@ -0,0 +1,6 @@
<?php
namespace Psalm\Issue;
class ImpureByReferenceAssignment extends CodeIssue
{
}

View File

@ -342,6 +342,17 @@ class PureAnnotationTest extends TestCase
}',
'error_message' => 'ImpureFunctionCall',
],
'impureByRef' => [
'<?php
/**
* @psalm-pure
*/
function foo(string &$a): string {
$a = "B";
return $a;
}',
'error_message' => 'ImpureByReferenceAssignment'
],
];
}
}