From 6962d3601c5374b7b7e81e6f2f6cecf3cd180857 Mon Sep 17 00:00:00 2001 From: przepompownia Date: Thu, 28 Mar 2024 00:02:34 +0100 Subject: [PATCH 1/5] Add test --- .../FrameWalker/FunctionLikeWalkerTest.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php b/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php index c46f5bf80e..c61eb3d725 100644 --- a/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php +++ b/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php @@ -34,6 +34,29 @@ public function hello() $this->assertEquals(false, $frame->locals()->byName('this')->first()->isProperty()); }]; + yield 'It returns this with correct type' => [ + <<<'EOT' + }); + } + } + + EOT + , function (Frame $frame): void { + $this->assertCount(1, $frame->locals()->byName('this')); + $this->assertEquals('Foobar\Barfoo\Foobar', $frame->locals()->byName('this')->first()->type()->__toString()); + $this->assertEquals(false, $frame->locals()->byName('this')->first()->isProperty()); + }]; + yield 'It returns method arguments' => [ <<<'EOT' Date: Thu, 28 Mar 2024 14:12:53 +0100 Subject: [PATCH 2/5] Fixing regression of object type creation classes --- .../Core/Inference/Walker/FunctionLikeWalker.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php b/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php index 06b4002292..8314eee1ed 100644 --- a/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php +++ b/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php @@ -76,6 +76,17 @@ private function walkFunctionLike(FrameResolver $resolver, Frame $frame, Functio ObjectCreationExpression::class, // For Inline classes ); + while ($classNode instanceof ObjectCreationExpression && $classNode->classTypeDesignator instanceof Node) { + // If we are here we found a normal ObjectCreationExpression like: new A(); and this is not useful and we continue traversing + $classNode = $classNode->getFirstAncestor( + ClassDeclaration::class, + InterfaceDeclaration::class, + TraitDeclaration::class, + EnumDeclaration::class, + ObjectCreationExpression::class, // For Inline classes + ); + } + if ($node instanceof AnonymousFunctionCreationExpression) { $this->addAnonymousImports($frame, $node); @@ -87,7 +98,7 @@ private function walkFunctionLike(FrameResolver $resolver, Frame $frame, Functio } // works for both closure and class method (we currently ignore binding) - if ($classNode) { + if ($classNode !== null) { $classType = $resolver->resolveNode($frame, $classNode)->type(); $this->addClassContext($node, $classType, $frame); } From 74d67df450c183a8535251efd59317a7b8c832e0 Mon Sep 17 00:00:00 2001 From: mamazu <14860264+mamazu@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:30:27 +0100 Subject: [PATCH 3/5] using do while for less code --- .../Core/Inference/Walker/FunctionLikeWalker.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php b/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php index 8314eee1ed..57324e4380 100644 --- a/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php +++ b/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php @@ -68,15 +68,7 @@ public function exit(FrameResolver $resolver, Frame $frame, Node $node): Frame private function walkFunctionLike(FrameResolver $resolver, Frame $frame, FunctionLike $node): void { $namespace = $node->getNamespaceDefinition(); - $classNode = $node->getFirstAncestor( - ClassDeclaration::class, - InterfaceDeclaration::class, - TraitDeclaration::class, - EnumDeclaration::class, - ObjectCreationExpression::class, // For Inline classes - ); - - while ($classNode instanceof ObjectCreationExpression && $classNode->classTypeDesignator instanceof Node) { + do { // If we are here we found a normal ObjectCreationExpression like: new A(); and this is not useful and we continue traversing $classNode = $classNode->getFirstAncestor( ClassDeclaration::class, @@ -85,7 +77,7 @@ private function walkFunctionLike(FrameResolver $resolver, Frame $frame, Functio EnumDeclaration::class, ObjectCreationExpression::class, // For Inline classes ); - } + } while ($classNode instanceof ObjectCreationExpression && $classNode->classTypeDesignator instanceof Node); if ($node instanceof AnonymousFunctionCreationExpression) { $this->addAnonymousImports($frame, $node); From f2d009e3ccc04a187077c09e237d43cbfd508e59 Mon Sep 17 00:00:00 2001 From: mamazu <14860264+mamazu@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:53:45 +0100 Subject: [PATCH 4/5] improving test names --- .../Core/Inference/FrameWalker/FunctionLikeWalkerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php b/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php index c61eb3d725..b1750e48b1 100644 --- a/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php +++ b/lib/WorseReflection/Tests/Integration/Core/Inference/FrameWalker/FunctionLikeWalkerTest.php @@ -34,7 +34,7 @@ public function hello() $this->assertEquals(false, $frame->locals()->byName('this')->first()->isProperty()); }]; - yield 'It returns this with correct type' => [ + yield 'It returns this with correct type in an anonymous function' => [ <<<'EOT' Date: Thu, 28 Mar 2024 14:57:18 +0100 Subject: [PATCH 5/5] Fixing stuff --- .../Core/Inference/Walker/FunctionLikeWalker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php b/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php index 57324e4380..a618bdb160 100644 --- a/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php +++ b/lib/WorseReflection/Core/Inference/Walker/FunctionLikeWalker.php @@ -70,7 +70,7 @@ private function walkFunctionLike(FrameResolver $resolver, Frame $frame, Functio $namespace = $node->getNamespaceDefinition(); do { // If we are here we found a normal ObjectCreationExpression like: new A(); and this is not useful and we continue traversing - $classNode = $classNode->getFirstAncestor( + $classNode = ($classNode ?? $node)->getFirstAncestor( ClassDeclaration::class, InterfaceDeclaration::class, TraitDeclaration::class,