From 392679fe958c78ed8af116a7ab2c504cd6592583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=BD=C3=A1=C4=8Dek?= Date: Sat, 9 Nov 2024 19:03:17 +0100 Subject: [PATCH] Introduce isDeprecated to CallableParametersAcceptor --- src/Analyser/MutatingScope.php | 2 ++ .../Callables/CallableParametersAcceptor.php | 2 ++ .../Callables/FunctionCallableVariant.php | 5 +++++ .../ExtendedCallableFunctionVariant.php | 6 ++++++ .../GenericParametersAcceptorResolver.php | 1 + src/Reflection/InaccessibleMethod.php | 5 +++++ src/Reflection/ParametersAcceptorSelector.php | 4 ++++ .../ResolvedFunctionVariantWithCallable.php | 6 ++++++ src/Reflection/TrivialParametersAcceptor.php | 5 +++++ src/Rules/RuleLevelHelper.php | 2 ++ src/Type/CallableType.php | 15 +++++++++++++++ src/Type/ClosureType.php | 12 ++++++++++++ src/Type/ClosureTypeFactory.php | 17 ++++++++++++++++- ...reFromCallableDynamicReturnTypeExtension.php | 1 + 14 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index f883c95578..53cf7ec6e6 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -1342,6 +1342,7 @@ static function (Node $node, Scope $scope) use ($arrowScope, &$arrowFunctionImpu $cachedClosureData['invalidateExpressions'], $cachedClosureData['usedVariables'], TrinaryLogic::createYes(), + TrinaryLogic::createNo(), ); } if (self::$resolveClosureTypeDepth >= 2) { @@ -1557,6 +1558,7 @@ static function (Node $node, Scope $scope) use ($arrowScope, &$arrowFunctionImpu $invalidateExpressions, $usedVariables, TrinaryLogic::createYes(), + TrinaryLogic::createNo(), ); } elseif ($node instanceof New_) { if ($node->class instanceof Name) { diff --git a/src/Reflection/Callables/CallableParametersAcceptor.php b/src/Reflection/Callables/CallableParametersAcceptor.php index 25ff7d770c..d5042193e3 100644 --- a/src/Reflection/Callables/CallableParametersAcceptor.php +++ b/src/Reflection/Callables/CallableParametersAcceptor.php @@ -19,6 +19,8 @@ public function getThrowPoints(): array; public function isPure(): TrinaryLogic; + public function isDeprecated(): TrinaryLogic; + public function acceptsNamedArguments(): TrinaryLogic; /** diff --git a/src/Reflection/Callables/FunctionCallableVariant.php b/src/Reflection/Callables/FunctionCallableVariant.php index 71ea905c52..28d8d17771 100644 --- a/src/Reflection/Callables/FunctionCallableVariant.php +++ b/src/Reflection/Callables/FunctionCallableVariant.php @@ -135,6 +135,11 @@ public function isPure(): TrinaryLogic return $certainCount > 0 ? TrinaryLogic::createNo() : TrinaryLogic::createMaybe(); } + public function isDeprecated(): TrinaryLogic + { + return $this->function->isDeprecated(); + } + public function getImpurePoints(): array { if ($this->impurePoints !== null) { diff --git a/src/Reflection/ExtendedCallableFunctionVariant.php b/src/Reflection/ExtendedCallableFunctionVariant.php index 5e2d3a9c10..8239ec81b9 100644 --- a/src/Reflection/ExtendedCallableFunctionVariant.php +++ b/src/Reflection/ExtendedCallableFunctionVariant.php @@ -32,6 +32,7 @@ public function __construct( ?TemplateTypeVarianceMap $callSiteVarianceMap, private array $throwPoints, private TrinaryLogic $isPure, + private TrinaryLogic $isDeprecated, private array $impurePoints, private array $invalidateExpressions, private array $usedVariables, @@ -60,6 +61,11 @@ public function isPure(): TrinaryLogic return $this->isPure; } + public function isDeprecated(): TrinaryLogic + { + return $this->isDeprecated; + } + public function getImpurePoints(): array { return $this->impurePoints; diff --git a/src/Reflection/GenericParametersAcceptorResolver.php b/src/Reflection/GenericParametersAcceptorResolver.php index e680908c32..47b1c75524 100644 --- a/src/Reflection/GenericParametersAcceptorResolver.php +++ b/src/Reflection/GenericParametersAcceptorResolver.php @@ -123,6 +123,7 @@ public static function resolve(array $argTypes, ParametersAcceptor $parametersAc $result, $originalParametersAcceptor->getThrowPoints(), $originalParametersAcceptor->isPure(), + $originalParametersAcceptor->isDeprecated(), $originalParametersAcceptor->getImpurePoints(), $originalParametersAcceptor->getInvalidateExpressions(), $originalParametersAcceptor->getUsedVariables(), diff --git a/src/Reflection/InaccessibleMethod.php b/src/Reflection/InaccessibleMethod.php index 037f4e8137..063433c924 100644 --- a/src/Reflection/InaccessibleMethod.php +++ b/src/Reflection/InaccessibleMethod.php @@ -62,6 +62,11 @@ public function isPure(): TrinaryLogic return TrinaryLogic::createMaybe(); } + public function isDeprecated(): TrinaryLogic + { + return $this->methodReflection->isDeprecated(); + } + public function getImpurePoints(): array { return [ diff --git a/src/Reflection/ParametersAcceptorSelector.php b/src/Reflection/ParametersAcceptorSelector.php index 703d345806..d51c00f86c 100644 --- a/src/Reflection/ParametersAcceptorSelector.php +++ b/src/Reflection/ParametersAcceptorSelector.php @@ -611,6 +611,7 @@ public static function combineAcceptors(array $acceptors): ExtendedParametersAcc $callableOccurred = false; $throwPoints = []; $isPure = TrinaryLogic::createNo(); + $isDeprecated = TrinaryLogic::createNo(); $impurePoints = []; $invalidateExpressions = []; $usedVariables = []; @@ -627,6 +628,7 @@ public static function combineAcceptors(array $acceptors): ExtendedParametersAcc $callableOccurred = true; $throwPoints = array_merge($throwPoints, $acceptor->getThrowPoints()); $isPure = $isPure->or($acceptor->isPure()); + $isDeprecated = $isDeprecated->or($acceptor->isDeprecated()); $impurePoints = array_merge($impurePoints, $acceptor->getImpurePoints()); $invalidateExpressions = array_merge($invalidateExpressions, $acceptor->getInvalidateExpressions()); $usedVariables = array_merge($usedVariables, $acceptor->getUsedVariables()); @@ -729,6 +731,7 @@ public static function combineAcceptors(array $acceptors): ExtendedParametersAcc null, $throwPoints, $isPure, + $isDeprecated, $impurePoints, $invalidateExpressions, $usedVariables, @@ -765,6 +768,7 @@ private static function wrapAcceptor(ParametersAcceptor $acceptor): ExtendedPara TemplateTypeVarianceMap::createEmpty(), $acceptor->getThrowPoints(), $acceptor->isPure(), + $acceptor->isDeprecated(), $acceptor->getImpurePoints(), $acceptor->getInvalidateExpressions(), $acceptor->getUsedVariables(), diff --git a/src/Reflection/ResolvedFunctionVariantWithCallable.php b/src/Reflection/ResolvedFunctionVariantWithCallable.php index 7dbd382405..68d9d87414 100644 --- a/src/Reflection/ResolvedFunctionVariantWithCallable.php +++ b/src/Reflection/ResolvedFunctionVariantWithCallable.php @@ -24,6 +24,7 @@ public function __construct( private ResolvedFunctionVariant $parametersAcceptor, private array $throwPoints, private TrinaryLogic $isPure, + private TrinaryLogic $isDeprecated, private array $impurePoints, private array $invalidateExpressions, private array $usedVariables, @@ -97,6 +98,11 @@ public function isPure(): TrinaryLogic return $this->isPure; } + public function isDeprecated(): TrinaryLogic + { + return $this->isDeprecated; + } + public function getImpurePoints(): array { return $this->impurePoints; diff --git a/src/Reflection/TrivialParametersAcceptor.php b/src/Reflection/TrivialParametersAcceptor.php index ea6b278145..8c7e3e9a6a 100644 --- a/src/Reflection/TrivialParametersAcceptor.php +++ b/src/Reflection/TrivialParametersAcceptor.php @@ -72,6 +72,11 @@ public function isPure(): TrinaryLogic return TrinaryLogic::createMaybe(); } + public function isDeprecated(): TrinaryLogic + { + return TrinaryLogic::createNo(); + } + public function getImpurePoints(): array { return [ diff --git a/src/Rules/RuleLevelHelper.php b/src/Rules/RuleLevelHelper.php index 416583546f..9ad1805c77 100644 --- a/src/Rules/RuleLevelHelper.php +++ b/src/Rules/RuleLevelHelper.php @@ -91,6 +91,7 @@ private function transformAcceptedType(Type $acceptingType, Type $acceptedType): $acceptedType->getResolvedTemplateTypeMap(), $acceptedType->getTemplateTags(), $acceptedType->isPure(), + $acceptedType->isDeprecated(), ); } @@ -112,6 +113,7 @@ private function transformAcceptedType(Type $acceptingType, Type $acceptedType): $acceptedType->getInvalidateExpressions(), $acceptedType->getUsedVariables(), $acceptedType->acceptsNamedArguments(), + $acceptedType->isDeprecated(), ); } diff --git a/src/Type/CallableType.php b/src/Type/CallableType.php index fe6e412ad2..9ea353c5d6 100644 --- a/src/Type/CallableType.php +++ b/src/Type/CallableType.php @@ -65,6 +65,8 @@ class CallableType implements CompoundType, CallableParametersAcceptor private TrinaryLogic $isPure; + private TrinaryLogic $isDeprecated; + /** * @api * @param list|null $parameters @@ -78,6 +80,7 @@ public function __construct( ?TemplateTypeMap $resolvedTemplateTypeMap = null, private array $templateTags = [], ?TrinaryLogic $isPure = null, + ?TrinaryLogic $isDeprecated = null, ) { $this->parameters = $parameters ?? []; @@ -86,6 +89,7 @@ public function __construct( $this->templateTypeMap = $templateTypeMap ?? TemplateTypeMap::createEmpty(); $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap ?? TemplateTypeMap::createEmpty(); $this->isPure = $isPure ?? TrinaryLogic::createMaybe(); + $this->isDeprecated = $isDeprecated ?? TrinaryLogic::createNo(); } /** @@ -101,6 +105,14 @@ public function isPure(): TrinaryLogic return $this->isPure; } + public function isDeprecated(): TrinaryLogic + { + return $this->isDeprecated; + } + + /** + * @return list + */ public function getReferencedClasses(): array { $classes = []; @@ -231,6 +243,7 @@ function (): string { $this->resolvedTemplateTypeMap, $this->templateTags, $this->isPure, + $this->isDeprecated, ); return $printer->print($selfWithoutParameterNames->toPhpDocNode()); @@ -445,6 +458,7 @@ public function traverse(callable $cb): Type $this->resolvedTemplateTypeMap, $this->templateTags, $this->isPure, + $this->isDeprecated, ); } @@ -495,6 +509,7 @@ public function traverseSimultaneously(Type $right, callable $cb): Type $this->resolvedTemplateTypeMap, $this->templateTags, $this->isPure, + $this->isDeprecated, ); } diff --git a/src/Type/ClosureType.php b/src/Type/ClosureType.php index a76aa90596..03caa373d5 100644 --- a/src/Type/ClosureType.php +++ b/src/Type/ClosureType.php @@ -79,6 +79,8 @@ class ClosureType implements TypeWithClassName, CallableParametersAcceptor private TrinaryLogic $acceptsNamedArguments; + private TrinaryLogic $isDeprecated; + /** * @api * @param list|null $parameters @@ -101,6 +103,7 @@ public function __construct( private array $invalidateExpressions = [], private array $usedVariables = [], ?TrinaryLogic $acceptsNamedArguments = null, + ?TrinaryLogic $isDeprecated = null, ) { if ($acceptsNamedArguments === null) { @@ -116,6 +119,7 @@ public function __construct( $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap ?? TemplateTypeMap::createEmpty(); $this->callSiteVarianceMap = $callSiteVarianceMap ?? TemplateTypeVarianceMap::createEmpty(); $this->impurePoints = $impurePoints ?? [new SimpleImpurePoint('functionCall', 'call to an unknown Closure', false)]; + $this->isDeprecated = $isDeprecated ?? TrinaryLogic::createNo(); } /** @@ -150,6 +154,11 @@ public function isPure(): TrinaryLogic return $certainCount > 0 ? TrinaryLogic::createNo() : TrinaryLogic::createMaybe(); } + public function isDeprecated(): TrinaryLogic + { + return $this->isDeprecated; + } + public function getClassName(): string { return $this->objectType->getClassName(); @@ -262,6 +271,7 @@ function (): string { $this->impurePoints, $this->invalidateExpressions, $this->usedVariables, + $this->isDeprecated, ); return $printer->print($selfWithoutParameterNames->toPhpDocNode()); @@ -584,6 +594,7 @@ public function traverse(callable $cb): Type $this->invalidateExpressions, $this->usedVariables, $this->acceptsNamedArguments, + $this->isDeprecated, ); } @@ -634,6 +645,7 @@ public function traverseSimultaneously(Type $right, callable $cb): Type $this->invalidateExpressions, $this->usedVariables, $this->acceptsNamedArguments, + $this->isDeprecated, ); } diff --git a/src/Type/ClosureTypeFactory.php b/src/Type/ClosureTypeFactory.php index fb36d04c44..b5c7983288 100644 --- a/src/Type/ClosureTypeFactory.php +++ b/src/Type/ClosureTypeFactory.php @@ -18,6 +18,7 @@ use PHPStan\Reflection\ParameterReflection; use PHPStan\Reflection\PassedByReference; use PHPStan\ShouldNotHappenException; +use PHPStan\TrinaryLogic; use ReflectionFunction; use function array_map; use function count; @@ -113,7 +114,21 @@ public function getDefaultValue(): ?Type }, $betterReflectionFunction->getParameters()); - return new ClosureType($parameters, TypehintHelper::decideTypeFromReflection(ReflectionType::fromTypeOrNull($betterReflectionFunction->getReturnType())), $betterReflectionFunction->isVariadic()); + return new ClosureType( + $parameters, + TypehintHelper::decideTypeFromReflection(ReflectionType::fromTypeOrNull($betterReflectionFunction->getReturnType())), + $betterReflectionFunction->isVariadic(), + null, + null, + null, + [], + [], + null, + [], + [], + null, + TrinaryLogic::createFromBoolean($betterReflectionFunction->isDeprecated()), + ); } } diff --git a/src/Type/Php/ClosureFromCallableDynamicReturnTypeExtension.php b/src/Type/Php/ClosureFromCallableDynamicReturnTypeExtension.php index d579157160..f8421d109e 100644 --- a/src/Type/Php/ClosureFromCallableDynamicReturnTypeExtension.php +++ b/src/Type/Php/ClosureFromCallableDynamicReturnTypeExtension.php @@ -54,6 +54,7 @@ public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, $variant->getInvalidateExpressions(), $variant->getUsedVariables(), $variant->acceptsNamedArguments(), + $variant->isDeprecated(), ); }