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

ExtendedMethodReflection #1403

Merged
merged 1 commit into from Jun 7, 2022
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
4 changes: 2 additions & 2 deletions src/Reflection/Annotations/AnnotationMethodReflection.php
Expand Up @@ -4,14 +4,14 @@

use PHPStan\Reflection\ClassMemberReflection;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\FunctionVariant;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptor;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Type;

class AnnotationMethodReflection implements MethodReflection
class AnnotationMethodReflection implements ExtendedMethodReflection
{

/** @var FunctionVariant[]|null */
Expand Down
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Reflection\Annotations;

use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\MethodsClassReflectionExtension;
use PHPStan\Type\Generic\TemplateTypeHelper;
Expand All @@ -11,7 +12,7 @@
class AnnotationsMethodsClassReflectionExtension implements MethodsClassReflectionExtension
{

/** @var MethodReflection[][] */
/** @var ExtendedMethodReflection[][] */
private array $methods = [];

public function hasMethod(ClassReflection $classReflection, string $methodName): bool
Expand All @@ -27,6 +28,9 @@ public function hasMethod(ClassReflection $classReflection, string $methodName):
return isset($this->methods[$classReflection->getCacheKey()][$methodName]);
}

/**
* @return ExtendedMethodReflection
*/
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
{
return $this->methods[$classReflection->getCacheKey()][$methodName];
Expand All @@ -36,7 +40,7 @@ private function findClassReflectionWithMethod(
ClassReflection $classReflection,
ClassReflection $declaringClass,
string $methodName,
): ?MethodReflection
): ?ExtendedMethodReflection
{
$methodTags = $classReflection->getMethodTags();
if (isset($methodTags[$methodName])) {
Expand Down
19 changes: 14 additions & 5 deletions src/Reflection/ClassReflection.php
Expand Up @@ -63,7 +63,7 @@
class ClassReflection
{

/** @var MethodReflection[] */
/** @var ExtendedMethodReflection[] */
private array $methods = [];

/** @var PropertyReflection[] */
Expand Down Expand Up @@ -365,7 +365,7 @@ public function hasMethod(string $methodName): bool
return false;
}

public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection
public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): ExtendedMethodReflection
{
$key = $methodName;
if ($scope->isInClass()) {
Expand All @@ -377,7 +377,7 @@ public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope):
continue;
}

$method = $extension->getMethod($this, $methodName);
$method = $this->wrapExtendedMethod($extension->getMethod($this, $methodName));
if ($scope->canCallMethod($method)) {
return $this->methods[$key] = $method;
}
Expand All @@ -392,12 +392,21 @@ public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope):
return $this->methods[$key];
}

private function wrapExtendedMethod(MethodReflection $method): ExtendedMethodReflection
{
if ($method instanceof ExtendedMethodReflection) {
return $method;
}

return new WrappedExtendedMethodReflection($method);
}

public function hasNativeMethod(string $methodName): bool
{
return $this->getPhpExtension()->hasNativeMethod($this, $methodName);
}

