File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 4444use PHPStan \Node \Printer \ExprPrinter ;
4545use PHPStan \Node \VirtualNode ;
4646use PHPStan \Parser \ArrayMapArgVisitor ;
47+ use PHPStan \Parser \ImmediatelyInvokedClosureVisitor ;
4748use PHPStan \Parser \Parser ;
4849use PHPStan \Php \PhpVersion ;
4950use PHPStan \Php \PhpVersionFactory ;
@@ -2153,12 +2154,16 @@ public function enterAnonymousFunctionWithoutReflection(
21532154 }
21542155
21552156 if (
2156- $ expr instanceof PropertyFetch
2157- || $ expr instanceof MethodCall
2158- || $ expr instanceof Expr \NullsafePropertyFetch
2159- || $ expr instanceof Expr \NullsafeMethodCall
2160- || $ expr instanceof Expr \StaticPropertyFetch
2161- || $ expr instanceof Expr \StaticCall
2157+ $ closure ->getAttribute (ImmediatelyInvokedClosureVisitor::ATTRIBUTE_NAME ) !== true
2158+ && $ closure ->getAttribute (ArrayMapArgVisitor::ATTRIBUTE_NAME ) === null
2159+ && (
2160+ $ expr instanceof PropertyFetch
2161+ || $ expr instanceof MethodCall
2162+ || $ expr instanceof Expr \NullsafePropertyFetch
2163+ || $ expr instanceof Expr \NullsafeMethodCall
2164+ || $ expr instanceof Expr \StaticPropertyFetch
2165+ || $ expr instanceof Expr \StaticCall
2166+ )
21622167 ) {
21632168 continue ;
21642169 }
Original file line number Diff line number Diff line change @@ -69,4 +69,24 @@ function ($key) use ($arr): void {
6969 }
7070 }
7171
72+ public function doIife (MethodCall $ call ): void
73+ {
74+ if ($ call ->name instanceof Identifier) {
75+ // IIFE - property types should be carried forward
76+ (function () use ($ call ): void {
77+ assertType ('PhpParser\Node\Identifier ' , $ call ->name );
78+ })();
79+ }
80+ }
81+
82+ public function doArrayMap (MethodCall $ call ): void
83+ {
84+ if ($ call ->name instanceof Identifier) {
85+ // array_map - closure is immediately invoked, property types should be carried forward
86+ array_map (function () use ($ call ): void {
87+ assertType ('PhpParser\Node\Identifier ' , $ call ->name );
88+ }, [1 ]);
89+ }
90+ }
91+
7292}
Original file line number Diff line number Diff line change @@ -57,7 +57,16 @@ public function testBug2457(): void
5757
5858 public function testBug10345 (): void
5959 {
60- $ this ->analyse ([__DIR__ . '/data/bug-10345.php ' ], []);
60+ $ this ->analyse ([__DIR__ . '/data/bug-10345.php ' ], [
61+ [
62+ 'Empty array passed to foreach. ' ,
63+ 125 ,
64+ ],
65+ [
66+ 'Empty array passed to foreach. ' ,
67+ 134 ,
68+ ],
69+ ]);
6170 }
6271
6372}
Original file line number Diff line number Diff line change @@ -116,3 +116,21 @@ public static function setItems(array $items): void
116116
117117 $ a6 = $ func6 ();
118118}
119+
120+ // Immediately invoked closure (IIFE) - should still detect empty array
121+ $ container7 = new \stdClass ();
122+ $ container7 ->items = [];
123+
124+ $ result7 = (function () use ($ container7 ): int {
125+ foreach ($ container7 ->items as $ item ) {}
126+ return 1 ;
127+ })();
128+
129+ // array_map - closure is immediately invoked, should still detect empty array
130+ $ container8 = new \stdClass ();
131+ $ container8 ->items = [];
132+
133+ $ result8 = array_map (function () use ($ container8 ): int {
134+ foreach ($ container8 ->items as $ item ) {}
135+ return 1 ;
136+ }, [1 ]);
You can’t perform that action at this time.
0 commit comments