diff --git a/src/Analyser/ExprHandler/Helper/EarlyTerminatingCallHelper.php b/src/Analyser/ExprHandler/Helper/EarlyTerminatingCallHelper.php index d44df0587f..04ea31fe51 100644 --- a/src/Analyser/ExprHandler/Helper/EarlyTerminatingCallHelper.php +++ b/src/Analyser/ExprHandler/Helper/EarlyTerminatingCallHelper.php @@ -5,9 +5,9 @@ use PHPStan\DependencyInjection\AutowiredParameter; use PHPStan\DependencyInjection\AutowiredService; use PHPStan\Reflection\ReflectionProvider; +use PHPStan\Type\ExtensionClassHelper; use PHPStan\Type\Type; use function array_key_exists; -use function array_merge; use function in_array; use function strtolower; @@ -57,8 +57,8 @@ public function isEarlyTerminatingMethodCall(string $methodName, Type $calledOnT continue; } - $classReflection = $this->reflectionProvider->getClass($referencedClass); - foreach (array_merge([$referencedClass], $classReflection->getParentClassesNames(), $classReflection->getNativeReflection()->getInterfaceNames()) as $className) { + $extensionClassNames = ExtensionClassHelper::getExtensionClassNames($this->reflectionProvider, $referencedClass); + foreach ($extensionClassNames as $className) { if (!isset($this->earlyTerminatingMethodCalls[$className])) { continue; } diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 3bc9039336..d2da6b934b 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -27,6 +27,7 @@ use PHPStan\Type\ConditionalTypeForParameter; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantIntegerType; +use PHPStan\Type\ExtensionClassHelper; use PHPStan\Type\FunctionTypeSpecifyingExtension; use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\IntegerRangeType; @@ -791,8 +792,8 @@ public function getStaticMethodTypeSpecifyingExtensionsForClass(string $classNam private function getTypeSpecifyingExtensionsForType(array $extensions, string $className): array { $extensionsForClass = [[]]; - $class = $this->reflectionProvider->getClass($className); - foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) { + $extensionClassNames = ExtensionClassHelper::getExtensionClassNames($this->reflectionProvider, $className); + foreach ($extensionClassNames as $extensionClassName) { if (!isset($extensions[$extensionClassName])) { continue; } diff --git a/src/Type/DynamicReturnTypeExtensionRegistry.php b/src/Type/DynamicReturnTypeExtensionRegistry.php index 5002627ec5..4f9862a5b3 100644 --- a/src/Type/DynamicReturnTypeExtensionRegistry.php +++ b/src/Type/DynamicReturnTypeExtensionRegistry.php @@ -83,8 +83,8 @@ private function getDynamicExtensionsForType(array $extensions, string $classNam } $extensionsForClass = [[]]; - $class = $this->reflectionProvider->getClass($className); - foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) { + $extensionClassNames = ExtensionClassHelper::getExtensionClassNames($this->reflectionProvider, $className); + foreach ($extensionClassNames as $extensionClassName) { $extensionClassName = strtolower($extensionClassName); if (!isset($extensions[$extensionClassName])) { continue; diff --git a/src/Type/ExtensionClassHelper.php b/src/Type/ExtensionClassHelper.php new file mode 100644 index 0000000000..21c6f610e8 --- /dev/null +++ b/src/Type/ExtensionClassHelper.php @@ -0,0 +1,28 @@ +> */ + private static array $extensionClassNames = []; + + /** + * @return string[] + */ + public static function getExtensionClassNames(ReflectionProvider $reflectionProvider, string $className): array + { + if (!array_key_exists($className, self::$extensionClassNames)) { + $class = $reflectionProvider->getClass($className); + self::$extensionClassNames[$className] = array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()); + } + + return self::$extensionClassNames[$className]; + } + +}