From d65138a11f0654b710a27b4b563bff2ccf0b2c1b Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sun, 4 Aug 2024 14:24:21 +0200 Subject: [PATCH] ExtendedPropertyReflection --- src/Analyser/MutatingScope.php | 3 +- src/Analyser/Scope.php | 4 +- .../AnnotationPropertyReflection.php | 4 +- ...ionsPropertiesClassReflectionExtension.php | 8 +- src/Reflection/ClassReflection.php | 15 +++- .../Dummy/ChangedTypePropertyReflection.php | 6 +- .../Dummy/DummyPropertyReflection.php | 4 +- src/Reflection/ExtendedPropertyReflection.php | 22 +++++ src/Reflection/Php/EnumPropertyReflection.php | 4 +- ...mUnresolvedPropertyPrototypeReflection.php | 6 +- .../Php/PhpClassReflectionExtension.php | 8 +- src/Reflection/Php/PhpPropertyReflection.php | 4 +- .../Php/SimpleXMLElementProperty.php | 4 +- .../Php/UniversalObjectCrateProperty.php | 4 +- ...endsPropertiesClassReflectionExtension.php | 6 +- src/Reflection/ResolvedPropertyReflection.php | 4 +- ...kUnresolvedPropertyPrototypeReflection.php | 12 +-- ...eUnresolvedPropertyPrototypeReflection.php | 12 +-- .../IntersectionTypePropertyReflection.php | 3 +- ...eUnresolvedPropertyPrototypeReflection.php | 7 +- .../Type/UnionTypePropertyReflection.php | 3 +- ...eUnresolvedPropertyPrototypeReflection.php | 7 +- .../UnresolvedPropertyPrototypeReflection.php | 6 +- .../WrappedExtendedPropertyReflection.php | 80 +++++++++++++++++++ src/Reflection/WrapperPropertyReflection.php | 4 +- src/Rules/Api/BcUncoveredInterface.php | 2 + .../Properties/FoundPropertyReflection.php | 6 +- src/Type/ObjectShapePropertyReflection.php | 4 +- src/Type/Type.php | 4 + 29 files changed, 193 insertions(+), 63 deletions(-) create mode 100644 src/Reflection/ExtendedPropertyReflection.php create mode 100644 src/Reflection/WrappedExtendedPropertyReflection.php diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index fca60cc869..c3c3b2ee25 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -59,6 +59,7 @@ use PHPStan\Reflection\ConstantReflection; use PHPStan\Reflection\Dummy\DummyConstructorReflection; use PHPStan\Reflection\ExtendedMethodReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\FunctionReflection; use PHPStan\Reflection\InitializerExprContext; use PHPStan\Reflection\InitializerExprTypeResolver; @@ -5687,7 +5688,7 @@ private function methodCallReturnType(Type $typeWithMethod, string $methodName, } /** @api */ - public function getPropertyReflection(Type $typeWithProperty, string $propertyName): ?PropertyReflection + public function getPropertyReflection(Type $typeWithProperty, string $propertyName): ?ExtendedPropertyReflection { if ($typeWithProperty instanceof UnionType) { $newTypes = []; diff --git a/src/Analyser/Scope.php b/src/Analyser/Scope.php index e26aa8853a..53ceaa3443 100644 --- a/src/Analyser/Scope.php +++ b/src/Analyser/Scope.php @@ -10,12 +10,12 @@ use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ConstantReflection; use PHPStan\Reflection\ExtendedMethodReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\FunctionReflection; use PHPStan\Reflection\MethodReflection; use PHPStan\Reflection\NamespaceAnswerer; use PHPStan\Reflection\ParameterReflection; use PHPStan\Reflection\ParametersAcceptor; -use PHPStan\Reflection\PropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; use PHPStan\Type\TypeWithClassName; @@ -71,7 +71,7 @@ public function getDefinedVariables(): array; public function hasConstant(Name $name): bool; - public function getPropertyReflection(Type $typeWithProperty, string $propertyName): ?PropertyReflection; + public function getPropertyReflection(Type $typeWithProperty, string $propertyName): ?ExtendedPropertyReflection; public function getMethodReflection(Type $typeWithMethod, string $methodName): ?ExtendedMethodReflection; diff --git a/src/Reflection/Annotations/AnnotationPropertyReflection.php b/src/Reflection/Annotations/AnnotationPropertyReflection.php index e6506a4a21..78b822ca3a 100644 --- a/src/Reflection/Annotations/AnnotationPropertyReflection.php +++ b/src/Reflection/Annotations/AnnotationPropertyReflection.php @@ -3,11 +3,11 @@ namespace PHPStan\Reflection\Annotations; use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; -final class AnnotationPropertyReflection implements PropertyReflection +final class AnnotationPropertyReflection implements ExtendedPropertyReflection { public function __construct( diff --git a/src/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.php b/src/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.php index 3a12dcdefb..0d5cdf4898 100644 --- a/src/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.php +++ b/src/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.php @@ -3,6 +3,7 @@ namespace PHPStan\Reflection\Annotations; use PHPStan\Reflection\ClassReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\PropertiesClassReflectionExtension; use PHPStan\Reflection\PropertyReflection; use PHPStan\Type\Generic\TemplateTypeHelper; @@ -12,7 +13,7 @@ final class AnnotationsPropertiesClassReflectionExtension implements PropertiesClassReflectionExtension { - /** @var PropertyReflection[][] */ + /** @var ExtendedPropertyReflection[][] */ private array $properties = []; public function hasProperty(ClassReflection $classReflection, string $propertyName): bool @@ -28,6 +29,9 @@ public function hasProperty(ClassReflection $classReflection, string $propertyNa return isset($this->properties[$classReflection->getCacheKey()][$propertyName]); } + /** + * @return ExtendedPropertyReflection + */ public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection { return $this->properties[$classReflection->getCacheKey()][$propertyName]; @@ -37,7 +41,7 @@ private function findClassReflectionWithProperty( ClassReflection $classReflection, ClassReflection $declaringClass, string $propertyName, - ): ?PropertyReflection + ): ?ExtendedPropertyReflection { $propertyTags = $classReflection->getPropertyTags(); if (isset($propertyTags[$propertyName])) { diff --git a/src/Reflection/ClassReflection.php b/src/Reflection/ClassReflection.php index 4c7410e2f0..390092a857 100644 --- a/src/Reflection/ClassReflection.php +++ b/src/Reflection/ClassReflection.php @@ -79,7 +79,7 @@ class ClassReflection /** @var ExtendedMethodReflection[] */ private array $methods = []; - /** @var PropertyReflection[] */ + /** @var ExtendedPropertyReflection[] */ private array $properties = []; /** @var ClassConstantReflection[] */ @@ -537,6 +537,15 @@ private function wrapExtendedMethod(MethodReflection $method): ExtendedMethodRef return new WrappedExtendedMethodReflection($method); } + private function wrapExtendedProperty(PropertyReflection $method): ExtendedPropertyReflection + { + if ($method instanceof ExtendedPropertyReflection) { + return $method; + } + + return new WrappedExtendedPropertyReflection($method); + } + public function hasNativeMethod(string $methodName): bool { return $this->getPhpExtension()->hasNativeMethod($this, $methodName); @@ -619,7 +628,7 @@ public function evictPrivateSymbols(): void $this->getPhpExtension()->evictPrivateSymbols($this->getCacheKey()); } - public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): ExtendedPropertyReflection { if ($this->isEnum()) { return $this->getNativeProperty($propertyName); @@ -640,7 +649,7 @@ public function getProperty(string $propertyName, ClassMemberAccessAnswerer $sco continue; } - $property = $extension->getProperty($this, $propertyName); + $property = $this->wrapExtendedProperty($extension->getProperty($this, $propertyName)); if ($scope->canAccessProperty($property)) { return $this->properties[$key] = $property; } diff --git a/src/Reflection/Dummy/ChangedTypePropertyReflection.php b/src/Reflection/Dummy/ChangedTypePropertyReflection.php index 7391715313..c4715616e7 100644 --- a/src/Reflection/Dummy/ChangedTypePropertyReflection.php +++ b/src/Reflection/Dummy/ChangedTypePropertyReflection.php @@ -3,7 +3,7 @@ namespace PHPStan\Reflection\Dummy; use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\WrapperPropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; @@ -11,7 +11,7 @@ final class ChangedTypePropertyReflection implements WrapperPropertyReflection { - public function __construct(private ClassReflection $declaringClass, private PropertyReflection $reflection, private Type $readableType, private Type $writableType) + public function __construct(private ClassReflection $declaringClass, private ExtendedPropertyReflection $reflection, private Type $readableType, private Type $writableType) { } @@ -80,7 +80,7 @@ public function isInternal(): TrinaryLogic return $this->reflection->isInternal(); } - public function getOriginalReflection(): PropertyReflection + public function getOriginalReflection(): ExtendedPropertyReflection { return $this->reflection; } diff --git a/src/Reflection/Dummy/DummyPropertyReflection.php b/src/Reflection/Dummy/DummyPropertyReflection.php index 90ef29825e..55addb6d90 100644 --- a/src/Reflection/Dummy/DummyPropertyReflection.php +++ b/src/Reflection/Dummy/DummyPropertyReflection.php @@ -3,14 +3,14 @@ namespace PHPStan\Reflection\Dummy; use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\ReflectionProviderStaticAccessor; use PHPStan\TrinaryLogic; use PHPStan\Type\MixedType; use PHPStan\Type\Type; use stdClass; -final class DummyPropertyReflection implements PropertyReflection +final class DummyPropertyReflection implements ExtendedPropertyReflection { public function getDeclaringClass(): ClassReflection diff --git a/src/Reflection/ExtendedPropertyReflection.php b/src/Reflection/ExtendedPropertyReflection.php new file mode 100644 index 0000000000..fbeac4f3a7 --- /dev/null +++ b/src/Reflection/ExtendedPropertyReflection.php @@ -0,0 +1,22 @@ +property; } - public function getTransformedProperty(): PropertyReflection + public function getTransformedProperty(): ExtendedPropertyReflection { return $this->property; } diff --git a/src/Reflection/Php/PhpClassReflectionExtension.php b/src/Reflection/Php/PhpClassReflectionExtension.php index d99bbf8955..7887f43191 100644 --- a/src/Reflection/Php/PhpClassReflectionExtension.php +++ b/src/Reflection/Php/PhpClassReflectionExtension.php @@ -21,13 +21,13 @@ use PHPStan\Reflection\Assertions; use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ExtendedMethodReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\FunctionVariantWithPhpDocs; use PHPStan\Reflection\MethodReflection; use PHPStan\Reflection\MethodsClassReflectionExtension; use PHPStan\Reflection\Native\NativeMethodReflection; use PHPStan\Reflection\Native\NativeParameterWithPhpDocsReflection; use PHPStan\Reflection\PropertiesClassReflectionExtension; -use PHPStan\Reflection\PropertyReflection; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Reflection\SignatureMap\FunctionSignature; use PHPStan\Reflection\SignatureMap\ParameterSignature; @@ -64,7 +64,7 @@ final class PhpClassReflectionExtension implements PropertiesClassReflectionExtension, MethodsClassReflectionExtension { - /** @var PropertyReflection[][] */ + /** @var ExtendedPropertyReflection[][] */ private array $propertiesIncludingAnnotations = []; /** @var PhpPropertyReflection[][] */ @@ -152,7 +152,7 @@ public function hasProperty(ClassReflection $classReflection, string $propertyNa return $classReflection->getNativeReflection()->hasProperty($propertyName); } - public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection + public function getProperty(ClassReflection $classReflection, string $propertyName): ExtendedPropertyReflection { if (!isset($this->propertiesIncludingAnnotations[$classReflection->getCacheKey()][$propertyName])) { $this->propertiesIncludingAnnotations[$classReflection->getCacheKey()][$propertyName] = $this->createProperty($classReflection, $propertyName, true); @@ -176,7 +176,7 @@ private function createProperty( ClassReflection $classReflection, string $propertyName, bool $includingAnnotations, - ): PropertyReflection + ): ExtendedPropertyReflection { $propertyReflection = $classReflection->getNativeReflection()->getProperty($propertyName); $propertyName = $propertyReflection->getName(); diff --git a/src/Reflection/Php/PhpPropertyReflection.php b/src/Reflection/Php/PhpPropertyReflection.php index 63d7eff0d8..b1f2c18656 100644 --- a/src/Reflection/Php/PhpPropertyReflection.php +++ b/src/Reflection/Php/PhpPropertyReflection.php @@ -7,7 +7,7 @@ use PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty; use PHPStan\BetterReflection\Reflection\Adapter\ReflectionUnionType; use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\MixedType; use PHPStan\Type\Type; @@ -17,7 +17,7 @@ * @api * @final */ -class PhpPropertyReflection implements PropertyReflection +class PhpPropertyReflection implements ExtendedPropertyReflection { private ?Type $finalNativeType = null; diff --git a/src/Reflection/Php/SimpleXMLElementProperty.php b/src/Reflection/Php/SimpleXMLElementProperty.php index dbb69f8e9f..4073809a23 100644 --- a/src/Reflection/Php/SimpleXMLElementProperty.php +++ b/src/Reflection/Php/SimpleXMLElementProperty.php @@ -3,7 +3,7 @@ namespace PHPStan\Reflection\Php; use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\BooleanType; use PHPStan\Type\FloatType; @@ -12,7 +12,7 @@ use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -final class SimpleXMLElementProperty implements PropertyReflection +final class SimpleXMLElementProperty implements ExtendedPropertyReflection { public function __construct( diff --git a/src/Reflection/Php/UniversalObjectCrateProperty.php b/src/Reflection/Php/UniversalObjectCrateProperty.php index ad10221352..ae1e86fe8c 100644 --- a/src/Reflection/Php/UniversalObjectCrateProperty.php +++ b/src/Reflection/Php/UniversalObjectCrateProperty.php @@ -3,11 +3,11 @@ namespace PHPStan\Reflection\Php; use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; -final class UniversalObjectCrateProperty implements PropertyReflection +final class UniversalObjectCrateProperty implements ExtendedPropertyReflection { public function __construct( diff --git a/src/Reflection/RequireExtension/RequireExtendsPropertiesClassReflectionExtension.php b/src/Reflection/RequireExtension/RequireExtendsPropertiesClassReflectionExtension.php index 600405d363..294cc94b62 100644 --- a/src/Reflection/RequireExtension/RequireExtendsPropertiesClassReflectionExtension.php +++ b/src/Reflection/RequireExtension/RequireExtendsPropertiesClassReflectionExtension.php @@ -4,6 +4,7 @@ use PHPStan\Analyser\OutOfClassScope; use PHPStan\Reflection\ClassReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\PropertiesClassReflectionExtension; use PHPStan\Reflection\PropertyReflection; use PHPStan\ShouldNotHappenException; @@ -16,6 +17,9 @@ public function hasProperty(ClassReflection $classReflection, string $propertyNa return $this->findProperty($classReflection, $propertyName) !== null; } + /** + * @return ExtendedPropertyReflection + */ public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection { $property = $this->findProperty($classReflection, $propertyName); @@ -26,7 +30,7 @@ public function getProperty(ClassReflection $classReflection, string $propertyNa return $property; } - private function findProperty(ClassReflection $classReflection, string $propertyName): ?PropertyReflection + private function findProperty(ClassReflection $classReflection, string $propertyName): ?ExtendedPropertyReflection { if (!$classReflection->isInterface()) { return null; diff --git a/src/Reflection/ResolvedPropertyReflection.php b/src/Reflection/ResolvedPropertyReflection.php index 3e111949cb..8e8447ecac 100644 --- a/src/Reflection/ResolvedPropertyReflection.php +++ b/src/Reflection/ResolvedPropertyReflection.php @@ -18,14 +18,14 @@ final class ResolvedPropertyReflection implements WrapperPropertyReflection private ?Type $writableType = null; public function __construct( - private PropertyReflection $reflection, + private ExtendedPropertyReflection $reflection, private TemplateTypeMap $templateTypeMap, private TemplateTypeVarianceMap $callSiteVarianceMap, ) { } - public function getOriginalReflection(): PropertyReflection + public function getOriginalReflection(): ExtendedPropertyReflection { return $this->reflection; } diff --git a/src/Reflection/Type/CallbackUnresolvedPropertyPrototypeReflection.php b/src/Reflection/Type/CallbackUnresolvedPropertyPrototypeReflection.php index 38b4bae4e9..151945e921 100644 --- a/src/Reflection/Type/CallbackUnresolvedPropertyPrototypeReflection.php +++ b/src/Reflection/Type/CallbackUnresolvedPropertyPrototypeReflection.php @@ -4,7 +4,7 @@ use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\Dummy\ChangedTypePropertyReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\ResolvedPropertyReflection; use PHPStan\Type\Type; @@ -14,7 +14,7 @@ final class CallbackUnresolvedPropertyPrototypeReflection implements UnresolvedP /** @var callable(Type): Type */ private $transformStaticTypeCallback; - private ?PropertyReflection $transformedProperty = null; + private ?ExtendedPropertyReflection $transformedProperty = null; private ?self $cachedDoNotResolveTemplateTypeMapToBounds = null; @@ -22,7 +22,7 @@ final class CallbackUnresolvedPropertyPrototypeReflection implements UnresolvedP * @param callable(Type): Type $transformStaticTypeCallback */ public function __construct( - private PropertyReflection $propertyReflection, + private ExtendedPropertyReflection $propertyReflection, private ClassReflection $resolvedDeclaringClass, private bool $resolveTemplateTypeMapToBounds, callable $transformStaticTypeCallback, @@ -45,12 +45,12 @@ public function doNotResolveTemplateTypeMapToBounds(): UnresolvedPropertyPrototy ); } - public function getNakedProperty(): PropertyReflection + public function getNakedProperty(): ExtendedPropertyReflection { return $this->propertyReflection; } - public function getTransformedProperty(): PropertyReflection + public function getTransformedProperty(): ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; @@ -75,7 +75,7 @@ public function withFechedOnType(Type $type): UnresolvedPropertyPrototypeReflect ); } - private function transformPropertyWithStaticType(ClassReflection $declaringClass, PropertyReflection $property): PropertyReflection + private function transformPropertyWithStaticType(ClassReflection $declaringClass, ExtendedPropertyReflection $property): ExtendedPropertyReflection { $readableType = $this->transformStaticType($property->getReadableType()); $writableType = $this->transformStaticType($property->getWritableType()); diff --git a/src/Reflection/Type/CalledOnTypeUnresolvedPropertyPrototypeReflection.php b/src/Reflection/Type/CalledOnTypeUnresolvedPropertyPrototypeReflection.php index 6582c358b7..4b843829ad 100644 --- a/src/Reflection/Type/CalledOnTypeUnresolvedPropertyPrototypeReflection.php +++ b/src/Reflection/Type/CalledOnTypeUnresolvedPropertyPrototypeReflection.php @@ -4,7 +4,7 @@ use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\Dummy\ChangedTypePropertyReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\ResolvedPropertyReflection; use PHPStan\Type\StaticType; use PHPStan\Type\Type; @@ -13,12 +13,12 @@ final class CalledOnTypeUnresolvedPropertyPrototypeReflection implements UnresolvedPropertyPrototypeReflection { - private ?PropertyReflection $transformedProperty = null; + private ?ExtendedPropertyReflection $transformedProperty = null; private ?self $cachedDoNotResolveTemplateTypeMapToBounds = null; public function __construct( - private PropertyReflection $propertyReflection, + private ExtendedPropertyReflection $propertyReflection, private ClassReflection $resolvedDeclaringClass, private bool $resolveTemplateTypeMapToBounds, private Type $fetchedOnType, @@ -40,12 +40,12 @@ public function doNotResolveTemplateTypeMapToBounds(): UnresolvedPropertyPrototy ); } - public function getNakedProperty(): PropertyReflection + public function getNakedProperty(): ExtendedPropertyReflection { return $this->propertyReflection; } - public function getTransformedProperty(): PropertyReflection + public function getTransformedProperty(): ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; @@ -70,7 +70,7 @@ public function withFechedOnType(Type $type): UnresolvedPropertyPrototypeReflect ); } - private function transformPropertyWithStaticType(ClassReflection $declaringClass, PropertyReflection $property): PropertyReflection + private function transformPropertyWithStaticType(ClassReflection $declaringClass, ExtendedPropertyReflection $property): ExtendedPropertyReflection { $readableType = $this->transformStaticType($property->getReadableType()); $writableType = $this->transformStaticType($property->getWritableType()); diff --git a/src/Reflection/Type/IntersectionTypePropertyReflection.php b/src/Reflection/Type/IntersectionTypePropertyReflection.php index e81c0b22dd..0db311786e 100644 --- a/src/Reflection/Type/IntersectionTypePropertyReflection.php +++ b/src/Reflection/Type/IntersectionTypePropertyReflection.php @@ -3,6 +3,7 @@ namespace PHPStan\Reflection\Type; use PHPStan\Reflection\ClassReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\PropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; @@ -11,7 +12,7 @@ use function count; use function implode; -final class IntersectionTypePropertyReflection implements PropertyReflection +final class IntersectionTypePropertyReflection implements ExtendedPropertyReflection { /** diff --git a/src/Reflection/Type/IntersectionTypeUnresolvedPropertyPrototypeReflection.php b/src/Reflection/Type/IntersectionTypeUnresolvedPropertyPrototypeReflection.php index ac2f0b9bcd..51e6ccaf46 100644 --- a/src/Reflection/Type/IntersectionTypeUnresolvedPropertyPrototypeReflection.php +++ b/src/Reflection/Type/IntersectionTypeUnresolvedPropertyPrototypeReflection.php @@ -2,6 +2,7 @@ namespace PHPStan\Reflection\Type; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\PropertyReflection; use PHPStan\Type\Type; use function array_map; @@ -9,7 +10,7 @@ final class IntersectionTypeUnresolvedPropertyPrototypeReflection implements UnresolvedPropertyPrototypeReflection { - private ?PropertyReflection $transformedProperty = null; + private ?ExtendedPropertyReflection $transformedProperty = null; private ?self $cachedDoNotResolveTemplateTypeMapToBounds = null; @@ -32,12 +33,12 @@ public function doNotResolveTemplateTypeMapToBounds(): UnresolvedPropertyPrototy return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->propertyName, array_map(static fn (UnresolvedPropertyPrototypeReflection $prototype): UnresolvedPropertyPrototypeReflection => $prototype->doNotResolveTemplateTypeMapToBounds(), $this->propertyPrototypes)); } - public function getNakedProperty(): PropertyReflection + public function getNakedProperty(): ExtendedPropertyReflection { return $this->getTransformedProperty(); } - public function getTransformedProperty(): PropertyReflection + public function getTransformedProperty(): ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; diff --git a/src/Reflection/Type/UnionTypePropertyReflection.php b/src/Reflection/Type/UnionTypePropertyReflection.php index f23f2f1234..91964e8eda 100644 --- a/src/Reflection/Type/UnionTypePropertyReflection.php +++ b/src/Reflection/Type/UnionTypePropertyReflection.php @@ -3,6 +3,7 @@ namespace PHPStan\Reflection\Type; use PHPStan\Reflection\ClassReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\PropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; @@ -11,7 +12,7 @@ use function count; use function implode; -final class UnionTypePropertyReflection implements PropertyReflection +final class UnionTypePropertyReflection implements ExtendedPropertyReflection { /** diff --git a/src/Reflection/Type/UnionTypeUnresolvedPropertyPrototypeReflection.php b/src/Reflection/Type/UnionTypeUnresolvedPropertyPrototypeReflection.php index f3f2d38965..b28625e3c3 100644 --- a/src/Reflection/Type/UnionTypeUnresolvedPropertyPrototypeReflection.php +++ b/src/Reflection/Type/UnionTypeUnresolvedPropertyPrototypeReflection.php @@ -2,6 +2,7 @@ namespace PHPStan\Reflection\Type; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\PropertyReflection; use PHPStan\Type\Type; use function array_map; @@ -9,7 +10,7 @@ final class UnionTypeUnresolvedPropertyPrototypeReflection implements UnresolvedPropertyPrototypeReflection { - private ?PropertyReflection $transformedProperty = null; + private ?ExtendedPropertyReflection $transformedProperty = null; private ?self $cachedDoNotResolveTemplateTypeMapToBounds = null; @@ -31,12 +32,12 @@ public function doNotResolveTemplateTypeMapToBounds(): UnresolvedPropertyPrototy return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->propertyName, array_map(static fn (UnresolvedPropertyPrototypeReflection $prototype): UnresolvedPropertyPrototypeReflection => $prototype->doNotResolveTemplateTypeMapToBounds(), $this->propertyPrototypes)); } - public function getNakedProperty(): PropertyReflection + public function getNakedProperty(): ExtendedPropertyReflection { return $this->getTransformedProperty(); } - public function getTransformedProperty(): PropertyReflection + public function getTransformedProperty(): ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; diff --git a/src/Reflection/Type/UnresolvedPropertyPrototypeReflection.php b/src/Reflection/Type/UnresolvedPropertyPrototypeReflection.php index 867f3c1dda..441d4a36c3 100644 --- a/src/Reflection/Type/UnresolvedPropertyPrototypeReflection.php +++ b/src/Reflection/Type/UnresolvedPropertyPrototypeReflection.php @@ -2,7 +2,7 @@ namespace PHPStan\Reflection\Type; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Type\Type; interface UnresolvedPropertyPrototypeReflection @@ -10,9 +10,9 @@ interface UnresolvedPropertyPrototypeReflection public function doNotResolveTemplateTypeMapToBounds(): self; - public function getNakedProperty(): PropertyReflection; + public function getNakedProperty(): ExtendedPropertyReflection; - public function getTransformedProperty(): PropertyReflection; + public function getTransformedProperty(): ExtendedPropertyReflection; public function withFechedOnType(Type $type): self; diff --git a/src/Reflection/WrappedExtendedPropertyReflection.php b/src/Reflection/WrappedExtendedPropertyReflection.php new file mode 100644 index 0000000000..9b941088bc --- /dev/null +++ b/src/Reflection/WrappedExtendedPropertyReflection.php @@ -0,0 +1,80 @@ +property->getDeclaringClass(); + } + + public function isStatic(): bool + { + return $this->property->isStatic(); + } + + public function isPrivate(): bool + { + return $this->property->isPrivate(); + } + + public function isPublic(): bool + { + return $this->property->isPublic(); + } + + public function getDocComment(): ?string + { + return $this->property->getDocComment(); + } + + public function getReadableType(): Type + { + return $this->property->getReadableType(); + } + + public function getWritableType(): Type + { + return $this->property->getWritableType(); + } + + public function canChangeTypeAfterAssignment(): bool + { + return $this->property->canChangeTypeAfterAssignment(); + } + + public function isReadable(): bool + { + return $this->property->isReadable(); + } + + public function isWritable(): bool + { + return $this->property->isWritable(); + } + + public function isDeprecated(): TrinaryLogic + { + return $this->property->isDeprecated(); + } + + public function getDeprecatedDescription(): ?string + { + return $this->property->getDeprecatedDescription(); + } + + public function isInternal(): TrinaryLogic + { + return $this->property->isInternal(); + } + +} diff --git a/src/Reflection/WrapperPropertyReflection.php b/src/Reflection/WrapperPropertyReflection.php index c34a3c7cfb..e7bb397ace 100644 --- a/src/Reflection/WrapperPropertyReflection.php +++ b/src/Reflection/WrapperPropertyReflection.php @@ -2,9 +2,9 @@ namespace PHPStan\Reflection; -interface WrapperPropertyReflection extends PropertyReflection +interface WrapperPropertyReflection extends ExtendedPropertyReflection { - public function getOriginalReflection(): PropertyReflection; + public function getOriginalReflection(): ExtendedPropertyReflection; } diff --git a/src/Rules/Api/BcUncoveredInterface.php b/src/Rules/Api/BcUncoveredInterface.php index 9a78dc5cc7..7670f1962f 100644 --- a/src/Rules/Api/BcUncoveredInterface.php +++ b/src/Rules/Api/BcUncoveredInterface.php @@ -5,6 +5,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Reflection\Callables\CallableParametersAcceptor; use PHPStan\Reflection\ExtendedMethodReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\FunctionReflection; use PHPStan\Reflection\ParameterReflectionWithPhpDocs; use PHPStan\Reflection\ParametersAcceptorWithPhpDocs; @@ -27,6 +28,7 @@ final class BcUncoveredInterface Scope::class, FunctionReflection::class, ExtendedMethodReflection::class, + ExtendedPropertyReflection::class, ParametersAcceptorWithPhpDocs::class, ParameterReflectionWithPhpDocs::class, CallableParametersAcceptor::class, diff --git a/src/Rules/Properties/FoundPropertyReflection.php b/src/Rules/Properties/FoundPropertyReflection.php index 57577364cd..a05182fa66 100644 --- a/src/Rules/Properties/FoundPropertyReflection.php +++ b/src/Rules/Properties/FoundPropertyReflection.php @@ -4,17 +4,17 @@ use PHPStan\Analyser\Scope; use PHPStan\Reflection\ClassReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\Php\PhpPropertyReflection; -use PHPStan\Reflection\PropertyReflection; use PHPStan\Reflection\WrapperPropertyReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; -final class FoundPropertyReflection implements PropertyReflection +final class FoundPropertyReflection implements ExtendedPropertyReflection { public function __construct( - private PropertyReflection $originalPropertyReflection, + private ExtendedPropertyReflection $originalPropertyReflection, private Scope $scope, private string $propertyName, private Type $readableType, diff --git a/src/Type/ObjectShapePropertyReflection.php b/src/Type/ObjectShapePropertyReflection.php index e7132ecfb3..ca96ebae94 100644 --- a/src/Type/ObjectShapePropertyReflection.php +++ b/src/Type/ObjectShapePropertyReflection.php @@ -3,12 +3,12 @@ namespace PHPStan\Type; use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\PropertyReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\ReflectionProviderStaticAccessor; use PHPStan\TrinaryLogic; use stdClass; -final class ObjectShapePropertyReflection implements PropertyReflection +final class ObjectShapePropertyReflection implements ExtendedPropertyReflection { public function __construct(private Type $type) diff --git a/src/Type/Type.php b/src/Type/Type.php index 3ac0a41c24..ec682c3e03 100644 --- a/src/Type/Type.php +++ b/src/Type/Type.php @@ -9,6 +9,7 @@ use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ConstantReflection; use PHPStan\Reflection\ExtendedMethodReflection; +use PHPStan\Reflection\ExtendedPropertyReflection; use PHPStan\Reflection\PropertyReflection; use PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection; use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection; @@ -85,6 +86,9 @@ public function canAccessProperties(): TrinaryLogic; public function hasProperty(string $propertyName): TrinaryLogic; + /** + * @return ExtendedPropertyReflection + */ public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection; public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection;