Skip to content

Commit

Permalink
Merge pull request #8933 from jack-worman/ReflectionClass_implementsI…
Browse files Browse the repository at this point in the history
…nterface_assert

Closes #8920
  • Loading branch information
weirdan committed Dec 18, 2022
2 parents c529709 + e7d4d69 commit 7afeee5
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 15 deletions.
10 changes: 6 additions & 4 deletions stubs/Php80.phpstub
Expand Up @@ -89,15 +89,17 @@ class ReflectionClass implements Reflector {
public function getDocComment(): string|false {}

/**
* @param ReflectionClass|class-string $class
*
* @template J as object
* @param self<J>|class-string<J> $class
* @psalm-assert-if-true self<T&J> $this
* @psalm-pure
*/
public function isSubclassOf(self|string $class): bool {}

/**
* @param self|class-string $interface
*
* @template J as object
* @param self<J>|interface-string<J> $interface
* @psalm-assert-if-true self<T&J> $this
* @psalm-pure
*/
public function implementsInterface(self|string $interface): bool {}
Expand Down
25 changes: 15 additions & 10 deletions stubs/Reflection.phpstub
Expand Up @@ -147,15 +147,13 @@ class ReflectionClass implements Reflector {
public function getReflectionConstants(?int $filter = null): array {}

/**
* @return array<class-string, self>
*
* @return array<interface-string, self>
* @psalm-pure
*/
public function getInterfaces(): array {}

/**
* @return list<class-string>
*
* @return list<interface-string>
* @psalm-pure
*/
public function getInterfaceNames(): array {}
Expand Down Expand Up @@ -192,7 +190,12 @@ class ReflectionClass implements Reflector {
*/
public function getModifiers(): bool {}

/** @psalm-pure */
/**
* @template J as object
* @param J $object
* @psalm-assert-if-true T&J $object
* @psalm-pure
*/
public function isInstance(object $object): bool {}

/**
Expand Down Expand Up @@ -222,8 +225,9 @@ class ReflectionClass implements Reflector {
public function getParentClass() {}

/**
* @param ReflectionClass|class-string $class
*
* @template J as object
* @param self<J>|class-string<J> $class
* @psalm-assert-if-true self<T&J> $this
* @psalm-pure
*/
public function isSubclassOf($class): bool {}
Expand All @@ -245,8 +249,9 @@ class ReflectionClass implements Reflector {
public function isIterable(): bool {}

/**
* @param self|class-string $interface
*
* @template J as object
* @param self<J>|interface-string<J> $interface
* @psalm-assert-if-true self<T&J> $this
* @psalm-pure
*/
public function implementsInterface($interface): bool {}
Expand Down Expand Up @@ -275,7 +280,7 @@ class ReflectionClass implements Reflector {
public function getShortName(): string {}

/**
* @return ?array<string>
* @return ?list<trait-string>
* @psalm-ignore-nullable-return
* @psalm-pure
*/
Expand Down
47 changes: 47 additions & 0 deletions tests/ReflectionTest.php
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Psalm\Tests;

use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;

class ReflectionTest extends TestCase
{
use ValidCodeAnalysisTestTrait;

public function providerValidCodeParse(): iterable
{
yield 'ReflectionClass::isSubclassOf' => [
'code' => <<<'PHP'
<?php
$a = new ReflectionClass(stdClass::class);
if (!$a->isSubclassOf(Iterator::class)) {
throw new Exception();
}
PHP,
'assertions' => ['$a===' => 'ReflectionClass<stdClass&Iterator>'],
];
yield 'ReflectionClass::implementsInterface' => [
'code' => <<<'PHP'
<?php
$a = new ReflectionClass(stdClass::class);
if (!$a->implementsInterface(Iterator::class)) {
throw new Exception();
}
PHP,
'assertions' => ['$a===' => 'ReflectionClass<stdClass&Iterator>'],
];
yield 'ReflectionClass::isInstance' => [
'code' => <<<'PHP'
<?php
$a = new stdClass();
$b = new ReflectionClass(Iterator::class);
if (!$b->isInstance($a)) {
throw new Exception();
}
PHP,
'assertions' => ['$a===' => 'Iterator&stdClass'],
];
}
}
10 changes: 9 additions & 1 deletion tests/Traits/ValidCodeAnalysisTestTrait.php
Expand Up @@ -18,7 +18,15 @@
trait ValidCodeAnalysisTestTrait
{
/**
* @return iterable<string,array{code:string,assertions?:array<string,string>,ignored_issues?:list<string>,php_version?:string}>
* @return iterable<
* string,
* array{
* code: string,
* assertions?: array<string, string>,
* ignored_issues?: list<string>,
* php_version?: string,
* }
* >
*/
abstract public function providerValidCodeParse(): iterable;

Expand Down

0 comments on commit 7afeee5

Please sign in to comment.