@@ -237,3 +237,163 @@ public function doFoo(array $a): void
237237 }
238238
239239}
240+
241+ class NonFinalObjectWithVisibility
242+ {
243+ public int $ pub = 1 ;
244+ protected int $ prot = 2 ;
245+ private int $ priv = 3 ;
246+ }
247+
248+ final class FinalObjectWithVisibility
249+ {
250+ public int $ pub = 1 ;
251+ protected int $ prot = 2 ;
252+ private int $ priv = 3 ;
253+ }
254+
255+ class ArrayColumnVisibilityNonFinalTest
256+ {
257+
258+ /** @param array<int, NonFinalObjectWithVisibility> $objects */
259+ public function testNonFinal (array $ objects ): void
260+ {
261+ assertType ('list<int> ' , array_column ($ objects , 'pub ' ));
262+ assertType ('list<int> ' , array_column ($ objects , 'prot ' ));
263+ assertType ('list ' , array_column ($ objects , 'priv ' ));
264+ }
265+
266+ /** @param array{NonFinalObjectWithVisibility} $objects */
267+ public function testNonFinalConstant (array $ objects ): void
268+ {
269+ assertType ('array{int} ' , array_column ($ objects , 'pub ' ));
270+ assertType ('list<int> ' , array_column ($ objects , 'prot ' )); // Could be array{}|array{int}
271+ assertType ('list ' , array_column ($ objects , 'priv ' ));
272+ }
273+
274+ }
275+
276+ class ArrayColumnVisibilityFinalTest
277+ {
278+
279+ /** @param array<int, FinalObjectWithVisibility> $objects */
280+ public function testFinal (array $ objects ): void
281+ {
282+ assertType ('list<int> ' , array_column ($ objects , 'pub ' ));
283+ assertType ('array{} ' , array_column ($ objects , 'prot ' ));
284+ assertType ('array{} ' , array_column ($ objects , 'priv ' ));
285+ }
286+
287+ /** @param array{FinalObjectWithVisibility} $objects */
288+ public function testFinalConstant (array $ objects ): void
289+ {
290+ assertType ('array{int} ' , array_column ($ objects , 'pub ' ));
291+ assertType ('array{} ' , array_column ($ objects , 'prot ' ));
292+ assertType ('array{} ' , array_column ($ objects , 'priv ' ));
293+ }
294+
295+ /** @param array<int, FinalObjectWithVisibility> $objects */
296+ public function testNonPublicAsIndex (array $ objects ): void
297+ {
298+ assertType ('array<int, int> ' , array_column ($ objects , 'pub ' , 'pub ' ));
299+ assertType ('array<int, int> ' , array_column ($ objects , 'pub ' , 'priv ' ));
300+ }
301+
302+ }
303+
304+ class ArrayColumnVisibilityImplicitFinalTest
305+ {
306+
307+ public function testNewExpression (): void
308+ {
309+ $ objects = [new NonFinalObjectWithVisibility ()];
310+ assertType ('array{int} ' , array_column ($ objects , 'pub ' ));
311+ assertType ('array{} ' , array_column ($ objects , 'prot ' ));
312+ assertType ('array{} ' , array_column ($ objects , 'priv ' ));
313+ }
314+
315+ }
316+
317+ class ArrayColumnVisibilityFromInsideTest
318+ {
319+
320+ public int $ pub = 1 ;
321+ private int $ priv = 2 ;
322+
323+ /** @param list<self> $objects */
324+ public function testFromInside (array $ objects ): void
325+ {
326+ assertType ('list<int> ' , array_column ($ objects , 'pub ' ));
327+ assertType ('list<int> ' , array_column ($ objects , 'priv ' ));
328+ }
329+
330+ }
331+
332+ class ArrayColumnVisibilityFromChildTest extends NonFinalObjectWithVisibility
333+ {
334+
335+ /** @param list<NonFinalObjectWithVisibility> $objects */
336+ public function testFromChild (array $ objects ): void
337+ {
338+ assertType ('list<int> ' , array_column ($ objects , 'pub ' ));
339+ assertType ('list<int> ' , array_column ($ objects , 'prot ' ));
340+ assertType ('list ' , array_column ($ objects , 'priv ' ));
341+ }
342+
343+ }
344+
345+ final class ObjectWithIssetOnly
346+ {
347+ private int $ priv = 2 ;
348+
349+ public function __isset (string $ name ): bool
350+ {
351+ return true ;
352+ }
353+ }
354+
355+ class ArrayColumnVisibilityWithIssetOnlyTest
356+ {
357+
358+ /** @param array<int, ObjectWithIssetOnly> $objects */
359+ public function testWithIssetOnly (array $ objects ): void
360+ {
361+ assertType ('array{} ' , array_column ($ objects , 'priv ' ));
362+ }
363+
364+ }
365+
366+ class ObjectWithIsset
367+ {
368+ public int $ pub = 1 ;
369+ private int $ priv = 2 ;
370+
371+ public function __isset (string $ name ): bool
372+ {
373+ return true ;
374+ }
375+
376+ public function __get (string $ name ): mixed
377+ {
378+ return $ this ->$ name ;
379+ }
380+ }
381+
382+ class ArrayColumnVisibilityWithIssetTest
383+ {
384+
385+ /** @param array<int, ObjectWithIsset> $objects */
386+ public function testWithIsset (array $ objects ): void
387+ {
388+ assertType ('list<int> ' , array_column ($ objects , 'pub ' ));
389+ assertType ('list ' , array_column ($ objects , 'priv ' ));
390+ }
391+
392+ /** @param array{ObjectWithIsset} $objects */
393+ public function testWithIssetConstant (array $ objects ): void
394+ {
395+ assertType ('array{int} ' , array_column ($ objects , 'pub ' ));
396+ assertType ('list ' , array_column ($ objects , 'priv ' ));
397+ }
398+
399+ }
0 commit comments