mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Fix variadic format cc @TysonAndre and allow callable param types
Ref #580
This commit is contained in:
parent
f604ed99d5
commit
fb802540d6
@ -411,6 +411,7 @@ class CommentChecker
|
||||
|
||||
if ($next_char === ':') {
|
||||
++$i;
|
||||
$type .= ':';
|
||||
$expects_callable_return = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ class FunctionCallChecker extends \Psalm\Checker\Statements\Expression\CallCheck
|
||||
$has_valid_function_call_type = false;
|
||||
|
||||
foreach ($stmt->name->inferredType->getTypes() as $var_type_part) {
|
||||
if ($var_type_part instanceof Type\Atomic\Fn) {
|
||||
if ($var_type_part instanceof Type\Atomic\Fn || $var_type_part instanceof Type\Atomic\TCallable) {
|
||||
$function_params = $var_type_part->params;
|
||||
|
||||
if (isset($stmt->inferredType) && $var_type_part->return_type) {
|
||||
|
@ -86,6 +86,6 @@ class FunctionLikeParameter
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return ($this->is_variadic ? '...' : '') . $this->type . ($this->is_optional ? '=' : '');
|
||||
return $this->type . ($this->is_variadic ? '...' : '') . ($this->is_optional ? '=' : '');
|
||||
}
|
||||
}
|
||||
|
@ -165,16 +165,6 @@ class ParseTree
|
||||
break;
|
||||
|
||||
case '...':
|
||||
if (!$current_leaf instanceof ParseTree\CallableTree) {
|
||||
throw new TypeParseTreeException('Unexpected token ' . $type_token);
|
||||
}
|
||||
|
||||
$new_leaf = new ParseTree\CallableParamTree($current_leaf);
|
||||
$new_leaf->variadic = true;
|
||||
$current_leaf->children[] = $new_leaf;
|
||||
$current_leaf = $new_leaf;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
$current_parent = $current_leaf->parent;
|
||||
|
||||
@ -195,7 +185,8 @@ class ParseTree
|
||||
}
|
||||
|
||||
$new_leaf = new ParseTree\CallableParamTree($current_parent);
|
||||
$new_leaf->has_default = true;
|
||||
$new_leaf->has_default = $type_token === '=';
|
||||
$new_leaf->variadic = $type_token === '...';
|
||||
$new_leaf->children = [$current_leaf];
|
||||
|
||||
$current_leaf->parent = $new_leaf;
|
||||
|
@ -64,6 +64,21 @@ class CallableTest extends TestCase
|
||||
'$a' => 'int',
|
||||
],
|
||||
],
|
||||
'varReturnType' => [
|
||||
'<?php
|
||||
$add_one = function(int $a): int {
|
||||
return $a + 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param callable(int) : int $c
|
||||
*/
|
||||
function bar(callable $c) : int {
|
||||
return $c(1);
|
||||
}
|
||||
|
||||
bar($add_one);',
|
||||
],
|
||||
'callableToClosure' => [
|
||||
'<?php
|
||||
/**
|
||||
@ -403,6 +418,22 @@ class CallableTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'MissingClosureReturnType',
|
||||
],
|
||||
'wrongCallableReturnType' => [
|
||||
'<?php
|
||||
$add_one = function(int $a): int {
|
||||
return $a + 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param callable(int) : int $c
|
||||
*/
|
||||
function bar(callable $c) : string {
|
||||
return $c(1);
|
||||
}
|
||||
|
||||
bar($add_one);',
|
||||
'error_message' => 'InvalidReturnStatement',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -329,8 +329,8 @@ class TypeParseTest extends TestCase
|
||||
public function testCallableWithVariadic()
|
||||
{
|
||||
$this->assertSame(
|
||||
'callable(int, ...string) : void',
|
||||
(string)Type::parseString('callable(int, ...string) : void')
|
||||
'callable(int, string...) : void',
|
||||
(string)Type::parseString('callable(int, string...) : void')
|
||||
);
|
||||
}
|
||||
|
||||
@ -341,7 +341,17 @@ class TypeParseTest extends TestCase
|
||||
*/
|
||||
public function testCallableWithBadVariadic()
|
||||
{
|
||||
Type::parseString('callable(int, ..string) : void');
|
||||
Type::parseString('callable(int, ...string) : void');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Psalm\Exception\TypeParseTreeException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCallableWithAnotherBadVariadic()
|
||||
{
|
||||
Type::parseString('callable(int, string..) : void');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,7 +361,7 @@ class TypeParseTest extends TestCase
|
||||
*/
|
||||
public function testCallableWithVariadicAndDefault()
|
||||
{
|
||||
Type::parseString('callable(int, ...string=) : void');
|
||||
Type::parseString('callable(int, string...=) : void');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,7 +371,7 @@ class TypeParseTest extends TestCase
|
||||
*/
|
||||
public function testBadVariadic()
|
||||
{
|
||||
Type::parseString('...string');
|
||||
Type::parseString('string...');
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user