re #96 add @template generics to univeros/structure collections#106
Merged
Conversation
Genericises the whole collection library as one coherent, PHPDoc-only, runtime-safe refactor. Baseline 325 -> 111 entries (-214) — the bulk of the level-6 burn-down. @template scheme (interface and concrete mirror each other): - CollectionInterface<TKey, TValue> extends Traversable<TKey, TValue> - MapInterface<TKey, TValue>; SetInterface<TValue>, SequenceInterface<TValue>, VectorInterface<TValue>, Stack/Queue<TValue> extend CollectionInterface<int, TValue>; PairInterface<TKey, TValue>; PriorityNodeInterface<TValue> - concrete classes add @implements + pin SPL generics (@implements IteratorAggregate<...> / ArrayAccess<...>); Pair's promoted $key/$value get @var TKey/@var TValue (native `mixed` unchanged) - traits carry their own @template and @use the base trait with bound args; $internal typed per storage shape (array<int, TValue> for sequences, array<int, Pair<TKey, TValue>> for Map) Object-key correctness: Map permits arbitrary (incl. object) keys, so every toArray()/jsonSerialize() returning a PHP array is typed array<array-key, TValue> (not array<TKey, ...>); TKey flows only through iteration. PHPDoc-only: no native type or native property-type changes (avoids the uninitialised-property class of bug). The one runtime touch is a behaviour-neutral `$values ?? []` guard in Set::__construct to satisfy template inference on the spread. Four documented @PHPStan-Ignore line-suppressions remain in CollectionTrait: the shared trait is used by collections with different storage shapes, so the `$internal = []` default can't match every narrowed @var and the capacity/append paths are unreachable for the delegate-backed collections. Each is annotated with the reason; they mask no real bug (verified with reportUnmatchedIgnoredErrors). Consumer impact: generic base types mean subclasses/users must now specify args, so ~28 new "does not specify its types" findings appear in Cookie, Container, Http, Courier etc. — net still -214. Those are a clean mechanical follow-up (declare @extends Map<...> on the consumer collections, which also clears the MapInterface-return findings left by earlier chunks). Rector then applied configured-set cleanups unlocked by the new types (useless @return removal, return-type inference). composer stan / cs / rector --dry-run green; full suite at the 5 pre-existing ext-mongodb environmental errors; 2724 Structure tests pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The big one — genericises the whole collection library (
Map/Set/Vector/Deque/Stack/Queue/PriorityQueue/Pair) as one coherent, PHPDoc-only, runtime-safe refactor. Baselinephpstan-baseline.neon: 325 → 111 entries (−214), the bulk of the #96 level-6 burn-down.@templateschemeCollectionInterface<TKey, TValue>@extends Traversable<TKey, TValue>MapInterface<TKey, TValue>;SetInterface<TValue>/SequenceInterface<TValue>/VectorInterface<TValue>/Stack/Queue<TValue>@extends CollectionInterface<int, TValue>;PairInterface<TKey, TValue>;PriorityNodeInterface<TValue>@implementsand pin the SPL generics (IteratorAggregate<…>/ArrayAccess<…>);Pair's promoted$key/$valueget@var TKey/@var TValue(nativemixedunchanged)@templateand@usethe base trait with bound args;$internaltyped per storage shapeCorrectness calls
Mapallows arbitrary (incl. object) keys, so everytoArray()/jsonSerialize()returning a PHP array is typedarray<array-key, TValue>— notarray<TKey, …>.TKeyflows only through iteration.$values ?? []guard inSet::__constructfor template inference.@phpstan-ignoreinCollectionTrait: the shared trait serves collections with different storage shapes, so the$internal = []default can't match every narrowed@varand the capacity/append paths are unreachable for delegate-backed collections. Each annotated with a reason; masks no real bug (verified withreportUnmatchedIgnoredErrors).Consumer impact (read this)
Generic base types mean subclasses/users must now specify args, so ~28 new "does not specify its types" findings appear in Cookie (+13), Container (+8), Http (+4), Courier, etc. Net is still −214. These are a clean mechanical follow-up: declare
@extends Map<…>on the consumer collection classes — which also clears theMapInterface-return findings earlier chunks had to leave. I scoped them out to keep this core-library change reviewable on its own.Verification
composer stangreen (111 baselined, 0 live), CS clean, rector--dry-runclean (after applying the configured-set cleanups the new types unlocked).ext-mongodberrors, no regressions (the agent's 2724 Structure tests pass; I verified the whole suite since every package consumes these collections).Part of #96. Progress: 719 → 111 (85% cleared.) Remaining: ~28 consumer
@extendsdeclarations + the small code-quality leftovers (unsafenew static, strict comparisons, subtype conflicts), then raise level 6 → 7 → 8.