Skip to content

Commit 843e2fc

Browse files
Smart linebreak printer for pipe chains (#6411)
* Smart linebreak printer for pipe chains * Fix build * Nit: isMultiLine -> isMultiline * Changelog
1 parent 6f972d7 commit 843e2fc

File tree

6 files changed

+105
-19
lines changed

6 files changed

+105
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- A little performance improvement for JSX V4 runtime helper by removing one object allocation for components with key prop. https://github.com/rescript-lang/rescript-compiler/pull/6376
2929
- The error message for "toplevel expressions should evaluate to unit" has been revamped and improved. https://github.com/rescript-lang/rescript-compiler/pull/6407
3030
- Improve "Somewhere wanted" error messages by changing wording and adding more context + suggested solutions to the error messages where appropriate. https://github.com/rescript-lang/rescript-compiler/pull/6410
31+
- Add smart printer for pipe-chains. https://github.com/rescript-lang/rescript-compiler/pull/6411
3132

3233
# 11.0.0-rc.3
3334

jscomp/gentype/TranslateStructure.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ let rec addAnnotationsToTypes_ ~config ~(expr : Typedtree.expression)
1111
let aName =
1212
if aName = "*opt*" then
1313
match arg_label with
14-
| Optional l ->
15-
l
14+
| Optional l -> l
1615
| _ -> "" (* should not happen *)
1716
else aName
1817
in
@@ -56,6 +55,7 @@ and addAnnotationsToFields ~config (expr : Typedtree.expression)
5655
in
5756
({field with nameJS = name} :: nextFields1, types1)
5857
| _ -> (fields, argTypes)
58+
[@@live]
5959

6060
(** Recover from expr the renaming annotations on named arguments. *)
6161
let addAnnotationsToFunctionType ~config (expr : Typedtree.expression)

jscomp/syntax/src/res_printer.ml

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3527,8 +3527,8 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl =
35273527
Doc.concat
35283528
[spacingBeforeOperator; Doc.text operatorTxt; spacingAfterOperator]
35293529
in
3530-
let printOperand ~isLhs expr parentOperator =
3531-
let rec flatten ~isLhs expr parentOperator =
3530+
let printOperand ~isLhs ~isMultiline expr parentOperator =
3531+
let rec flatten ~isLhs ~isMultiline expr parentOperator =
35323532
if ParsetreeViewer.isBinaryExpression expr then
35333533
match expr with
35343534
| {
@@ -3541,7 +3541,7 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl =
35413541
ParsetreeViewer.flattenableOperators parentOperator operator
35423542
&& not (ParsetreeViewer.hasAttributes expr.pexp_attributes)
35433543
then
3544-
let leftPrinted = flatten ~isLhs:true left operator in
3544+
let leftPrinted = flatten ~isLhs:true ~isMultiline left operator in
35453545
let rightPrinted =
35463546
let rightPrinteableAttrs, rightInternalAttrs =
35473547
ParsetreeViewer.partitionPrintableAttributes
@@ -3585,12 +3585,26 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl =
35853585
Doc.rparen;
35863586
]
35873587
else
3588-
Doc.concat
3589-
[
3590-
leftPrinted;
3591-
printBinaryOperator ~inlineRhs:false operator;
3592-
rightPrinted;
3593-
]
3588+
match operator with
3589+
| ("|." | "|.u") when isMultiline ->
3590+
(* If the pipe-chain is written over multiple lines, break automatically
3591+
* `let x = a->b->c -> same line, break when line-width exceeded
3592+
* `let x = a->
3593+
* b->c` -> pipe-chain is written on multiple lines, break the group *)
3594+
Doc.breakableGroup ~forceBreak:true
3595+
(Doc.concat
3596+
[
3597+
leftPrinted;
3598+
printBinaryOperator ~inlineRhs:false operator;
3599+
rightPrinted;
3600+
])
3601+
| _ ->
3602+
Doc.concat
3603+
[
3604+
leftPrinted;
3605+
printBinaryOperator ~inlineRhs:false operator;
3606+
rightPrinted;
3607+
]
35943608
in
35953609

35963610
let doc =
@@ -3665,7 +3679,7 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl =
36653679
| Braced braces -> printBraces doc expr braces
36663680
| Nothing -> doc)
36673681
in
3668-
flatten ~isLhs expr parentOperator
3682+
flatten ~isLhs ~isMultiline expr parentOperator
36693683
in
36703684
match expr.pexp_desc with
36713685
| Pexp_apply
@@ -3679,8 +3693,8 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl =
36793693
|| ParsetreeViewer.isBinaryExpression rhs
36803694
|| printAttributes ~state expr.pexp_attributes cmtTbl <> Doc.nil) ->
36813695
let lhsHasCommentBelow = hasCommentBelow cmtTbl lhs.pexp_loc in
3682-
let lhsDoc = printOperand ~isLhs:true lhs op in
3683-
let rhsDoc = printOperand ~isLhs:false rhs op in
3696+
let lhsDoc = printOperand ~isLhs:true ~isMultiline:false lhs op in
3697+
let rhsDoc = printOperand ~isLhs:false ~isMultiline:false rhs op in
36843698
Doc.group
36853699
(Doc.concat
36863700
[
@@ -3697,12 +3711,16 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl =
36973711
| Pexp_apply
36983712
( {pexp_desc = Pexp_ident {txt = Longident.Lident operator}},
36993713
[(Nolabel, lhs); (Nolabel, rhs)] ) ->
3714+
let isMultiline =
3715+
lhs.pexp_loc.loc_start.pos_lnum < rhs.pexp_loc.loc_start.pos_lnum
3716+
in
3717+
37003718
let right =
37013719
let operatorWithRhs =
37023720
let rhsDoc =
37033721
printOperand
37043722
~isLhs:(ParsetreeViewer.isRhsBinaryOperator operator)
3705-
rhs operator
3723+
~isMultiline rhs operator
37063724
in
37073725
Doc.concat
37083726
[
@@ -3722,7 +3740,7 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl =
37223740
[
37233741
printOperand
37243742
~isLhs:(not @@ ParsetreeViewer.isRhsBinaryOperator operator)
3725-
lhs operator;
3743+
~isMultiline lhs operator;
37263744
right;
37273745
])
37283746
in

jscomp/syntax/tests/printer/expr/expected/callback.res.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,16 @@ let f = () => {
215215
</div>
216216
}
217217

218-
myPromise->Js.Promise.then_(value => {
218+
myPromise
219+
->Js.Promise.then_(value => {
219220
Js.log(value)
220221
Js.Promise.resolve(value + 2)
221-
}, _)->Js.Promise.then_(value => {
222+
}, _)
223+
->Js.Promise.then_(value => {
222224
Js.log(value)
223225
Js.Promise.resolve(value + 3)
224-
}, _)->Js.Promise.catch(err => {
226+
}, _)
227+
->Js.Promise.catch(err => {
225228
Js.log2("Failure!!", err)
226229
Js.Promise.resolve(-2)
227230
}, _)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
let myFunc = (strA, strB) => strA ++ strB
2+
3+
"expr1"->myFunc("expr2")->myFunc("expr3")
4+
5+
"expr1"
6+
->myFunc("expr2")
7+
->myFunc("expr3")
8+
9+
"expr1"
10+
->myFunc("expr2")
11+
->myFunc("expr3")
12+
13+
"expr1"
14+
->myFunc("expr2")
15+
->myFunc("expr3")
16+
->myFunc("expr4")
17+
18+
myPromise->Promise.then(v => {
19+
Js.log(v)
20+
Promise.resolve(v)
21+
})
22+
23+
myPromise->Promise.then(v => {
24+
Js.log(v)
25+
Promise.resolve(v)
26+
})
27+
28+
let messages = React.useMemo(() =>
29+
messagesById
30+
->StringMap.valuesToArray
31+
->Array.filter(ChatMessage.isVisibleInSimpleFilter)
32+
->Array.toSorted(ChatMessage.compareByDateAsc)
33+
, [messagesById])
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
let myFunc = (strA, strB) => strA ++ strB
2+
3+
"expr1"->myFunc("expr2")->myFunc("expr3")
4+
5+
"expr1"
6+
->myFunc("expr2")->myFunc("expr3")
7+
8+
"expr1"->myFunc("expr2")
9+
->myFunc("expr3")
10+
11+
"expr1"->myFunc("expr2")
12+
->myFunc("expr3")->myFunc("expr4")
13+
14+
myPromise->Promise.then(v => {
15+
Js.log(v)
16+
Promise.resolve(v)
17+
})
18+
19+
myPromise
20+
->Promise.then(v => {
21+
Js.log(v)
22+
Promise.resolve(v)
23+
})
24+
25+
let messages = React.useMemo(() =>
26+
messagesById
27+
->StringMap.valuesToArray
28+
->Array.filter(ChatMessage.isVisibleInSimpleFilter)
29+
->Array.toSorted(ChatMessage.compareByDateAsc)
30+
, [messagesById])
31+

0 commit comments

Comments
 (0)