From 9b26ffe2f9e5a390509081e1cb848f630e8d10c9 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 09:26:50 +0100 Subject: [PATCH 01/11] Create PHPParser.stub --- .../ContainerDynamicReturnTypeExtension.php | 3 + build/phpstan.neon | 1 + build/stubs/PhpParserExpr.stub | 102 ++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 build/stubs/PhpParserExpr.stub diff --git a/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php b/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php index 8e43bd2d47..da8d1f9584 100644 --- a/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php +++ b/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php @@ -14,6 +14,7 @@ use PHPStan\Type\TypeCombinator; use function count; use function in_array; +use function PHPStan\dumpType; final class ContainerDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { @@ -32,6 +33,7 @@ public function isMethodSupported(MethodReflection $methodReflection): bool public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type { + dumpType($methodCall->getArgs()); if (count($methodCall->getArgs()) === 0) { return ParametersAcceptorSelector::selectFromArgs( $scope, @@ -39,6 +41,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method $methodReflection->getVariants(), )->getReturnType(); } + dumpType($methodCall->getArgs()); $argType = $scope->getType($methodCall->getArgs()[0]->value); if (!$argType instanceof ConstantStringType) { return ParametersAcceptorSelector::selectFromArgs( diff --git a/build/phpstan.neon b/build/phpstan.neon index 97a076fab0..5d298dabe6 100644 --- a/build/phpstan.neon +++ b/build/phpstan.neon @@ -124,6 +124,7 @@ parameters: - stubs/ReactStreams.stub - stubs/NetteDIContainer.stub - stubs/PhpParserName.stub + - stubs/PhpParserExpr.stub - stubs/Identifier.stub rules: diff --git a/build/stubs/PhpParserExpr.stub b/build/stubs/PhpParserExpr.stub new file mode 100644 index 0000000000..6eec4bf1f3 --- /dev/null +++ b/build/stubs/PhpParserExpr.stub @@ -0,0 +1,102 @@ + + */ + abstract public function getRawArgs(): array; + /** + * Assert that this is not a first-class callable and return only ordinary Args. + * + * @return list + */ + public function getArgs(): array { + assert(!$this->isFirstClassCallable()); + return $this->getRawArgs(); + } +} + +class FuncCall extends CallLike { + /** @var list Arguments */ + public array $args; + + /** + * Constructs a function call node. + * + * @param Node\Name|Expr $name Function name + * @param list $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Node $name, array $args = [], array $attributes = []) {} +} + +class MethodCall extends CallLike { + /** @var list Arguments */ + public array $args; + + /** + * Constructs a function call node. + * + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Method name + * @param list $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Expr $var, $name, array $args = [], array $attributes = []) {} +} + +class New_ extends CallLike { + /** @var list Arguments */ + public array $args; + + /** + * Constructs a function call node. + * + * @param Node\Name|Expr|Node\Stmt\Class_ $class Class name (or class node for anonymous classes) + * @param list $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Node $class, array $args = [], array $attributes = []) {} +} + +class NullsafeMethodCall extends CallLike { + /** @var list Arguments */ + public array $args; + + /** + * Constructs a nullsafe method call node. + * + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Method name + * @param list $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Expr $var, $name, array $args = [], array $attributes = []) {} +} + +class StaticCall extends CallLike { + /** @var list Arguments */ + public array $args; + + /** + * Constructs a static method call node. + * + * @param Node\Name|Expr $class Class name + * @param string|Identifier|Expr $name Method name + * @param list $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Node $class, $name, array $args = [], array $attributes = []) {} +} From 73cdb39f32a9a7bc422192ec281f652cbf1ca483 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 10:56:05 +0100 Subject: [PATCH 02/11] Update ContainerDynamicReturnTypeExtension.php --- build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php b/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php index da8d1f9584..aa303212e5 100644 --- a/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php +++ b/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php @@ -33,7 +33,6 @@ public function isMethodSupported(MethodReflection $methodReflection): bool public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type { - dumpType($methodCall->getArgs()); if (count($methodCall->getArgs()) === 0) { return ParametersAcceptorSelector::selectFromArgs( $scope, @@ -41,7 +40,6 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method $methodReflection->getVariants(), )->getReturnType(); } - dumpType($methodCall->getArgs()); $argType = $scope->getType($methodCall->getArgs()[0]->value); if (!$argType instanceof ConstantStringType) { return ParametersAcceptorSelector::selectFromArgs( From 5528d1c9874552d185f07e43fe0e347340e53ccc Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 11:05:15 +0100 Subject: [PATCH 03/11] fix --- src/Analyser/ArgumentsNormalizer.php | 8 ++++++-- src/Analyser/NodeScopeResolver.php | 2 +- src/Reflection/ParametersAcceptorSelector.php | 3 +++ src/Rules/Functions/RandomIntParametersRule.php | 2 +- tests/PHPStan/Analyser/ArgumentsNormalizerLegacyTest.php | 8 -------- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Analyser/ArgumentsNormalizer.php b/src/Analyser/ArgumentsNormalizer.php index 4a4844cd8c..9baa342ff4 100644 --- a/src/Analyser/ArgumentsNormalizer.php +++ b/src/Analyser/ArgumentsNormalizer.php @@ -182,8 +182,8 @@ public static function reorderNewArguments( } /** - * @param Arg[] $callArgs - * @return ?array + * @param list $callArgs + * @return ?list */ public static function reorderArgs(ParametersAcceptor $parametersAcceptor, array $callArgs): ?array { @@ -322,6 +322,10 @@ public static function reorderArgs(ParametersAcceptor $parametersAcceptor, array $reorderedArgs[] = $arg; } + if (!array_is_list($reorderedArgs)) { + throw new ShouldNotHappenException(); + } + return $reorderedArgs; } diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 9e1b226d8c..1d833752b0 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -4455,7 +4455,7 @@ private function getMethodThrowPoint(MethodReflection $methodReflection, Paramet } /** - * @param Node\Arg[] $args + * @param list $args */ private function getConstructorThrowPoint(MethodReflection $constructorReflection, ParametersAcceptor $parametersAcceptor, ClassReflection $classReflection, New_ $new, Name $className, array $args, MutatingScope $scope): ?ThrowPoint { diff --git a/src/Reflection/ParametersAcceptorSelector.php b/src/Reflection/ParametersAcceptorSelector.php index a8ef3d3f7d..f98b9bf6e2 100644 --- a/src/Reflection/ParametersAcceptorSelector.php +++ b/src/Reflection/ParametersAcceptorSelector.php @@ -471,6 +471,9 @@ public static function selectFromArgs( $parameters = null; $singleParametersAcceptor = null; if (count($parametersAcceptors) === 1) { + if (!array_is_list($args)) { + throw new ShouldNotHappenException('args is expected to be a list'); + } $reorderedArgs = ArgumentsNormalizer::reorderArgs($parametersAcceptors[0], $args); $singleParametersAcceptor = $parametersAcceptors[0]; } diff --git a/src/Rules/Functions/RandomIntParametersRule.php b/src/Rules/Functions/RandomIntParametersRule.php index d2f8c52597..62c21cb2c6 100644 --- a/src/Rules/Functions/RandomIntParametersRule.php +++ b/src/Rules/Functions/RandomIntParametersRule.php @@ -49,7 +49,7 @@ public function processNode(Node $node, Scope $scope): array return []; } - $args = array_values($node->getArgs()); + $args = $node->getArgs(); if (count($args) < 2) { return []; } diff --git a/tests/PHPStan/Analyser/ArgumentsNormalizerLegacyTest.php b/tests/PHPStan/Analyser/ArgumentsNormalizerLegacyTest.php index 9b92249486..06235a934e 100644 --- a/tests/PHPStan/Analyser/ArgumentsNormalizerLegacyTest.php +++ b/tests/PHPStan/Analyser/ArgumentsNormalizerLegacyTest.php @@ -49,11 +49,9 @@ public function testArgumentReorderAllNamed(): void $reorderedArgs = $funcCall->getArgs(); $this->assertCount(2, $reorderedArgs); - $this->assertArrayHasKey(0, $reorderedArgs); $this->assertNull($reorderedArgs[0]->name, 'named-arg turned into regular numeric arg'); $this->assertInstanceOf(String_::class, $reorderedArgs[0]->value, 'value-arg at the right position'); - $this->assertArrayHasKey(1, $reorderedArgs); $this->assertNull($reorderedArgs[1]->name, 'named-arg turned into regular numeric arg'); $this->assertInstanceOf(LNumber::class, $reorderedArgs[1]->value, 'flags-arg at the right position'); $this->assertSame(0, $reorderedArgs[1]->value->value); @@ -90,17 +88,14 @@ public function testArgumentReorderAllNamedWithSkipped(): void $reorderedArgs = $funcCall->getArgs(); $this->assertCount(3, $reorderedArgs); - $this->assertArrayHasKey(0, $reorderedArgs); $this->assertNull($reorderedArgs[0]->name, 'named-arg turned into regular numeric arg'); $this->assertInstanceOf(String_::class, $reorderedArgs[0]->value, 'value-arg at the right position'); - $this->assertArrayHasKey(1, $reorderedArgs); $this->assertNull($reorderedArgs[1]->name, 'named-arg turned into regular numeric arg'); $this->assertInstanceOf(TypeExpr::class, $reorderedArgs[1]->value, 'flags-arg at the right position'); $this->assertInstanceOf(ConstantIntegerType::class, $reorderedArgs[1]->value->getExprType()); $this->assertSame(0, $reorderedArgs[1]->value->getExprType()->getValue(), 'flags-arg with default value'); - $this->assertArrayHasKey(2, $reorderedArgs); $this->assertNull($reorderedArgs[2]->name, 'named-arg turned into regular numeric arg'); $this->assertInstanceOf(LNumber::class, $reorderedArgs[2]->value, 'depth-arg at the right position'); $this->assertSame(128, $reorderedArgs[2]->value->value); @@ -153,10 +148,7 @@ public function testLeaveRegularCallAsIs(): void $reorderedArgs = $funcCall->getArgs(); $this->assertCount(2, $reorderedArgs); - $this->assertArrayHasKey(0, $reorderedArgs); $this->assertInstanceOf(String_::class, $reorderedArgs[0]->value, 'value-arg at unchanged position'); - - $this->assertArrayHasKey(1, $reorderedArgs); $this->assertInstanceOf(LNumber::class, $reorderedArgs[1]->value, 'flags-arg at unchanged position'); $this->assertSame(0, $reorderedArgs[1]->value->value); } From 1f71973b31197ea58fcd48943d4b3a71af3cae13 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 11:05:56 +0100 Subject: [PATCH 04/11] cs --- src/Analyser/ArgumentsNormalizer.php | 1 + src/Reflection/ParametersAcceptorSelector.php | 1 + src/Rules/Functions/RandomIntParametersRule.php | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Analyser/ArgumentsNormalizer.php b/src/Analyser/ArgumentsNormalizer.php index 9baa342ff4..418f58d760 100644 --- a/src/Analyser/ArgumentsNormalizer.php +++ b/src/Analyser/ArgumentsNormalizer.php @@ -13,6 +13,7 @@ use PHPStan\ShouldNotHappenException; use PHPStan\TrinaryLogic; use PHPStan\Type\Constant\ConstantArrayType; +use function array_is_list; use function array_key_exists; use function array_keys; use function count; diff --git a/src/Reflection/ParametersAcceptorSelector.php b/src/Reflection/ParametersAcceptorSelector.php index f98b9bf6e2..a679fb0f4e 100644 --- a/src/Reflection/ParametersAcceptorSelector.php +++ b/src/Reflection/ParametersAcceptorSelector.php @@ -43,6 +43,7 @@ use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypeTraverser; use PHPStan\Type\UnionType; +use function array_is_list; use function array_key_exists; use function array_key_last; use function array_map; diff --git a/src/Rules/Functions/RandomIntParametersRule.php b/src/Rules/Functions/RandomIntParametersRule.php index 62c21cb2c6..1205283002 100644 --- a/src/Rules/Functions/RandomIntParametersRule.php +++ b/src/Rules/Functions/RandomIntParametersRule.php @@ -14,7 +14,6 @@ use PHPStan\Type\Constant\ConstantIntegerType; use PHPStan\Type\IntegerRangeType; use PHPStan\Type\VerbosityLevel; -use function array_values; use function count; use function sprintf; From 74fc363f276eb407444e0865b0e9783899314a79 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 11:06:59 +0100 Subject: [PATCH 05/11] Discard changes to build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php --- build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php | 1 - 1 file changed, 1 deletion(-) diff --git a/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php b/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php index aa303212e5..8e43bd2d47 100644 --- a/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php +++ b/build/PHPStan/Build/ContainerDynamicReturnTypeExtension.php @@ -14,7 +14,6 @@ use PHPStan\Type\TypeCombinator; use function count; use function in_array; -use function PHPStan\dumpType; final class ContainerDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension { From c17dbe7f8e8af6d7c088c93ceaab834643c29681 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 11:24:03 +0100 Subject: [PATCH 06/11] Add PhpParserStmt --- build/phpstan.neon | 1 + build/stubs/PhpParserStmt.stub | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 build/stubs/PhpParserStmt.stub diff --git a/build/phpstan.neon b/build/phpstan.neon index 5d298dabe6..a7e8e596d5 100644 --- a/build/phpstan.neon +++ b/build/phpstan.neon @@ -125,6 +125,7 @@ parameters: - stubs/NetteDIContainer.stub - stubs/PhpParserName.stub - stubs/PhpParserExpr.stub + - stubs/PhpParserStmt.stub - stubs/Identifier.stub rules: diff --git a/build/stubs/PhpParserStmt.stub b/build/stubs/PhpParserStmt.stub new file mode 100644 index 0000000000..f7892fd80e --- /dev/null +++ b/build/stubs/PhpParserStmt.stub @@ -0,0 +1,17 @@ +|null Statements */ + public ?array $stmts; +} + +class If_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} From 77283612d0bb4640b85727ffc842110882a8e5d1 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 11:52:44 +0100 Subject: [PATCH 07/11] fix --- build/phpstan.neon | 1 + build/stubs/PhpParserExpr.stub | 5 +++++ build/stubs/PhpParserNode.stub | 10 ++++++++++ build/stubs/PhpParserStmt.stub | 6 ++++++ src/Parser/CleaningVisitor.php | 4 ++-- 5 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 build/stubs/PhpParserNode.stub diff --git a/build/phpstan.neon b/build/phpstan.neon index a7e8e596d5..57c896e08d 100644 --- a/build/phpstan.neon +++ b/build/phpstan.neon @@ -124,6 +124,7 @@ parameters: - stubs/ReactStreams.stub - stubs/NetteDIContainer.stub - stubs/PhpParserName.stub + - stubs/PhpParserNode.stub - stubs/PhpParserExpr.stub - stubs/PhpParserStmt.stub - stubs/Identifier.stub diff --git a/build/stubs/PhpParserExpr.stub b/build/stubs/PhpParserExpr.stub index 6eec4bf1f3..433505ff74 100644 --- a/build/stubs/PhpParserExpr.stub +++ b/build/stubs/PhpParserExpr.stub @@ -100,3 +100,8 @@ class StaticCall extends CallLike { */ public function __construct(Node $class, $name, array $args = [], array $attributes = []) {} } + +class Closure extends Expr implements FunctionLike { + /** @var list Statements */ + public array $stmts; +} diff --git a/build/stubs/PhpParserNode.stub b/build/stubs/PhpParserNode.stub new file mode 100644 index 0000000000..57585ed871 --- /dev/null +++ b/build/stubs/PhpParserNode.stub @@ -0,0 +1,10 @@ + Hook body */ + public $body; +} diff --git a/build/stubs/PhpParserStmt.stub b/build/stubs/PhpParserStmt.stub index f7892fd80e..f096a1d6b8 100644 --- a/build/stubs/PhpParserStmt.stub +++ b/build/stubs/PhpParserStmt.stub @@ -11,7 +11,13 @@ class ClassMethod extends Node\Stmt implements FunctionLike { public ?array $stmts; } +class Function_ extends Node\Stmt implements FunctionLike { + /** @var list Statements */ + public array $stmts; +} + class If_ extends Node\Stmt { /** @var list Statements */ public array $stmts; } + diff --git a/src/Parser/CleaningVisitor.php b/src/Parser/CleaningVisitor.php index c0f4c0b458..382769e3b4 100644 --- a/src/Parser/CleaningVisitor.php +++ b/src/Parser/CleaningVisitor.php @@ -50,8 +50,8 @@ public function enterNode(Node $node): ?Node } /** - * @param Node\Stmt[] $stmts - * @return Node\Stmt[] + * @param list $stmts + * @return list */ private function keepVariadicsAndYields(array $stmts, ?string $hookedPropertyName): array { From 620123a89342694c926616e134ce8c49b8ad7d9a Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 11:57:26 +0100 Subject: [PATCH 08/11] Update PhpParserExpr.stub --- build/stubs/PhpParserExpr.stub | 1 + 1 file changed, 1 insertion(+) diff --git a/build/stubs/PhpParserExpr.stub b/build/stubs/PhpParserExpr.stub index 433505ff74..636d8cf5b4 100644 --- a/build/stubs/PhpParserExpr.stub +++ b/build/stubs/PhpParserExpr.stub @@ -8,6 +8,7 @@ use PhpParser\Node\Arg; use PhpParser\Node\Expr; use PhpParser\Node\Identifier; use PhpParser\Node\VariadicPlaceholder; +use PhpParser\Node\FunctionLike; abstract class CallLike extends Expr { /** From 35818b80a94477310626dc498d6642fe8196ad69 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 12:04:27 +0100 Subject: [PATCH 09/11] added all classes wrapping stmts --- build/stubs/PhpParserStmt.stub | 68 ++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/build/stubs/PhpParserStmt.stub b/build/stubs/PhpParserStmt.stub index f096a1d6b8..0e33aff1a3 100644 --- a/build/stubs/PhpParserStmt.stub +++ b/build/stubs/PhpParserStmt.stub @@ -6,12 +6,47 @@ use PhpParser\Modifiers; use PhpParser\Node; use PhpParser\Node\FunctionLike; -class ClassMethod extends Node\Stmt implements FunctionLike { - /** @var list|null Statements */ - public ?array $stmts; +class Block extends Stmt { + /** @var list Statements */ + public array $stmts; } -class Function_ extends Node\Stmt implements FunctionLike { +class Case_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class Catch_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class Do_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class ElseIf_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class Else_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class Finally_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class For_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class Foreach_ extends Node\Stmt { /** @var list Statements */ public array $stmts; } @@ -21,3 +56,28 @@ class If_ extends Node\Stmt { public array $stmts; } +class Namespace_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class TryCatch extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class While_ extends Node\Stmt { + /** @var list Statements */ + public array $stmts; +} + +class ClassMethod extends Node\Stmt implements FunctionLike { + /** @var list|null Statements */ + public ?array $stmts; +} + +class Function_ extends Node\Stmt implements FunctionLike { + /** @var list Statements */ + public array $stmts; +} + From a8cbd0ac0fca2905d959a96b744889e906f0139f Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 12:06:06 +0100 Subject: [PATCH 10/11] Update PhpParserStmt.stub --- build/stubs/PhpParserStmt.stub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/stubs/PhpParserStmt.stub b/build/stubs/PhpParserStmt.stub index 0e33aff1a3..950658805c 100644 --- a/build/stubs/PhpParserStmt.stub +++ b/build/stubs/PhpParserStmt.stub @@ -6,7 +6,7 @@ use PhpParser\Modifiers; use PhpParser\Node; use PhpParser\Node\FunctionLike; -class Block extends Stmt { +class Block extends Node\Stmt { /** @var list Statements */ public array $stmts; } From d570956c12bd0c163efd30d191a3d4daaad4d18d Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 31 Oct 2025 13:36:52 +0100 Subject: [PATCH 11/11] fix --- src/Analyser/ArgumentsNormalizer.php | 3 ++- src/Reflection/ParametersAcceptorSelector.php | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Analyser/ArgumentsNormalizer.php b/src/Analyser/ArgumentsNormalizer.php index 418f58d760..7b8f4259fa 100644 --- a/src/Analyser/ArgumentsNormalizer.php +++ b/src/Analyser/ArgumentsNormalizer.php @@ -16,6 +16,7 @@ use function array_is_list; use function array_key_exists; use function array_keys; +use function array_values; use function count; use function ksort; use function max; @@ -324,7 +325,7 @@ public static function reorderArgs(ParametersAcceptor $parametersAcceptor, array } if (!array_is_list($reorderedArgs)) { - throw new ShouldNotHappenException(); + $reorderedArgs = array_values($reorderedArgs); } return $reorderedArgs; diff --git a/src/Reflection/ParametersAcceptorSelector.php b/src/Reflection/ParametersAcceptorSelector.php index a679fb0f4e..f6c3058cc2 100644 --- a/src/Reflection/ParametersAcceptorSelector.php +++ b/src/Reflection/ParametersAcceptorSelector.php @@ -473,7 +473,9 @@ public static function selectFromArgs( $singleParametersAcceptor = null; if (count($parametersAcceptors) === 1) { if (!array_is_list($args)) { - throw new ShouldNotHappenException('args is expected to be a list'); + // actually $args parameter should be typed to list but we can't atm, + // because its a BC break. + $args = array_values($args); } $reorderedArgs = ArgumentsNormalizer::reorderArgs($parametersAcceptors[0], $args); $singleParametersAcceptor = $parametersAcceptors[0];