Skip to content

Commit 410e292

Browse files
authored
Make chain breaking as similar to original prettier (js) as much as possible (#2320)
* Removed chain break with more than 3 expressions * Added maxChainCallExpressionCountPHP option to control max calls in a chain * Added option to readme Updated description in options file * Added advance check for chain breaks * Reduced chain items count to 2 for complexity test Fixed array handling in complexity test * Func. name change * Removed comment * Style fix --------- Co-authored-by: Kristijan Novaković <[email protected]>
1 parent c8aadcf commit 410e292

File tree

9 files changed

+151
-146
lines changed

9 files changed

+151
-146
lines changed

src/printer.mjs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
getAncestorNode,
3737
isReferenceLikeNode,
3838
normalizeMagicMethodName,
39+
isSimpleCallArgument,
3940
} from "./util.mjs";
4041

4142
const {
@@ -508,9 +509,9 @@ function printMemberChain(path, options, print) {
508509
printIndentedGroup(groups.slice(shouldMerge ? 2 : 1)),
509510
];
510511

511-
const callExpressionCount = printedNodes.filter(
512-
(tuple) => tuple.node.kind === "call"
513-
).length;
512+
const callExpressions = printedNodes.filter((tuple) =>
513+
["call", "new"].includes(tuple.node.kind)
514+
);
514515

515516
// We don't want to print in one line if there's:
516517
// * A comment.
@@ -519,7 +520,10 @@ function printMemberChain(path, options, print) {
519520
// If the last group is a function it's okay to inline if it fits.
520521
if (
521522
hasComment ||
522-
callExpressionCount >= 3 ||
523+
(callExpressions.length > 2 &&
524+
callExpressions.some(
525+
(exp) => !exp.node.arguments.every((arg) => isSimpleCallArgument(arg))
526+
)) ||
523527
printedGroups.slice(0, -1).some(willBreak)
524528
) {
525529
return group(expanded);

src/util.mjs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,79 @@ function normalizeMagicMethodName(name) {
612612
return name;
613613
}
614614

615+
/**
616+
* @param {string[]} kindsArray
617+
* @returns {(node: Node | Comment) => Boolean}
618+
*/
619+
function createTypeCheckFunction(kindsArray) {
620+
const kinds = new Set(kindsArray);
621+
return (node) => kinds.has(node?.kind);
622+
}
623+
624+
const isSingleWordType = createTypeCheckFunction([
625+
"variable",
626+
"parameter",
627+
"variadic",
628+
"clone",
629+
"cast",
630+
"boolean",
631+
"number",
632+
"string",
633+
"literal",
634+
"nullkeyword",
635+
"namedargument",
636+
"variadicplaceholder",
637+
]);
638+
639+
const isArrayExpression = createTypeCheckFunction(["array"]);
640+
const isCallOrNewExpression = createTypeCheckFunction(["call", "new"]);
641+
const isArrowFuncExpression = createTypeCheckFunction(["arrowfunc"]);
642+
643+
function getChainParts(node, prev = []) {
644+
const parts = prev;
645+
if (isCallOrNewExpression(node)) {
646+
parts.push(node);
647+
}
648+
649+
if (!node.what) {
650+
return parts;
651+
}
652+
653+
return getChainParts(node.what, parts);
654+
}
655+
656+
function isSimpleCallArgument(node, depth = 2) {
657+
if (depth <= 0) {
658+
return false;
659+
}
660+
661+
const isChildSimple = (child) => isSimpleCallArgument(child, depth - 1);
662+
663+
if (isSingleWordType(node)) {
664+
return true;
665+
}
666+
667+
if (isArrayExpression(node)) {
668+
return node.items.every((x) => x === null || isChildSimple(x));
669+
}
670+
671+
if (isCallOrNewExpression(node)) {
672+
const parts = getChainParts(node);
673+
return (
674+
parts.filter((node) => node.kind === "call").length <= depth &&
675+
parts.every((node) => node.arguments.every(isChildSimple))
676+
);
677+
}
678+
679+
if (isArrowFuncExpression(node)) {
680+
return (
681+
node.arguments.length <= depth && node.arguments.every(isChildSimple)
682+
);
683+
}
684+
685+
return false;
686+
}
687+
615688
export {
616689
printNumber,
617690
getPrecedence,
@@ -641,4 +714,5 @@ export {
641714
isDocNode,
642715
getAncestorNode,
643716
normalizeMagicMethodName,
717+
isSimpleCallArgument,
644718
};

tests/call/__snapshots__/jsfmt.spec.mjs.snap

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -705,18 +705,8 @@ $var = $this->foo()();
705705
$var = ($this->foo->bar)();
706706
$var = $this->foo->bar()();
707707
$var = ($this->foo->bar->baz->foo->bar->baz)();
708-
$var = $this->foo()
709-
->bar()
710-
->baz()
711-
->foo()
712-
->bar()
713-
->baz()();
714-
$var = ($this->foo()
715-
->bar()
716-
->baz()
717-
->foo()
718-
->bar()
719-
->baz)();
708+
$var = $this->foo()->bar()->baz()->foo()->bar()->baz()();
709+
$var = ($this->foo()->bar()->baz()->foo()->bar()->baz)();
720710
$var = $this["foo"]();
721711
$var = $this["foo"]["bar"]();
722712
$var = ($this::$foo)();
@@ -733,10 +723,7 @@ $var = ((["Foo", "bar"])->bar)();
733723
$var = ($var->foo)()();
734724
$var = ($var->foo)()();
735725
$var = (($var->foo)()->bar)();
736-
$var = ((($var
737-
->foo)()
738-
->bar)()
739-
->baz)();
726+
$var = ((($var->foo)()->bar)()->baz)();
740727
741728
$obj = call('return new class($value)
742729
{

tests/member_chain/__snapshots__/jsfmt.spec.mjs.snap

Lines changed: 50 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,47 @@ printWidth: 80
110110
111111
$object->foo()->bar()->baz();
112112
113+
$object->foo()->bar()->baz()->foo()->bar()->baz();
114+
115+
$object->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz();
116+
117+
$object->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz();
118+
113119
foo()->bar()->baz();
114120
115121
foo()->bar->baz();
116122
117123
=====================================output=====================================
118124
<?php
119125
126+
$object->foo()->bar()->baz();
127+
128+
$object->foo()->bar()->baz()->foo()->bar()->baz();
129+
130+
$object->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz();
131+
120132
$object
121133
->foo()
122134
->bar()
123-
->baz();
124-
125-
foo()
135+
->baz()
136+
->foo()
137+
->bar()
138+
->baz()
139+
->foo()
140+
->bar()
141+
->baz()
142+
->foo()
143+
->bar()
144+
->baz()
145+
->foo()
146+
->bar()
147+
->baz()
148+
->foo()
126149
->bar()
127150
->baz();
128151
152+
foo()->bar()->baz();
153+
129154
foo()->bar->baz();
130155
131156
================================================================================
@@ -191,10 +216,7 @@ $object[$valid
191216
192217
($a ? $b : $c)->d()->e();
193218
194-
($a ? $b : $c)
195-
->d()
196-
->e()
197-
->f();
219+
($a ? $b : $c)->d()->e()->f();
198220
199221
($valid
200222
? $helper->responseBody($this->currentUser)
@@ -436,12 +458,8 @@ $var = Foo::keys($items)->filter(function ($x) { return $x > 2; })->map(function
436458
<?php
437459
438460
one()->two();
439-
one()
440-
->two()
441-
->three();
442-
one()
443-
->two->three()
444-
->four->five();
461+
one()->two()->three();
462+
one()->two->three()->four->five();
445463
446464
Route::prefix("api")
447465
->middleware("api")
@@ -476,9 +494,7 @@ $a->a()->b();
476494
$a->a()->b();
477495
$a->a()->b;
478496
$a->b->a();
479-
$a->b()
480-
->c()
481-
->d();
497+
$a->b()->c()->d();
482498
$a->b->c->d;
483499
484500
// should inline
@@ -545,67 +561,19 @@ $foo->bar(
545561
"veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong"
546562
)()()()()();
547563
548-
$brian->hotel
549-
->orders()
550-
->ordered()
551-
->with("smith")
552-
->get();
553-
$brian::$hotel
554-
->orders()
555-
->ordered()
556-
->with("smith")
557-
->get();
558-
$brian["hotel"]
559-
->orders()
560-
->ordered()
561-
->with("smith")
562-
->get();
563-
Foo::$hotel
564-
->orders()
565-
->ordered()
566-
->with("smith")
567-
->get();
568-
(new Foo())->hotel
569-
->orders()
570-
->ordered()
571-
->with("smith")
572-
->get();
573-
(clone $a)->hotel
574-
->orders()
575-
->ordered()
576-
->with("smith")
577-
->get();
578-
579-
$var = $brian->hotel
580-
->orders()
581-
->ordered()
582-
->with("smith")
583-
->get();
584-
$var = $brian::$hotel
585-
->orders()
586-
->ordered()
587-
->with("smith")
588-
->get();
589-
$var = $brian["hotel"]
590-
->orders()
591-
->ordered()
592-
->with("smith")
593-
->get();
594-
$var = Foo::$hotel
595-
->orders()
596-
->ordered()
597-
->with("smith")
598-
->get();
599-
$var = (new Foo())->hotel
600-
->orders()
601-
->ordered()
602-
->with("smith")
603-
->get();
604-
$var = (clone $a)->hotel
605-
->orders()
606-
->ordered()
607-
->with("smith")
608-
->get();
564+
$brian->hotel->orders()->ordered()->with("smith")->get();
565+
$brian::$hotel->orders()->ordered()->with("smith")->get();
566+
$brian["hotel"]->orders()->ordered()->with("smith")->get();
567+
Foo::$hotel->orders()->ordered()->with("smith")->get();
568+
(new Foo())->hotel->orders()->ordered()->with("smith")->get();
569+
(clone $a)->hotel->orders()->ordered()->with("smith")->get();
570+
571+
$var = $brian->hotel->orders()->ordered()->with("smith")->get();
572+
$var = $brian::$hotel->orders()->ordered()->with("smith")->get();
573+
$var = $brian["hotel"]->orders()->ordered()->with("smith")->get();
574+
$var = Foo::$hotel->orders()->ordered()->with("smith")->get();
575+
$var = (new Foo())->hotel->orders()->ordered()->with("smith")->get();
576+
$var = (clone $a)->hotel->orders()->ordered()->with("smith")->get();
609577
610578
$var = Foo::keys($items)
611579
->filter(function ($x) {
@@ -615,9 +583,11 @@ $var = Foo::keys($items)
615583
return $x * 2;
616584
});
617585
618-
(new static(func_get_args()))->push($this)->each(function ($item) {
619-
VarDumper::dump($item);
620-
});
586+
(new static(func_get_args()))
587+
->push($this)
588+
->each(function ($item) {
589+
VarDumper::dump($item);
590+
});
621591
(new static(func_get_args()))
622592
->offset(10)
623593
->push($this)

tests/member_chain/break-multiple.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
$object->foo()->bar()->baz();
44

5+
$object->foo()->bar()->baz()->foo()->bar()->baz();
6+
7+
$object->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz();
8+
9+
$object->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz()->foo()->bar()->baz();
10+
511
foo()->bar()->baz();
612

713
foo()->bar->baz();

tests/parens/__snapshots__/jsfmt.spec.mjs.snap

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,10 +1568,7 @@ $var = (clone foo())->bar()->foo();
15681568
$var = (clone foo())->bar()->foo();
15691569
$var = (clone foo())->bar()->foo()[0];
15701570
$var = (clone foo())->bar()->foo()[0][1];
1571-
$var = (clone foo())
1572-
->bar()
1573-
->foo()
1574-
->baz();
1571+
$var = (clone foo())->bar()->foo()->baz();
15751572
$var = (clone $foo())->bar;
15761573
$var = (clone $bar->y)->x;
15771574
$var = (clone $foo)[0];
@@ -2562,10 +2559,7 @@ $var = (new foo())->bar()->foo();
25622559
$var = (new foo())->bar()->foo();
25632560
$var = (new foo())->bar()->foo()[0];
25642561
$var = (new foo())->bar()->foo()[0][1];
2565-
$var = (new foo())
2566-
->bar()
2567-
->foo()
2568-
->baz();
2562+
$var = (new foo())->bar()->foo()->baz();
25692563
$var = (new $foo())->bar;
25702564
$var = (new $bar->y())->x;
25712565
$var = (new foo())[0];
@@ -2935,10 +2929,7 @@ $var = ((int) $var) + 1 === 2 ? "1" : "2";
29352929
($var ? $var : $var)[1];
29362930
($var ? $var : $var)->d();
29372931
($var ? $var : $var)->d()->e();
2938-
($var ? $var : $var)
2939-
->d()
2940-
->e()
2941-
->f();
2932+
($var ? $var : $var)->d()->e()->f();
29422933
($var
29432934
? $var->responseBody($var->currentUser)
29442935
: $var->responseBody($var->defaultUser)

tests/print/__snapshots__/jsfmt.spec.mjs.snap

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,7 @@ print $var->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongProperty
299299
->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongProperty
300300
->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongProperty;
301301
302-
print $var
303-
->call()
304-
->call()
305-
->call();
302+
print $var->call()->call()->call();
306303
print $var
307304
->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongCall()
308305
->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongCall()

0 commit comments

Comments
 (0)