Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing getAttributes for all supported reflectors #643

Merged
merged 1 commit into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 32 additions & 1 deletion conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1494,10 +1494,41 @@ services:
- phpstan.broker.dynamicStaticMethodReturnTypeExtension

-
class: PHPStan\Type\Php\ReflectionClassGetAttributesMethodReturnTypeExtension
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
arguments:
className: ReflectionClass
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension

-
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
arguments:
className: ReflectionClassConstant
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension

-
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
arguments:
className: ReflectionFunctionAbstract
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension

-
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
arguments:
className: ReflectionParameter
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension

-
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
arguments:
className: ReflectionProperty
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension


exceptionTypeResolver:
class: PHPStan\Rules\Exceptions\ExceptionTypeResolver
factory: @PHPStan\Rules\Exceptions\DefaultExceptionTypeResolver
Expand Down
5 changes: 4 additions & 1 deletion conf/config.stubFiles.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ parameters:
stubFiles:
- ../stubs/ReflectionAttribute.stub
- ../stubs/ReflectionClass.stub
- ../stubs/ReflectionClassConstant.stub
- ../stubs/ReflectionFunctionAbstract.stub
- ../stubs/ReflectionParameter.stub
- ../stubs/ReflectionProperty.stub
- ../stubs/iterable.stub
- ../stubs/ArrayObject.stub
- ../stubs/WeakReference.stub
- ../stubs/ext-ds.stub
- ../stubs/PDOStatement.stub
- ../stubs/ReflectionFunctionAbstract.stub
- ../stubs/date.stub
- ../stubs/zip.stub
- ../stubs/dom.stub
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,23 @@
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;

class ReflectionClassGetAttributesMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension
class ReflectionGetAttributesMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension
{

/** @var class-string */
private string $className;

/**
* @param class-string $className One of reflection classes: https://www.php.net/manual/en/book.reflection.php
*/
public function __construct(string $className)
{
$this->className = $className;
}

public function getClass(): string
{
return \ReflectionClass::class;
return $this->className;
}

public function isMethodSupported(MethodReflection $methodReflection): bool
Expand Down
11 changes: 11 additions & 0 deletions stubs/ReflectionClassConstant.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

class ReflectionClassConstant
{
/**
* @return array<ReflectionAttribute<object>>
*/
public function getAttributes(?string $name = null, int $flags = 0)
{
}
}
6 changes: 6 additions & 0 deletions stubs/ReflectionFunctionAbstract.stub
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@ abstract class ReflectionFunctionAbstract
*/
public function getFileName () {}

/**
* @return array<ReflectionAttribute<object>>
*/
public function getAttributes(?string $name = null, int $flags = 0)
{
}
}
11 changes: 11 additions & 0 deletions stubs/ReflectionParameter.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

class ReflectionParameter
{
/**
* @return array<ReflectionAttribute<object>>
*/
public function getAttributes(?string $name = null, int $flags = 0)
{
}
}
11 changes: 11 additions & 0 deletions stubs/ReflectionProperty.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

class ReflectionProperty
{
/**
* @return array<ReflectionAttribute<object>>
*/
public function getAttributes(?string $name = null, int $flags = 0)
{
}
}
74 changes: 51 additions & 23 deletions tests/PHPStan/Analyser/data/reflectionclass-issue-5511-php8.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,63 @@ class Abc
{
}

#[Abc]
class X
{
}

/**
* @param string $str
* @param class-string $className
* @param class-string<Abc> $genericClassName
*/
function testGetAttributes(string $str, string $className, string $genericClassName): void
function testGetAttributes(
\ReflectionClass $reflectionClass,
\ReflectionMethod $reflectionMethod,
\ReflectionParameter $reflectionParameter,
\ReflectionProperty $reflectionProperty,
\ReflectionClassConstant $reflectionClassConstant,
\ReflectionFunction $reflectionFunction,
string $str,
string $className,
string $genericClassName
): void
{
$class = new \ReflectionClass(X::class);

$attrsAll = $class->getAttributes();
$attrsAbc1 = $class->getAttributes(Abc::class);
$attrsAbc2 = $class->getAttributes(Abc::class, \ReflectionAttribute::IS_INSTANCEOF);
$attrsGCN = $class->getAttributes($genericClassName);
$attrsCN = $class->getAttributes($className);
$attrsStr = $class->getAttributes($str);
$attrsNonsense = $class->getAttributes("some random string");

assertType('array<ReflectionAttribute<object>>', $attrsAll);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $attrsAbc1);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $attrsAbc2);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $attrsGCN);
assertType('array<ReflectionAttribute<object>>', $attrsCN);
assertType('array<ReflectionAttribute<object>>', $attrsStr);
assertType('array<ReflectionAttribute<some random string>>', $attrsNonsense);
$classAll = $reflectionClass->getAttributes();
$classAbc1 = $reflectionClass->getAttributes(Abc::class);
$classAbc2 = $reflectionClass->getAttributes(Abc::class, \ReflectionAttribute::IS_INSTANCEOF);
$classGCN = $reflectionClass->getAttributes($genericClassName);
$classCN = $reflectionClass->getAttributes($className);
$classStr = $reflectionClass->getAttributes($str);
$classNonsense = $reflectionClass->getAttributes("some random string");

assertType('array<ReflectionAttribute<object>>', $classAll);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $classAbc1);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $classAbc2);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $classGCN);
assertType('array<ReflectionAttribute<object>>', $classCN);
assertType('array<ReflectionAttribute<object>>', $classStr);
assertType('array<ReflectionAttribute<some random string>>', $classNonsense);

$methodAll = $reflectionMethod->getAttributes();
$methodAbc = $reflectionMethod->getAttributes(Abc::class);
assertType('array<ReflectionAttribute<object>>', $methodAll);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $methodAbc);

$paramAll = $reflectionParameter->getAttributes();
$paramAbc = $reflectionParameter->getAttributes(Abc::class);
assertType('array<ReflectionAttribute<object>>', $paramAll);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $paramAbc);

$propAll = $reflectionProperty->getAttributes();
$propAbc = $reflectionProperty->getAttributes(Abc::class);
assertType('array<ReflectionAttribute<object>>', $propAll);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $propAbc);

$constAll = $reflectionClassConstant->getAttributes();
$constAbc = $reflectionClassConstant->getAttributes(Abc::class);
assertType('array<ReflectionAttribute<object>>', $constAll);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $constAbc);

$funcAll = $reflectionFunction->getAttributes();
$funcAbc = $reflectionFunction->getAttributes(Abc::class);
assertType('array<ReflectionAttribute<object>>', $funcAll);
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $funcAbc);
}

/**
Expand Down