From 89838a3b1715f0a5a2e5d8bbc8fcc100c6bf8ed6 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 10 May 2026 23:32:08 +0200 Subject: [PATCH] Refactor MutatingScope --- src/Analyser/MutatingScope.php | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index e71ed1ab546..5e28dc50ee7 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2021,18 +2021,7 @@ public function enterAnonymousFunctionWithoutReflection( $isNullable = $this->isParameterValueNullable($parameter); $parameterType = $this->getFunctionType($parameter->type, $isNullable, $parameter->variadic); if ($callableParameters !== null) { - if (isset($callableParameters[$i])) { - $parameterType = self::intersectButNotNever($parameterType, $callableParameters[$i]->getType()); - } elseif (count($callableParameters) > 0) { - $lastParameter = array_last($callableParameters); - if ($lastParameter->isVariadic()) { - $parameterType = self::intersectButNotNever($parameterType, $lastParameter->getType()); - } else { - $parameterType = self::intersectButNotNever($parameterType, new MixedType()); - } - } else { - $parameterType = self::intersectButNotNever($parameterType, new MixedType()); - } + $parameterType = self::intersectButNotNever($parameterType, $this->getCallableParameterType($callableParameters, $i)); } $holder = ExpressionTypeHolder::createYes($parameter->var, $parameterType); $expressionTypes[$paramExprString] = $holder; @@ -2231,20 +2220,8 @@ public function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFun foreach ($arrowFunction->params as $i => $parameter) { $isNullable = $this->isParameterValueNullable($parameter); $parameterType = $this->getFunctionType($parameter->type, $isNullable, $parameter->variadic); - if ($callableParameters !== null) { - if (isset($callableParameters[$i])) { - $parameterType = self::intersectButNotNever($parameterType, $callableParameters[$i]->getType()); - } elseif (count($callableParameters) > 0) { - $lastParameter = array_last($callableParameters); - if ($lastParameter->isVariadic()) { - $parameterType = self::intersectButNotNever($parameterType, $lastParameter->getType()); - } else { - $parameterType = self::intersectButNotNever($parameterType, new MixedType()); - } - } else { - $parameterType = self::intersectButNotNever($parameterType, new MixedType()); - } + $parameterType = self::intersectButNotNever($parameterType, $this->getCallableParameterType($callableParameters, $i)); } if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { @@ -2310,6 +2287,27 @@ public function getFunctionType($type, bool $isNullable, bool $isVariadic): Type return $this->initializerExprTypeResolver->getFunctionType($type, $isNullable, false, InitializerExprContext::fromScope($this)); } + /** + * @param ParameterReflection[] $callableParameters + */ + private function getCallableParameterType(array $callableParameters, int $index): Type + { + if (isset($callableParameters[$index])) { + return $callableParameters[$index]->getType(); + } + + if (count($callableParameters) === 0) { + return new MixedType(); + } + + $lastParameter = array_last($callableParameters); + if ($lastParameter->isVariadic()) { + return $lastParameter->getType(); + } + + return new MixedType(); + } + public static function intersectButNotNever(Type $nativeType, Type $inferredType): Type { if ($nativeType->isSuperTypeOf($inferredType)->no()) {