-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
feat: Introduce StaticPrivateMethodFixer
#4557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Restrictions:
|
Why? How could a code calling
This could only affects |
|
Wouldn't running after static lambda relax the first requirement? |
These two kinda have circular dependency, idk if php-cs-fixer can handle that atm. |
Heh, that's tricky, it should run before to relax methods containing non-static closures, but also after to fix non-static closures using private methods now declared static. |
You can solve the dependency by running these recursively, which would require changing the tool architecture. Your exit condition being "nothing got fixed", or "nesting level limit reached". |
I mean, it's the same effect as running it twice, I guess. It's a bit annoying if you have an unstable rule combo like this: you run CS and commit, your CI runs it again and fails because it changed something too. |
@keradus always pushed for avoiding such architectures for clear reasons. I think I'll propose the first production-ready version of the Fixer to completely ignore private method containing any closure |
@Ocramius you killed me 😢 this practically makes the Fixer impossible to be implemented without context awareness |
Interfaces can't declare private methods right? |
No, but the resulting new method can be present in the interface, and such creating a conflict |
I don't understand, could you provide an example |
I thought this https://3v4l.org/G6vS6 could be possible but turns out it can't, so either @Ocramius knows something we don't or he was wrong; and it would be really weird for him to be wrong 😛 |
Maybe annoying, but still a good amount of improvement 👍 |
@Slamdunk sorry, I missed the limitation to private methods in my thougt process 😛 |
TBH I really assumed you actually could put private methods in interfaces, because... you know, PHP. TIL you can't. |
*/ | ||
public function isCandidate(Tokens $tokens) | ||
{ | ||
return $tokens->isAllTokenKindsFound([T_CLASS, T_PRIVATE]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the fixer can also be applied inside of Traits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm, I think not
// file Foo.php
trait Foo
{
private function bar() {}
}
// file Baz.php
class Baz
{
use Foo;
public function wut()
{
return $this->bar();
}
}
I cannot fix Foo::bar because I would break Baz::wut behavior; well, not entirely break as php still run without issue, but a static analyzer would complain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry I just read #4557 (comment): yes we can fix Traits too pointing the possible side effects into the risky description.
But honestly the two scenarios are much differently spread imho:
- A class that uses a private method of a trait: ok, bad but common, we can't use this fixer for Trait as we would (logically) break the code
- A trait that uses a private method of a class: WUT? Are you kidding me? Yeah it's feasible, but if you write crappy code it's not our fault
I feel safe to fix classes and not fix traits, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a good idea.
I don't think it will be a common problem, but it is one of those nasty edge cases.
One more possible edge case that (may) not be relevant yet. How about $this etc in php 7.4 arrow functions |
I was planning to pinpoint it in an issue like #4382 as I haven't a clear idea on the topic as of yet, nor on the way this library intend to support the new code structure |
435d2a8
to
beb77cc
Compare
@SpacePossum may we tag this for 2.17? |
8c2f8b0
to
8681bac
Compare
30b441c
to
64fc4e8
Compare
References:
$this
referencesMust not contain non-static closuressee feat: IntroduceStaticPrivateMethodFixer
#4557 (comment) updated to: Must not contain closuresdebug_backtrace()
calls$this->{$method}()
or$$var
inside the methodProtectedToPrivateFixer
StaticLambdaFixer