public function getNativeMethod(string $methodName): MethodReflection
public function getNativeMethod(string $methodName): ExtendedMethodReflection
{
if (!$this->hasNativeMethod($methodName)) {
throw new MissingMethodFromReflectionException($this->getName(), $methodName);
Expand All @@ -410,7 +419,7 @@ public function hasConstructor(): bool
return $this->findConstructor() !== null;
}

public function getConstructor(): MethodReflection
public function getConstructor(): ExtendedMethodReflection
{
$constructor = $this->findConstructor();
if ($constructor === null) {
Expand Down
19 changes: 19 additions & 0 deletions src/Reflection/ExtendedMethodReflection.php
@@ -0,0 +1,19 @@
<?php declare(strict_types = 1);

namespace PHPStan\Reflection;

/**
* The purpose of this interface is to be able to
* answer more questions about methods
* without breaking backward compatibility
* with existing MethodsClassReflectionExtension.
*
* Developers are meant to only use the MethodReflection
* and its methods in their code.
*
* Methods on ExtendedMethodReflection are subject to change.
*/
interface ExtendedMethodReflection extends MethodReflection
{

}
4 changes: 2 additions & 2 deletions src/Reflection/Native/NativeMethodReflection.php
Expand Up @@ -4,8 +4,8 @@

use PHPStan\Reflection\ClassMemberReflection;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\MethodPrototypeReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorWithPhpDocs;
use PHPStan\Reflection\Php\BuiltinMethodReflection;
use PHPStan\Reflection\ReflectionProvider;
Expand All @@ -16,7 +16,7 @@
use ReflectionException;
use function strtolower;

class NativeMethodReflection implements MethodReflection
class NativeMethodReflection implements ExtendedMethodReflection
{

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Reflection/Php/EnumCasesMethodReflection.php
Expand Up @@ -4,15 +4,15 @@

use PHPStan\Reflection\ClassMemberReflection;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\FunctionVariant;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptor;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Type;

class EnumCasesMethodReflection implements MethodReflection
class EnumCasesMethodReflection implements ExtendedMethodReflection
{

public function __construct(private ClassReflection $declaringClass, private Type $returnType)
Expand Down
12 changes: 8 additions & 4 deletions src/Reflection/Php/PhpClassReflectionExtension.php
Expand Up @@ -19,6 +19,7 @@
use PHPStan\Reflection\Annotations\AnnotationsMethodsClassReflectionExtension;
use PHPStan\Reflection\Annotations\AnnotationsPropertiesClassReflectionExtension;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\FunctionVariantWithPhpDocs;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\MethodsClassReflectionExtension;
Expand Down Expand Up @@ -68,10 +69,10 @@ class PhpClassReflectionExtension
/** @var PhpPropertyReflection[][] */
private array $nativeProperties = [];

/** @var MethodReflection[][] */
/** @var ExtendedMethodReflection[][] */
private array $methodsIncludingAnnotations = [];

/** @var MethodReflection[][] */
/** @var ExtendedMethodReflection[][] */
private array $nativeMethods = [];

/** @var array<string, array<string, Type>> */
Expand Down Expand Up @@ -375,6 +376,9 @@ public function hasMethod(ClassReflection $classReflection, string $methodName):
return $classReflection->getNativeReflection()->hasMethod($methodName);
}

/**
* @return ExtendedMethodReflection
*/
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
{
if (isset($this->methodsIncludingAnnotations[$classReflection->getCacheKey()][$methodName])) {
Expand Down Expand Up @@ -411,7 +415,7 @@ public function hasNativeMethod(ClassReflection $classReflection, string $method
return false;
}

public function getNativeMethod(ClassReflection $classReflection, string $methodName): MethodReflection
public function getNativeMethod(ClassReflection $classReflection, string $methodName): ExtendedMethodReflection
{
if (isset($this->nativeMethods[$classReflection->getCacheKey()][$methodName])) {
return $this->nativeMethods[$classReflection->getCacheKey()][$methodName];
Expand Down Expand Up @@ -450,7 +454,7 @@ private function createMethod(
ClassReflection $classReflection,
BuiltinMethodReflection $methodReflection,
bool $includingAnnotations,
): MethodReflection
): ExtendedMethodReflection
{
if ($includingAnnotations && $this->annotationsMethodsClassReflectionExtension->hasMethod($classReflection, $methodReflection->getName())) {
$hierarchyDistances = $classReflection->getClassHierarchyDistances();
Expand Down
4 changes: 2 additions & 2 deletions src/Reflection/Php/PhpMethodReflection.php
Expand Up @@ -13,10 +13,10 @@
use PHPStan\Parser\Parser;
use PHPStan\Reflection\ClassMemberReflection;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\FunctionVariantWithPhpDocs;
use PHPStan\Reflection\InitializerExprTypeResolver;
use PHPStan\Reflection\MethodPrototypeReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParameterReflectionWithPhpDocs;
use PHPStan\Reflection\ParametersAcceptor;
use PHPStan\Reflection\ParametersAcceptorWithPhpDocs;
Expand Down Expand Up @@ -44,7 +44,7 @@
use const PHP_VERSION_ID;

/** @api */
class PhpMethodReflection implements MethodReflection
class PhpMethodReflection implements ExtendedMethodReflection
{

/** @var PhpParameterReflection[]|null */
Expand Down
85 changes: 85 additions & 0 deletions src/Reflection/WrappedExtendedMethodReflection.php
@@ -0,0 +1,85 @@
<?php declare(strict_types = 1);

namespace PHPStan\Reflection;

use PHPStan\TrinaryLogic;
use PHPStan\Type\Type;

class WrappedExtendedMethodReflection implements ExtendedMethodReflection
{

public function __construct(private MethodReflection $method)
{
}

public function getDeclaringClass(): ClassReflection
{
return $this->method->getDeclaringClass();
}

public function isStatic(): bool
{
return $this->method->isStatic();
}

public function isPrivate(): bool
{
return $this->method->isPrivate();
}

public function isPublic(): bool
{
return $this->method->isPublic();
}

public function getDocComment(): ?string
{
return $this->method->getDocComment();
}

public function getName(): string
{
return $this->method->getName();
}

public function getPrototype(): ClassMemberReflection
{
return $this->method->getPrototype();
}

public function getVariants(): array
{
return $this->method->getVariants();
}

public function isDeprecated(): TrinaryLogic
{
return $this->method->isDeprecated();
}

public function getDeprecatedDescription(): ?string
{
return $this->method->getDeprecatedDescription();
}

public function isFinal(): TrinaryLogic
{
return $this->method->isFinal();
}

public function isInternal(): TrinaryLogic
{
return $this->method->isInternal();
}

public function getThrowType(): ?Type
{
return $this->method->getThrowType();
}

public function hasSideEffects(): TrinaryLogic
{
return $this->method->hasSideEffects();
}

}
4 changes: 2 additions & 2 deletions src/Rules/Methods/MethodSignatureRule.php
Expand Up @@ -6,7 +6,7 @@
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassMethodNode;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\ParameterReflectionWithPhpDocs;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\ParametersAcceptorWithPhpDocs;
Expand Down Expand Up @@ -120,7 +120,7 @@ public function processNode(Node $node, Scope $scope): array
}

/**
* @return MethodReflection[]
* @return ExtendedMethodReflection[]
*/
private function collectParentMethods(string $methodName, ClassReflection $class): array
{
Expand Down