chore: raise PHPStan to level 8 - #133
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #133 +/- ##
============================================
+ Coverage 97.05% 97.48% +0.43%
- Complexity 309 313 +4
============================================
Files 25 25
Lines 986 996 +10
============================================
+ Hits 957 971 +14
+ Misses 29 25 -4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Level 8 checks calls on nullable types, which surfaced three real holes: - `configElem()` dropped the element it was configuring whenever a `CONTAINER` config produced no element of its own. It now keeps the element in that case, which also makes it total: given an element, it always returns one. That is expressed as a conditional return type, so `getElem()` can be declared to return `Html` rather than `Html|null` and its ~20 call sites no longer look nullable. - `BootstrapRow::$container` was typed `Container` but `setParent()` accepts `?IContainer`, so a detached row held null behind a non-nullable type. The property is now nullable, `getParent()` reports that honestly, `setParent()` rejects a parent that is not a `Nette\Forms\Container`, and the new `getContainer()` gives rendering code the attached container or a clear exception. - `BootstrapRow::$ownedNames` was declared `string[]` but collected the nullable `$name` argument. It now records the name the component actually ends up with. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
dakorpar
force-pushed
the
chore/phpstan-level-up
branch
from
August 14, 2026 19:44
c81720b to
1a19a7f
Compare
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.
Raises the PHPStan level in
make phpstanfrom 7 to 8. Level 8 checks method calls and property access on nullable types, which surfaced three real holes rather than just noise.What level 8 found
BootstrapRenderer::configElem()could throw away the element it was configuring.When a config entry had a
CONTAINERkey whose own config produced no element,$el = $containeroverwrote the element withnulland the caller silently lost it. It now only swaps in the container when there is one. That also makes the method total — given an element, it always returns one — which is expressed with a conditional return type:With that,
getElem()is declared: Htmlinstead of: ?Html, and its ~20 call sites acrossrenderBody(),renderPair(),renderFeedback()andrenderDescription()stop looking nullable. TwoconfigElem(…, null)calls that always needed a real element were switched togetElem(), and a dead!empty($nonLabel)guard on an always-truthyHtmlobject was dropped.BootstrapRow::$containerwas typedContainerbut could holdnull.setParent()takes?IContainerand assigned straight to the property, so a detached row (or one attached to a non-Nette\Forms\Container) violated its own declared type. Now:Container|null;getParent()returns?IContainer, matchingIComponentand reality;setParent()throwsInvalidArgumentExceptionfor a parent that is not aNette\Forms\Container, instead of storing something the rest of the class cannot use;getContainer(): Containergivesrender(),addComponent()andBootstrapCell::render()the attached container, or anInvalidStateExceptionwith a clear message instead of a null-call fatal.BootstrapRow::$ownedNameswas declaredstring[]but collected?string.It now records the name the component actually ends up with after the add.
API notes
BootstrapRow::getParent()widened fromIContainerto?IContainer. Callers that need the container should use the newgetContainer().Verification
make phpstan(now-l 8) — no errorsmake cs— cleanmake tests— 161 tests, 245 assertions, all passing (3 new tests cover the detached-row and wrong-parent paths)No fixture changes: rendered HTML is unchanged.
🤖 Generated with Claude Code