mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Improve native understanding of docblock-less variadics
This commit is contained in:
parent
895b612ca1
commit
65ef5ba8b7
@ -1220,6 +1220,13 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
]);
|
||||
}
|
||||
}
|
||||
} elseif ($param->variadic) {
|
||||
$param_type = new Type\Union([
|
||||
new Type\Atomic\TArray([
|
||||
Type::getInt(),
|
||||
Type::getMixed(),
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
$is_optional = $param->default !== null;
|
||||
|
@ -91,91 +91,6 @@ class Php56Test extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('float|int', (string) $context->vars_in_scope['$g']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testVariadic()
|
||||
{
|
||||
$stmts = self::$parser->parse('<?php
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
function f($req, $opt = null, ...$params) {
|
||||
}
|
||||
|
||||
f(1);
|
||||
f(1, 2);
|
||||
f(1, 2, 3);
|
||||
f(1, 2, 3, 4);
|
||||
f(1, 2, 3, 4, 5);
|
||||
');
|
||||
|
||||
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
|
||||
$context = new Context();
|
||||
$file_checker->visitAndAnalyzeMethods($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testVariadicArray()
|
||||
{
|
||||
$stmts = self::$parser->parse('<?php
|
||||
/**
|
||||
* @param array<int, int> $a_list
|
||||
* @return array<int, int>
|
||||
*/
|
||||
function f(int ...$a_list) {
|
||||
return array_map(
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function (int $a) {
|
||||
return $a + 1;
|
||||
},
|
||||
$a_list
|
||||
);
|
||||
}
|
||||
|
||||
f(1);
|
||||
f(1, 2);
|
||||
f(1, 2, 3);
|
||||
|
||||
/**
|
||||
* @param string ...$a_list
|
||||
* @return void
|
||||
*/
|
||||
function g(string ...$a_list) {
|
||||
}
|
||||
');
|
||||
|
||||
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
|
||||
$context = new Context();
|
||||
$file_checker->visitAndAnalyzeMethods($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Psalm\Exception\CodeException
|
||||
* @expectedExceptionMessage InvalidScalarArgument
|
||||
* @return void
|
||||
*/
|
||||
public function testVariadicArrayBadParam()
|
||||
{
|
||||
$stmts = self::$parser->parse('<?php
|
||||
/**
|
||||
* @param array<int, int> $a_list
|
||||
* @return void
|
||||
*/
|
||||
function f(int ...$a_list) {
|
||||
}
|
||||
f(1, 2, "3");
|
||||
');
|
||||
|
||||
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
|
||||
$context = new Context();
|
||||
$file_checker->visitAndAnalyzeMethods($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
|
124
tests/VariadicTest.php
Normal file
124
tests/VariadicTest.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace Psalm\Tests;
|
||||
|
||||
use PhpParser\ParserFactory;
|
||||
use PHPUnit_Framework_TestCase;
|
||||
use Psalm\Checker\FileChecker;
|
||||
use Psalm\Config;
|
||||
use Psalm\Context;
|
||||
|
||||
class VariadicTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var \PhpParser\Parser */
|
||||
protected static $parser;
|
||||
|
||||
/** @var TestConfig */
|
||||
protected static $config;
|
||||
|
||||
/** @var \Psalm\Checker\ProjectChecker */
|
||||
protected $project_checker;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
FileChecker::clearCache();
|
||||
$this->project_checker = new \Psalm\Checker\ProjectChecker();
|
||||
$this->project_checker->setConfig(new TestConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testVariadic()
|
||||
{
|
||||
$stmts = self::$parser->parse('<?php
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
function f($req, $opt = null, ...$params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
f(1);
|
||||
f(1, 2);
|
||||
f(1, 2, 3);
|
||||
f(1, 2, 3, 4);
|
||||
f(1, 2, 3, 4, 5);
|
||||
');
|
||||
|
||||
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
|
||||
$context = new Context();
|
||||
$file_checker->visitAndAnalyzeMethods($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testVariadicArray()
|
||||
{
|
||||
$stmts = self::$parser->parse('<?php
|
||||
/**
|
||||
* @param array<int, int> $a_list
|
||||
* @return array<int, int>
|
||||
*/
|
||||
function f(int ...$a_list) {
|
||||
return array_map(
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function (int $a) {
|
||||
return $a + 1;
|
||||
},
|
||||
$a_list
|
||||
);
|
||||
}
|
||||
|
||||
f(1);
|
||||
f(1, 2);
|
||||
f(1, 2, 3);
|
||||
|
||||
/**
|
||||
* @param string ...$a_list
|
||||
* @return void
|
||||
*/
|
||||
function g(string ...$a_list) {
|
||||
}
|
||||
');
|
||||
|
||||
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
|
||||
$context = new Context();
|
||||
$file_checker->visitAndAnalyzeMethods($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Psalm\Exception\CodeException
|
||||
* @expectedExceptionMessage InvalidScalarArgument
|
||||
* @return void
|
||||
*/
|
||||
public function testVariadicArrayBadParam()
|
||||
{
|
||||
$stmts = self::$parser->parse('<?php
|
||||
/**
|
||||
* @param array<int, int> $a_list
|
||||
* @return void
|
||||
*/
|
||||
function f(int ...$a_list) {
|
||||
}
|
||||
f(1, 2, "3");
|
||||
');
|
||||
|
||||
$file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts);
|
||||
$context = new Context();
|
||||
$file_checker->visitAndAnalyzeMethods($context);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user