Skip to content

Commit

Permalink
Merge pull request #9173 from shvlv/feature/support-class-constants-f…
Browse files Browse the repository at this point in the history
…or-phpstorm-meta-override
  • Loading branch information
weirdan committed Jan 25, 2023
2 parents 242fbf4 + eca7079 commit 0682adf
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/Psalm/Internal/Scanner/PhpStormMetaScanner.php
Expand Up @@ -12,6 +12,7 @@
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use ReflectionProperty;

use function count;
use function implode;
Expand Down Expand Up @@ -63,6 +64,40 @@ public static function handleOverride(array $args, Codebase $codebase): void
} 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;
}
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions tests/StubTest.php
Expand Up @@ -317,6 +317,10 @@ public function testPhpStormMetaParsingFile(): void
'<?php
namespace Ns {
class MyClass {
public const OBJECT = "object";
private const EXCEPTION = "exception";
/**
* @return mixed
* @psalm-suppress InvalidReturnType
Expand All @@ -328,6 +332,12 @@ public function create(string $s) {}
* @psalm-suppress InvalidReturnType
*/
public function create2(string $s) {}
/**
* @return mixed
* @psalm-suppress InvalidReturnType
*/
public function create3(string $s) {}
/**
* @param mixed $s
Expand Down Expand Up @@ -374,6 +384,9 @@ function bar(array $a) {}
$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");
Expand Down Expand Up @@ -404,6 +417,9 @@ function bar(array $a) {}
'$y1===' => 'stdClass',
'$y2===' => 'Exception',

'$const1===' => 'stdClass',
'$const2===' => 'Exception',

'$b1===' => 'stdClass',
'$b2===' => 'Exception',

Expand Down
7 changes: 7 additions & 0 deletions tests/fixtures/stubs/phpstorm.meta.php
Expand Up @@ -25,6 +25,13 @@
'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));
Expand Down

0 comments on commit 0682adf

Please sign in to comment.