mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Revert "Fix #2909 - don’t treat args of unknown calls as possible by-reference vars"
This reverts commit 105fe012c4d177bbb23d81c73e9b1ea4c69fe7be.
This commit is contained in:
parent
09137b0a32
commit
b2678d40aa
@ -657,15 +657,37 @@ class CallAnalyzer
|
||||
PhpParser\Node\Arg $arg,
|
||||
Context $context
|
||||
) {
|
||||
$was_inside_call = $context->inside_call;
|
||||
$context->inside_call = true;
|
||||
// there are a bunch of things we want to evaluate even when we don't
|
||||
// know what function/method is being called
|
||||
if ($arg->value instanceof PhpParser\Node\Expr\Closure
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\ConstFetch
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\ClassConstFetch
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\FuncCall
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\MethodCall
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\StaticCall
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\New_
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\Assign
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\ArrayDimFetch
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\PropertyFetch
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\Array_
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\BinaryOp
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\Ternary
|
||||
|| $arg->value instanceof PhpParser\Node\Scalar\Encapsed
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\PostInc
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\PostDec
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\PreInc
|
||||
|| $arg->value instanceof PhpParser\Node\Expr\PreDec
|
||||
) {
|
||||
$was_inside_call = $context->inside_call;
|
||||
$context->inside_call = true;
|
||||
|
||||
if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context) === false) {
|
||||
return false;
|
||||
}
|
||||
if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$was_inside_call) {
|
||||
$context->inside_call = false;
|
||||
if (!$was_inside_call) {
|
||||
$context->inside_call = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($arg->value instanceof PhpParser\Node\Expr\PropertyFetch
|
||||
@ -681,7 +703,27 @@ class CallAnalyzer
|
||||
}
|
||||
|
||||
if ($var_id) {
|
||||
if ($context->hasVariable($var_id, $statements_analyzer)) {
|
||||
if (!$context->hasVariable($var_id, $statements_analyzer)
|
||||
|| $context->vars_in_scope[$var_id]->isNull()
|
||||
) {
|
||||
// we don't know if it exists, assume it's passed by reference
|
||||
$context->vars_in_scope[$var_id] = Type::getMixed();
|
||||
$context->vars_possibly_in_scope[$var_id] = true;
|
||||
|
||||
if (strpos($var_id, '-') === false
|
||||
&& strpos($var_id, '[') === false
|
||||
&& !$statements_analyzer->hasVariable($var_id)
|
||||
) {
|
||||
$location = new CodeLocation($statements_analyzer, $arg->value);
|
||||
$statements_analyzer->registerVariable(
|
||||
$var_id,
|
||||
$location,
|
||||
null
|
||||
);
|
||||
|
||||
$statements_analyzer->registerVariableUses([$location->getHash() => $location]);
|
||||
}
|
||||
} else {
|
||||
$context->removeVarFromConflictingClauses(
|
||||
$var_id,
|
||||
$context->vars_in_scope[$var_id],
|
||||
|
@ -859,23 +859,6 @@ class MethodCallTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'InvalidStringClass',
|
||||
],
|
||||
'dontAssumePossibleByRef' => [
|
||||
'<?php
|
||||
class C {
|
||||
function b(string $p): string {
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
function func() {
|
||||
return new C();
|
||||
}
|
||||
|
||||
/** @psalm-suppress MixedMethodCall */
|
||||
func()->b($param);',
|
||||
'error_message' => 'UndefinedGlobalVariable',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -543,14 +543,14 @@ class UnusedCodeTest extends TestCase
|
||||
/**
|
||||
* @psalm-suppress MixedArgument
|
||||
*/
|
||||
public function bar(string $request): void {
|
||||
public function bar(): void {
|
||||
/** @var mixed $action */
|
||||
$action = "";
|
||||
$this->{"execute" . ucfirst($action)}($request);
|
||||
}
|
||||
}
|
||||
|
||||
(new Foo)->bar("hello");'
|
||||
(new Foo)->bar();'
|
||||
],
|
||||
'usedMethodCallForExternalMutationFreeClass' => [
|
||||
'<?php
|
||||
|
@ -518,6 +518,13 @@ class UnusedVariableTest extends TestCase
|
||||
|
||||
if ($i) {}',
|
||||
],
|
||||
'unknownMethodCallWithVar' => [
|
||||
'<?php
|
||||
/** @psalm-suppress MixedMethodCall */
|
||||
function passesByRef(object $a): void {
|
||||
$a->passedByRef($b);
|
||||
}',
|
||||
],
|
||||
'usedMethodCallVariable' => [
|
||||
'<?php
|
||||
function reindex(array $arr, string $methodName): array {
|
||||
|
Loading…
x
Reference in New Issue
Block a user