-
-
Notifications
You must be signed in to change notification settings - Fork 133
feat: format new without parenthesis in PHP 8.4 #2422
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
Marking as draft for now because I want to do some additional testing, and it looks like there are CI failures. |
508435a
to
1a96268
Compare
Looks really good! 💯 I'm hopeful that we can land glayzzle/php-parser#1152 in the coming days - let's merge this afterwards, without the regression 🙂 |
a97efcf
to
d06af24
Compare
@czosel I have rebased this to fix the package.json/yarn.lock conflict, tests run fine locally, but CI fails, and I cant reproduce that locally. Might need to recreate the PR? |
d06af24
to
8741ddb
Compare
Thank you for nudging me on this (I had been away). I've updated the PR to use |
I can reproduce the CI failure locally when running I'm seeing 2 failures:
Here's an example of # 1: Object {
"expression": Object {
"kind": "assign",
"left": Object {
"curly": false,
"kind": "variable",
"name": "class",
},
"operator": "=",
"right": Object {
+ "kind": "bin",
+ "left": Object {
"arguments": Array [],
- "kind": "call",
+ "kind": "new",
"what": Object {
- "kind": "propertylookup",
- "offset": Object {
- "kind": "identifier",
- "name": "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongMethod",
+ "kind": "name",
+ "name": "Foo",
+ "resolution": "uqn",
+ },
},
- "what": Object {
+ "right": Object {
"arguments": Array [],
- "kind": "new",
+ "kind": "call",
"what": Object {
"kind": "name",
- "name": "Foo",
+ "name": "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongMethod",
"resolution": "uqn",
},
},
- },
+ "type": "->",
},
}, I don't understand all of the details in that, but it looks like As for # 2, an example error is
In this case, the input snippet I'll keep tinkering with this; but if someone can confirm that I'm on the right track (or not!) that would be really helpful. Thank you! |
8741ddb
to
1aed80c
Compare
@claytonrcarter thanks for looking into this! Concerning the differences in AST, you'll have to "clean those up": see Line 26 in 14f802a
I'll take a look at the parser error and get back to you. |
I could reproduce the issue in the php-parser repository by adapting a test case. I created an issue for this: glayzzle/php-parser#1160 |
OK, it sounds like we may have to wait for glayzzle/php-parser#1160. In the meantime, I'm looking at cleaning up the AST and I have some questions:
Again, just want to confirm that I'm on the right track. Thanks. Update here's an example of what I'm talking about: Expand to show exampleThe code snippet$class = (new Foo)->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongMethod(); is reformatted in 8.4 to
But these are parsed differently by the parser. The RHS of the assign in the former is {
arguments: [],
kind: "call",
what: {
kind: "propertylookup",
offset: {
kind: "identifier",
name: "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongMethod",
},
what: {
arguments: [],
kind: "new",
what: {
kind: "name",
name: "Foo",
resolution: "uqn",
},
},
},
} while for the latter it's more like this (approx) {
kind: "bin",
type: "->",
left: {
arguments: [],
kind: "new",
what: {
kind: "name",
name: "Foo",
resolution: "uqn",
},
right: {
arguments: [],
kind: "call",
what: {
kind: "name",
name: "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongMethod",
resolution: "uqn",
},
},
} So they are parsed as substantially different nodes, and – to get them to match – I'm currently just returning a hard-coded JS object of the former. This works, but it feels wrong. Am I misunderstanding something about this approach? Note that there seem to be only 4 cases that fail like this, so it's not many, but they will all need this sort of fussy hard-coded replacement. Again, unless I'm misunderstanding how I should be doing this. |
Generally, I think you're on the right track. The fact that When parsing
|
@claytonrcarter After spending a few more minutes thinking about this, I'm relatively convinced that the AST representation of
should actually be the same, namely a Which would make the AST cleanup obsolete 👍 |
@claytonrcarter Thank you so much for working on this! I just ran your branch on my codebase and observed the following: new A()
->b()
->c()
->d(); becomes new A()->b()
->c()
->d(); I'm not sure if this is covered by what you're already working to solve above, or warrants a new test. It also really likes to move assignments to the next line like this: $asdf =
new A()->b()
->c(); This causes yet another level of indentation which I don't think is wanted. Those are the only issues I had in our fairly large codebase, though (~1700 files). Really looking forward to seeing this merged! |
needsParens() is already being called with 2 params, but the fn signature didn't reflect that
a871cad
to
2036567
Compare
This now includes the fix in glayzzle/php-parser#1162, and ... CI is passing! No AST massaging needed! Thank you all for your help and guidance; truly a team effort! @hackel Ryan, I added a some code to the snapshots based on your examples and they seem to formatting as you would expect. Can you can try this out again on your code base and see if it's any better? |
Well ... almost passing. Codecov seems to be flagging me on changes to |
I dont think codecov knows what is going on there. Here is the same thing happening on changing the default parser version: |
I've stopped caring about what codecov is reporting ... 🙈 |
e43159c
to
8d42d88
Compare
Apart from the last minor question, this is ready to be merged from my point of view 💯 |
8d42d88
to
3cbf52d
Compare
@claytonrcarter I ran the new code and it all looks great on my end. Great job! |
This took some iterating, but was well worth it 👍 thanks @claytonrcarter and @cseufert 💯 |
Released in |
This adds support for formatting things like
(new Foo())->bar
asnew Foo()->bar
. Support for this syntax was added in PHP 8.4 and very recently merged and released in php-parser.Note that php-parser 3.2.2 introduced a parser bug that affects how we format specifically placed comments in class constant assignments. My opinion is that this is an extreme edge case issue and it's worth the temporary regression in order to gain support for one of the highlighted features of php 8.4. (There is already a pending PR to fix this in php-parser, and we can rollout an update to fix it here when that lands.edit: this has been fixedbreaking: removes (temporarily) support for some comments in class constant assigmentsphpVersion
option for8.4
Verification
Try it out
This should be reformatted to
And
php foo.php
should print123
in both cases (though the latter will fail in php <= 8.3).