Skip to content

Commit

Permalink
Merge branch '4.x' into upstream-master
Browse files Browse the repository at this point in the history
  • Loading branch information
weirdan committed Jan 7, 2022
2 parents 3fb3db3 + 760badd commit 762ef8d
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 6 deletions.
Expand Up @@ -52,6 +52,7 @@
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Reconciler;
Expand Down Expand Up @@ -688,12 +689,11 @@ private static function getAnalyzeNamedExpression(
);
} elseif ($var_type_part instanceof TCallableObject
|| $var_type_part instanceof TCallableString
|| ($var_type_part instanceof TNamedObject && $var_type_part->value === 'Closure')
|| ($var_type_part instanceof TObjectWithProperties && isset($var_type_part->methods['__invoke']))
) {
// this is fine
$has_valid_function_call_type = true;
} elseif (($var_type_part instanceof TNamedObject && $var_type_part->value === 'Closure')) {
// this is fine
$has_valid_function_call_type = true;
} elseif ($var_type_part instanceof TString
|| $var_type_part instanceof TArray
|| $var_type_part instanceof TList
Expand Down
4 changes: 4 additions & 0 deletions src/Psalm/Internal/PhpVisitor/Reflector/ExpressionScanner.php
Expand Up @@ -128,6 +128,10 @@ private static function registerClassMapFunctionCall(
}
}

if ($node->isFirstClassCallable()) {
return;
}

if ($function_id === 'define') {
$first_arg_value = isset($node->getArgs()[0]) ? $node->getArgs()[0]->value : null;
$second_arg_value = isset($node->getArgs()[1]) ? $node->getArgs()[1]->value : null;
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic/TKeyedArray.php
Expand Up @@ -429,7 +429,7 @@ public function getList(): TNonEmptyList
*/
private function escapeAndQuote($name)
{
if (is_string($name) && preg_match('/[^a-zA-Z0-9_]/', $name)) {
if (is_string($name) && ($name === '' || preg_match('/[^a-zA-Z0-9_]/', $name))) {
$name = '\'' . str_replace("\n", '\n', addslashes($name)) . '\'';
}

Expand Down
27 changes: 27 additions & 0 deletions tests/AssertAnnotationTest.php
Expand Up @@ -1944,6 +1944,33 @@ function assertString(A $arg): bool {return $arg->b !== null;}
function requiresString(string $_str): void {}
',
],
'assertWithEmptyStringOnKeyedArray' => [
'<?php
class A
{
function test(): void
{
$a = ["" => ""];
/** @var array<string, mixed> $b */
$b = [];
$this->assertSame($a, $b);
}
/**
* @template T
* @param T $expected
* @param mixed $actual
* @psalm-assert =T $actual
*/
public function assertSame($expected, $actual): void
{
return;
}
}
',
],
];
}

Expand Down
9 changes: 9 additions & 0 deletions tests/CallableTest.php
Expand Up @@ -316,6 +316,15 @@ function foo(callable $c): void {
$c2 = new C();
$c2();',
],
'invokeMethodExists' => [
'<?php
function call(object $obj): void {
if (!method_exists($obj, "__invoke")) {
return;
}
$obj();
}',
],
'correctParamType' => [
'<?php
$take_string = function(string $s): string { return $s; };
Expand Down
9 changes: 7 additions & 2 deletions tests/ClosureTest.php
Expand Up @@ -729,6 +729,12 @@ public static function __callStatic(string $name, array $args): mixed {
[],
'8.1'
],
'FirstClassCallable:array_map' => [
'<?php call_user_func(array_map(...), intval(...), ["1"]);',
'assertions' => [],
[],
'8.1',
],
];
}

Expand Down Expand Up @@ -1171,9 +1177,8 @@ public static function __callStatic(string $name, array $args): mixed {
'error_message' => 'MixedAssignment',
[],
false,
'8.1'
'8.1',
],

];
}
}

0 comments on commit 762ef8d

Please sign in to comment.