From 6e259bed03226d98aac21d50650e8f80d19f504c Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Tue, 8 May 2018 18:11:10 -0400 Subject: [PATCH] Always evaluate closures, even when passed as mixed call args --- .../Statements/Expression/Call/MethodCallChecker.php | 10 ++++++++++ .../Checker/Statements/Expression/CallChecker.php | 7 +++++++ tests/ValueTest.php | 12 ++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/Psalm/Checker/Statements/Expression/Call/MethodCallChecker.php b/src/Psalm/Checker/Statements/Expression/Call/MethodCallChecker.php index 1e778000f..d447bf152 100644 --- a/src/Psalm/Checker/Statements/Expression/Call/MethodCallChecker.php +++ b/src/Psalm/Checker/Statements/Expression/Call/MethodCallChecker.php @@ -200,6 +200,16 @@ class MethodCallChecker extends \Psalm\Checker\Statements\Expression\CallChecker // fall through } + if (self::checkFunctionArguments( + $statements_checker, + $stmt->args, + null, + null, + $context + ) === false) { + return false; + } + $return_type = Type::getMixed(); break; } diff --git a/src/Psalm/Checker/Statements/Expression/CallChecker.php b/src/Psalm/Checker/Statements/Expression/CallChecker.php index ac8a14bfe..b8a14dc85 100644 --- a/src/Psalm/Checker/Statements/Expression/CallChecker.php +++ b/src/Psalm/Checker/Statements/Expression/CallChecker.php @@ -466,6 +466,13 @@ class CallChecker } } } else { + // if it's a closure, we want to evaluate it anyway + if ($arg->value instanceof PhpParser\Node\Expr\Closure) { + if (ExpressionChecker::analyze($statements_checker, $arg->value, $context) === false) { + return false; + } + } + if ($arg->value instanceof PhpParser\Node\Expr\PropertyFetch && $arg->value->name instanceof PhpParser\Node\Identifier ) { diff --git a/tests/ValueTest.php b/tests/ValueTest.php index 28ee0331f..b1f78c912 100644 --- a/tests/ValueTest.php +++ b/tests/ValueTest.php @@ -220,6 +220,18 @@ class ValueTest extends TestCase $a(); if ($i === 0) {}', ], + 'incrementMixedCall' => [ + 'add(function() use (&$i) : void { + if (rand(0, 1)) $i++; + }); + if ($i === 0) {} + }', + 'assertions' => [], + 'error_levels' => ['MissingParamType', 'MixedMethodCall'], + ], ]; }