1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Merge pull request #9173 from shvlv/feature/support-class-constants-for-phpstorm-meta-override

This commit is contained in:
Bruce Weirdan 2023-01-25 12:31:17 -04:00 committed by GitHub
commit 0682adf3e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 0 deletions

View File

@ -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,40 @@ class PhpStormMetaScanner
} elseif ($array_item->value instanceof PhpParser\Node\Scalar\String_) {
$map[$array_item->key->value] = $array_item->value->value;
}
} elseif ($array_item
&& $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
) {
/** @var string|null $resolved_name */
$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_PRIVATE,
);
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;
}
}
}
}

View File

@ -317,6 +317,10 @@ class StubTest extends TestCase
'<?php
namespace Ns {
class MyClass {
public const OBJECT = "object";
private const EXCEPTION = "exception";
/**
* @return mixed
* @psalm-suppress InvalidReturnType
@ -328,6 +332,12 @@ class StubTest extends TestCase
* @psalm-suppress InvalidReturnType
*/
public function create2(string $s) {}
/**
* @return mixed
* @psalm-suppress InvalidReturnType
*/
public function create3(string $s) {}
/**
* @param mixed $s
@ -374,6 +384,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',

View File

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