Add IDE type narrowing to generated validator mixins - #1802
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1802 +/- ##
=========================================
Coverage 97.14% 97.14%
Complexity 1096 1096
=========================================
Files 198 198
Lines 2554 2554
=========================================
Hits 2481 2481
Misses 73 73 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@henriquemoody these are in draft because of the branch-alias (we need to amend the real composer versions when we do the release dance). However, although not packagist-ready yet, they are open for review of the code. I requested review only here to avoid spam but you're free to comment in any of the 3. |
henriquemoody
left a comment
There was a problem hiding this comment.
This is trully trully awesome!!
| '{{subject}} must be a scalar', | ||
| '{{subject}} must not be a scalar', | ||
| )] | ||
| #[Assurance(type: 'int|float|bool|string', exact: true)] |
There was a problem hiding this comment.
| #[Assurance(type: 'int|float|bool|string', exact: true)] | |
| #[Assurance(type: 'scalar', exact: true)] |
Or am I missing something?
There was a problem hiding this comment.
For this PR, it's the same.
For FluentAnalysis, there are some things we don't do yet (like unpacking scalar into the list for multi-node hop narrowing).
So, in the future, we might have to pre-unpack all types in declaration instead of using the more elegant one, just to give FluentAnalysis more surface. Or we might want to implement the unpacking in FluentAnalysis.
There was a problem hiding this comment.
We can't instruct IDEs into unpacking scalar into the list, and some of they don't do that. PHPStan does, and the FluentAnalysis extension can be made to do that by using the types package from phpstan.
For that reason, I would prefer using the unpacked explicit list. scalar is an alias for that list, and if by exposing the list we target more IDEs, that would be my preference.
07ccc7d to
3ec0d33
Compare
|
I have removed the Hopefully, this would make clear what IDEs can do and what they cannot (the static-narrowing.php file is a good reference card though, and remains the same). |
67ea602 to
d26a84c
Compare
d26a84c to
eeb5975
Compare
Make validator chains narrow types for IDEs and PHPStan without the FluentAnalysis extension, driven entirely by the generated src/Mixins PHPDoc. - Annotate src/Validators with #[Assurance] / #[AssuranceSubject] declaring each rule's assured type. - Regenerate src/Mixins: Chain becomes generic (@template-covariant TSure); static entry methods narrow to Chain<concrete>; assert()/check() carry an unconditional @phpstan-assert TSure. Container rules (key/property/length/ max/min) and the concrete prefix forms (nullOrIntType, keyIntType, allIntType) narrow; argument-wrapping and compose forms stay Chain<mixed> so a raw (non-fluent) Validator argument is still accepted. - isValid() intentionally does not narrow: its only conditional form is a two-way guard, unsound for inexact rules on the false branch. - Add the tests/inference static-narrowing suite (no extension config) and run it in CI; scope the phpstan/phpcs accommodations for generated mixins.
eeb5975 to
3d288ea
Compare
Part of a PR group: Fluent - FluentGen - Validation
Make validator chains narrow types for IDEs and PHPStan without the FluentAnalysis extension, driven entirely by the generated src/Mixins PHPDoc.
This PR group adds advanced static (no PHPStan extension needed) type support and narrowing for fluent chains, pioneering it for Validation (StringFormatter should also be compatible with this approach)
In the example above, the devsense extension for VSCode is correctly infering an
int[](iterable int) from aeach(int())fluent validation chain.More examples in
tests/inference/assertions/static-narrowing.php.Notes: