1
0
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:
Matthew Brown 2018-03-27 00:12:41 -04:00
parent f604ed99d5
commit fb802540d6
6 changed files with 51 additions and 18 deletions

View File

@ -411,6 +411,7 @@ class CommentChecker
if ($next_char === ':') {
++$i;
$type .= ':';
$expects_callable_return = true;
continue;
}

View File

@ -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) {

View File

@ -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 ? '=' : '');
}
}

View File

@ -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;

View File

@ -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',
],
];
}
}

View File

@ -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...');
}
/**