Repository navigation
Load an ext-ds v2 stub overlay with list return types when ext-ds 2 is selected - #6939
phpstan-bot wants to merge 1 commit into
Conversation
… is selected
- ExtDsStubFilesExtension only loaded stubs/ext-ds.stub for ext-ds 1 and
nothing for ext-ds 2, so v2 classes fell back to the plain PhpStorm
ds_v2 stubs (`array<int, TValue>` for toArray() etc.).
- Add stubs/ext-ds-v2.stub and load it when ext-ds 2 is detected:
- `list<TValue>` for Seq/Set/Heap toArray() and jsonSerialize(), and
Seq/Heap __serialize()
- the same generic precision the v1 overlay has: widening
merge()/union()/xor(), intersect()/diff() on Map and Set, Seq::merge(),
Map::get()/remove() with a TDefault template (no `|null` without a
default), and typed reduce() on Seq/Map/Set
- Add ExtDsV2Test with an ext-ds ^2 composer.json fixture.
VincentLanglet
left a comment
There was a problem hiding this comment.
Shouldn't we rely on the phpstorm stubs for the v2 ? https://github.com/JetBrains/phpstorm-stubs/blob/f5ebeeaff58ab1000c1a4c2e8fba03a2797e2090/ds_v2/ds.php#L82
|
I didn't change any code. With the PhpStorm stubs alone, users get exactly the regression reported in the issue. Why the PhpStorm stubs aren't enough: the stub you linked (
So the stubs aren't missing anything ext-ds 2 has. They are just less precise than PHPStan's own What the v2 overlay does: it only overrides the methods whose PhpStorm types are imprecise. Everything else, including the class shapes, Fixing it upstream instead: we could also send a PR to JetBrains/phpstorm-stubs. That would only cover the Checks: |
Summary
Since 2.2.15 PHPStan picks the ext-ds stubs by major version. For ext-ds 2 it loaded no PHPStan overlay at all. Types came only from the PhpStorm
ds_v2stubs, soDs\Set::toArray()and similar methods becamearray<int, TValue>instead oflist<TValue>. This PR adds an overlay for ext-ds 2 and loads it when version 2 is detected.Changes
stubs/ext-ds-v2.stub(new): overlay for the ext-ds 2 classesSeq,Map,SetandHeap:list<TValue>fortoArray()andjsonSerialize()onSeq,SetandHeap, and for__serialize()onSeqandHeapmerge(),union()andxor()widen the type parametersintersect()anddiff()onMapandSetSeq::merge()Map::get()andMap::remove()use aTDefaulttemplate, so the result isTValue(notTValue|null) when no default is passedreduce()is typed onSeq,MapandSetsrc/PhpDoc/ExtDsStubFilesExtension.php: returnext-ds-v2.stubfor ext-ds 2. ext-ds 1 and unknown versions behave as before.@throwstags from the v1 overlay, because the v2 exception classes aren't confirmed. Without them the methods stay implicitly throwing, so catch blocks are not reported as dead.Root cause
Commit 677df31 ("Select versioned extension stubs") made
ext-ds.stubload only for ext-ds 1. It added no v2 counterpart. So everything the overlay used to refine (listreturns, widening generics,TDefaultonget/remove) was lost for v2 users, not justtoArray().Test
tests/PHPStan/Analyser/ExtDsV2Test.phpwithdata/ext-ds-v2.phpand anext-ds ^2composer.json fixture (data/ext-ds-v2-platform). It covers:toArray(),jsonSerialize()and__serialize()on all v2 collectionsMap::get()andMap::remove(), with and without a defaultmerge(),union()andxor()onMap,SetandSeqreduce()The test fails without the change in
ExtDsStubFilesExtension(10 failures) and passes with it.Fixes phpstan/phpstan#15645
🤖 Generated with Claude Code