Prevent reporting property.inInterface error when PHP version is 8.4 or later#3656
Prevent reporting property.inInterface error when PHP version is 8.4 or later#3656ondrejmirtes merged 11 commits intophpstan:2.0.xfrom jakubtobiasz:allow-properties-in-interface-on-php-84
property.inInterface error when PHP version is 8.4 or later#3656Conversation
|
You need a bit more research on the topic, e.g. it seems the properties on interfaces are only allowed when public and you need tests for the new cases |
| final class PropertiesInInterfaceRule implements Rule | ||
| { | ||
|
|
||
| private const PHP_8_4_VERSION_ID = 80400; |
There was a problem hiding this comment.
PhpVersion id-checks need to go into a new method of PhpVersion class
|
Hi @staabm, Thanks for leaving your review 🤠.
Right, I knew about it but missed it here. So in case of a) We should just report I bet the option At the same time, I guess we should leave this implementation as-is (so |
|
Please wait for my review before further steps 😊 |
ondrejmirtes
left a comment
There was a problem hiding this comment.
Please note that in PHP 8.4 not all properties in interface are allowed. Please read the Interfaces section in https://wiki.php.net/rfc/property-hooks.
- Only public properties can be in an interface
- Only properties with get or set or both hooks can be in an interface.
- Property hook in an interface cannot have a body.
The rule should account for all of this.
Please note that the original error message "Interfaces may not include properties." is not exactly correct on PHP 8.4 so all of these situations should have new messages.
Thanks.
| if (PHP_VERSION_ID < 80400) { | ||
| $this->markTestSkipped('This test requires at least PHP 8.4.'); | ||
| } |
There was a problem hiding this comment.
I'm not 100% sure about this approach. In theory it is valid; however, maybe we should mock PhpVersion or set PHP_VERSION_ID by hand.
|
@ondrejmirtes I've implemented all suggestions, and I'm ready for the next ones (if needed 😅). |
ondrejmirtes
left a comment
There was a problem hiding this comment.
- We don't need to do this in multiple rules. It kind of makes it hard to see what situations are covered or not. A decision tree (series of if-else conditions) in a single rule would be much more readable and understandable. So please do this in a single rule. The right moment to split a rule might come later but not now.
- There are cases not covered by your added code. Properties can be abstract even in classes, meaning at least one of their hooks must not have a body.
|
I was focused on interfaces and fixing the issue with However, from my POV, the first and second bullets are conflicted. If we want to add handling abstract classes with the logic inside the In my humble opinion, we should stay with split classes as they follow SRP and new features seem to not fit the So my suggestion is to leave the separation and cover abstract classes as a separate PR, as in such a case this PR could be merged as a bugfix for Of course, I'm waiting for your decision 🖖🏻. |
|
I don't want this PR to completely implement property hooks, that's a much bigger project. I just want it to check what I said I want it to check. So to report a wrong declaration that's detectable just by looking at it. I don't even want this rule to check missing implementation of an abstract hook from a parent. That's a job for a different rule. Here's a complete list of things that should be reported by this (single) rule class after this PR:
I'd understand if you decide not to work on this. In that case you can close this PR. But in my eyes this is the minimal work needed for the rule to make sense if it's supposed to understand "some properties can now be in interface" which is what you want to achieve. |
Nah, that's not the case. I'll do my best to deliver this :). I'll use the list you provided while reimplementing it. I guess around the end of the next week. Just last thing — where should I put the code touching abstract classes? |
Are covered by the latest changes :). The rest will be covered later this week. By the way, I'm bumping the previous questions 😅
I don't see any existing rule matching the new rules about property hooks, so it seems natural to create |
property.inInterface error when PHP version is 8.4 or alterproperty.inInterface error when PHP version is 8.4 or later
Right now you're in a rule about ClassPropertyNode. You can get |
|
But yeah, these items:
Could be added to a separate rule, like |
|
Despite my approach with setting the Do you have any idea how to "omit" it or what I can do with it? P.S. The code itself is finished, so you can take a look if it looks good in general. |
The solution is to skip the test based on |
But the test is also failing on |
|
From what I see in the
P.S. I let myself resolve your comments; however, if your flow assumes you are resolving them after checking if they are fixed, let me know :). |
|
I'll take it from here, thanks! |
|
Feel free to check out the commits I added. There was one bug in logic (7eaed3a), the rest is basically my preferences how to organize code. |
|
Thank you. |
|
Thanks for the cooperation 🙌🏼 |
After reading Ondrej's tweet and playing with PHPStan
2.0on PHP8.4, I've found out it reports theproperty.inInterfaceerror and it is non-ignorable. My first thought was to allow ignoring this error, but I've ended up not reporting this issue at all once the PHP version is8.4or later.