mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Allow omitting argument offsets for map-type overrides in phpstorm.meta
Fixes vimeo/psalm#8758
This commit is contained in:
parent
94dac9f9e7
commit
de96494fee
@ -89,15 +89,22 @@ class PhpStormMetaScanner
|
||||
if ($identifier instanceof PhpParser\Node\Expr\StaticCall
|
||||
&& $identifier->class instanceof PhpParser\Node\Name\FullyQualified
|
||||
&& $identifier->name instanceof PhpParser\Node\Identifier
|
||||
&& $identifier->getArgs()
|
||||
&& $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber
|
||||
&& (
|
||||
$identifier->getArgs() === []
|
||||
|| $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber
|
||||
)
|
||||
) {
|
||||
$meta_fq_classlike_name = implode('\\', $identifier->class->parts);
|
||||
|
||||
$meta_method_name = strtolower($identifier->name->name);
|
||||
|
||||
if ($map) {
|
||||
$offset = $identifier->getArgs()[0]->value->value;
|
||||
$offset = 0;
|
||||
if ($identifier->getArgs()
|
||||
&& $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber
|
||||
) {
|
||||
$offset = $identifier->getArgs()[0]->value->value;
|
||||
}
|
||||
|
||||
$codebase->methods->return_type_provider->registerClosure(
|
||||
$meta_fq_classlike_name,
|
||||
@ -248,13 +255,20 @@ class PhpStormMetaScanner
|
||||
|
||||
if ($identifier instanceof PhpParser\Node\Expr\FuncCall
|
||||
&& $identifier->name instanceof PhpParser\Node\Name\FullyQualified
|
||||
&& $identifier->getArgs()
|
||||
&& $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber
|
||||
&& (
|
||||
$identifier->getArgs() === []
|
||||
|| $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber
|
||||
)
|
||||
) {
|
||||
$function_id = strtolower(implode('\\', $identifier->name->parts));
|
||||
|
||||
if ($map) {
|
||||
$offset = $identifier->getArgs()[0]->value->value;
|
||||
$offset = 0;
|
||||
if ($identifier->getArgs()
|
||||
&& $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber
|
||||
) {
|
||||
$offset = $identifier->getArgs()[0]->value->value;
|
||||
}
|
||||
|
||||
$codebase->functions->return_type_provider->registerClosure(
|
||||
$function_id,
|
||||
|
@ -22,6 +22,9 @@ use function explode;
|
||||
use function getcwd;
|
||||
use function implode;
|
||||
use function reset;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
|
||||
@ -321,6 +324,12 @@ class StubTest extends TestCase
|
||||
*/
|
||||
public function create(string $s) {}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @psalm-suppress InvalidReturnType
|
||||
*/
|
||||
public function create2(string $s) {}
|
||||
|
||||
/**
|
||||
* @param mixed $s
|
||||
* @return mixed
|
||||
@ -342,6 +351,12 @@ class StubTest extends TestCase
|
||||
*/
|
||||
function create(string $s) {}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @psalm-suppress InvalidReturnType
|
||||
*/
|
||||
function create2(string $s) {}
|
||||
|
||||
/**
|
||||
* @param mixed $s
|
||||
* @return mixed
|
||||
@ -358,11 +373,19 @@ class StubTest extends TestCase
|
||||
$a1 = (new \Ns\MyClass)->creAte("object");
|
||||
$a2 = (new \Ns\MyClass)->creaTe("exception");
|
||||
|
||||
$y1 = (new \Ns\MyClass)->creAte2("object");
|
||||
$y2 = (new \Ns\MyClass)->creaTe2("exception");
|
||||
|
||||
$b1 = \Create("object");
|
||||
$b2 = \cReate("exception");
|
||||
|
||||
$e2 = \creAte(\LogicException::class);
|
||||
|
||||
$z1 = \Create2("object");
|
||||
$z2 = \cReate2("exception");
|
||||
|
||||
$x2 = \creAte2(\LogicException::class);
|
||||
|
||||
$c1 = (new \Ns\MyClass)->foo(5);
|
||||
$c2 = (new \Ns\MyClass)->bar(["hello"]);
|
||||
|
||||
@ -373,6 +396,57 @@ class StubTest extends TestCase
|
||||
|
||||
$context = new Context();
|
||||
$this->analyzeFile($file_path, $context);
|
||||
|
||||
$this->assertContextVars(
|
||||
[
|
||||
'$a1===' => 'stdClass',
|
||||
'$a2===' => 'Exception',
|
||||
|
||||
'$y1===' => 'stdClass',
|
||||
'$y2===' => 'Exception',
|
||||
|
||||
'$b1===' => 'stdClass',
|
||||
'$b2===' => 'Exception',
|
||||
|
||||
'$e2===' => 'LogicException',
|
||||
|
||||
'$z1===' => 'stdClass',
|
||||
'$z2===' => 'Exception',
|
||||
|
||||
'$x2===' => 'LogicException',
|
||||
|
||||
'$c1===' => "5",
|
||||
'$c2===' => "'hello'",
|
||||
|
||||
'$d1===' => "5",
|
||||
'$d2===' => "'hello'"
|
||||
],
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
/** @param array<string, string> $assertions */
|
||||
private function assertContextVars(array $assertions, Context $context): void
|
||||
{
|
||||
$actual_vars = [];
|
||||
foreach ($assertions as $var => $_) {
|
||||
$exact = false;
|
||||
|
||||
if ($var && strpos($var, '===') === strlen($var) - 3) {
|
||||
$var = substr($var, 0, -3);
|
||||
$exact = true;
|
||||
}
|
||||
|
||||
if (isset($context->vars_in_scope[$var])) {
|
||||
$value = $context->vars_in_scope[$var]->getId($exact);
|
||||
if ($exact) {
|
||||
$actual_vars[$var . '==='] = $value;
|
||||
} else {
|
||||
$actual_vars[$var] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->assertSame($assertions, $actual_vars);
|
||||
}
|
||||
|
||||
public function testNamespacedStubClass(): void
|
||||
|
13
tests/fixtures/stubs/phpstorm.meta.php
vendored
13
tests/fixtures/stubs/phpstorm.meta.php
vendored
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace PHPSTORM_META {
|
||||
|
||||
// tests with argument offset (0)
|
||||
override(\Ns\MyClass::crEate(0), map([
|
||||
'' => '@',
|
||||
'exception' => \Exception::class,
|
||||
@ -12,6 +13,18 @@ namespace PHPSTORM_META {
|
||||
'object' => \stdClass::class,
|
||||
]));
|
||||
|
||||
// tests without argument offset (0 by default)
|
||||
override(\Ns\MyClass::crEate2(), map([
|
||||
'' => '@',
|
||||
'exception' => \Exception::class,
|
||||
'object' => \stdClass::class,
|
||||
]));
|
||||
override(\create2(), map([
|
||||
'' => '@',
|
||||
'exception' => \Exception::class,
|
||||
'object' => \stdClass::class,
|
||||
]));
|
||||
|
||||
override(\Ns\MyClass::foO(0), type(0));
|
||||
override(\Ns\MyClass::Bar(0), elementType(0));
|
||||
override(\foo(0), type(0));
|
||||
|
Loading…
Reference in New Issue
Block a user