mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Parse class constant for PhpStorm Meta override
This commit is contained in:
parent
e784128902
commit
d6aff3ed20
@ -12,6 +12,7 @@ use Psalm\Type\Atomic\TArray;
|
||||
use Psalm\Type\Atomic\TKeyedArray;
|
||||
use Psalm\Type\Atomic\TNamedObject;
|
||||
use Psalm\Type\Union;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function count;
|
||||
use function implode;
|
||||
@ -63,6 +64,38 @@ class PhpStormMetaScanner
|
||||
} elseif ($array_item->value instanceof PhpParser\Node\Scalar\String_) {
|
||||
$map[$array_item->key->value] = $array_item->value->value;
|
||||
}
|
||||
} elseif ($array_item->key instanceof PhpParser\Node\Expr\ClassConstFetch
|
||||
&& $array_item->key->class instanceof PhpParser\Node\Name\FullyQualified
|
||||
&& $array_item->key->name instanceof PhpParser\Node\Identifier
|
||||
) {
|
||||
$resolved_name = $array_item->key->class->getAttribute('resolvedName');
|
||||
if (!$resolved_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$constant_type = $codebase->classlikes->getClassConstantType(
|
||||
$resolved_name,
|
||||
$array_item->key->name->name,
|
||||
ReflectionProperty::IS_PUBLIC,
|
||||
);
|
||||
|
||||
if (!$constant_type instanceof Union || !$constant_type->isSingleStringLiteral()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$meta_key = $constant_type->getSingleStringLiteral()->value;
|
||||
|
||||
if ($array_item->value instanceof PhpParser\Node\Expr\ClassConstFetch
|
||||
&& $array_item->value->class instanceof PhpParser\Node\Name\FullyQualified
|
||||
&& $array_item->value->name instanceof PhpParser\Node\Identifier
|
||||
&& strtolower($array_item->value->name->name)
|
||||
) {
|
||||
$map[$meta_key] = new Union([
|
||||
new TNamedObject(implode('\\', $array_item->value->class->parts)),
|
||||
]);
|
||||
} elseif ($array_item->value instanceof PhpParser\Node\Scalar\String_) {
|
||||
$map[$meta_key] = $array_item->value->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,6 +317,10 @@ class StubTest extends TestCase
|
||||
'<?php
|
||||
namespace Ns {
|
||||
class MyClass {
|
||||
|
||||
public const OBJECT = "object";
|
||||
public const EXCEPTION = "exception";
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @psalm-suppress InvalidReturnType
|
||||
@ -329,6 +333,12 @@ class StubTest extends TestCase
|
||||
*/
|
||||
public function create2(string $s) {}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @psalm-suppress InvalidReturnType
|
||||
*/
|
||||
public function create3(string $s) {}
|
||||
|
||||
/**
|
||||
* @param mixed $s
|
||||
* @return mixed
|
||||
@ -375,6 +385,9 @@ class StubTest extends TestCase
|
||||
$y1 = (new \Ns\MyClass)->creAte2("object");
|
||||
$y2 = (new \Ns\MyClass)->creaTe2("exception");
|
||||
|
||||
$const1 = (new \Ns\MyClass)->creAte3(\Ns\MyClass::OBJECT);
|
||||
$const2 = (new \Ns\MyClass)->creaTe3("exception");
|
||||
|
||||
$b1 = \Create("object");
|
||||
$b2 = \cReate("exception");
|
||||
|
||||
@ -404,6 +417,9 @@ class StubTest extends TestCase
|
||||
'$y1===' => 'stdClass',
|
||||
'$y2===' => 'Exception',
|
||||
|
||||
'$const1===' => 'stdClass',
|
||||
'$const2===' => 'Exception',
|
||||
|
||||
'$b1===' => 'stdClass',
|
||||
'$b2===' => 'Exception',
|
||||
|
||||
|
7
tests/fixtures/stubs/phpstorm.meta.php
vendored
7
tests/fixtures/stubs/phpstorm.meta.php
vendored
@ -25,6 +25,13 @@ namespace PHPSTORM_META {
|
||||
'object' => \stdClass::class,
|
||||
]));
|
||||
|
||||
// tests with class constant as key
|
||||
override(\Ns\MyClass::crEate3(), map([
|
||||
'' => '@',
|
||||
\Ns\MyClass::EXCEPTION => \Exception::class,
|
||||
\Ns\MyClass::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