Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit f47c1ce

Browse files
author
Iwan
committed
Improve printing of non-callback arguments in Pexp_apply with callbacks
Fix #212 Sometimes one of the non-callback arguments will break in a function application where the first or last argument is a callback. There might be a single line comment in there, or a multiline string. We want to break all the arguments in this case for readability. **before** ```rescript showDialog( ` Do you really want to leave this workspace? Some more text with detailed explanations... `, danger=true, ~confirmText="Yes, I am sure!", ~onConfirm={() => ()}, ) ``` **after** ```rescript showDialog( ` Do you really want to leave this workspace? Some more text with detailed explanations... `, ~danger=true, ~confirmText="Yes, I am sure!", ~onConfirm={() => ()}, ) ```
1 parent 110d9c6 commit f47c1ce

File tree

4 files changed

+211
-23
lines changed

4 files changed

+211
-23
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## Unreleased
22

3+
* Improve printing of non-callback arguments in call expressions with callback in [#241](https://github.com/rescript-lang/syntax/pull/241/files)
34
* Fix printing of constrained expressions in rhs of js objects [#240](https://github.com/rescript-lang/syntax/pull/240)
45
* Improve printing of trailing comments under lhs of "pipe" expression in [#329](https://github.com/rescript-lang/syntax/pull/239/files)
56
* Improve printing of jsx children and props with leading line comment in [#236](https://github.com/rescript-lang/syntax/pull/236)

src/res_printer.ml

+66-23
Original file line numberDiff line numberDiff line change
@@ -3991,6 +3991,7 @@ and printArgumentsWithCallbackInFirstPosition ~uncurried args cmtTbl =
39913991
lblDoc;
39923992
printPexpFun ~inCallback:FitsOnOneLine expr cmtTbl
39933993
] in
3994+
let callback = printComments callback cmtTbl expr.pexp_loc in
39943995
let printedArgs =
39953996
Doc.join ~sep:(Doc.concat [Doc.comma; Doc.line]) (
39963997
List.map (fun arg -> printArgument arg cmtTbl) args
@@ -3999,6 +4000,7 @@ and printArgumentsWithCallbackInFirstPosition ~uncurried args cmtTbl =
39994000
(callback, printedArgs)
40004001
| _ -> assert false
40014002
in
4003+
40024004
(* Thing.map((arg1, arg2) => MyModuleBlah.toList(argument), foo) *)
40034005
(* Thing.map((arg1, arg2) => {
40044006
* MyModuleBlah.toList(argument)
@@ -4021,10 +4023,29 @@ and printArgumentsWithCallbackInFirstPosition ~uncurried args cmtTbl =
40214023
* )
40224024
*)
40234025
let breakAllArgs = printArguments ~uncurried args cmtTblCopy in
4024-
Doc.customLayout [
4025-
fitsOnOneLine;
4026-
breakAllArgs;
4027-
]
4026+
4027+
(* Sometimes one of the non-callback arguments will break.
4028+
* There might be a single line comment in there, or a multiline string etc.
4029+
* showDialog(
4030+
* ~onConfirm={() => ()},
4031+
* `
4032+
* Do you really want to leave this workspace?
4033+
* Some more text with detailed explanations...
4034+
* `,
4035+
* ~danger=true,
4036+
* // comment --> here a single line comment
4037+
* ~confirmText="Yes, I am sure!",
4038+
* )
4039+
* In this case, we always want the arguments broken over multiple lines,
4040+
* like a normal function call.
4041+
*)
4042+
if Doc.willBreak printedArgs then
4043+
breakAllArgs
4044+
else
4045+
Doc.customLayout [
4046+
fitsOnOneLine;
4047+
breakAllArgs;
4048+
]
40284049

40294050
and printArgumentsWithCallbackInLastPosition ~uncurried args cmtTbl =
40304051
(* Because the same subtree gets printed twice, we need to copy the cmtTbl.
@@ -4047,13 +4068,19 @@ and printArgumentsWithCallbackInLastPosition ~uncurried args cmtTbl =
40474068
]
40484069
in
40494070
let callbackFitsOnOneLine =
4050-
printPexpFun ~inCallback:FitsOnOneLine expr cmtTbl in
4051-
let callbackArgumetnsFitsOnOneLine =
4052-
printPexpFun ~inCallback:ArgumentsFitOnOneLine expr cmtTblCopy in
4071+
let pexpFunDoc = printPexpFun ~inCallback:FitsOnOneLine expr cmtTbl in
4072+
let doc = Doc.concat [lblDoc; pexpFunDoc] in
4073+
printComments doc cmtTbl expr.pexp_loc
4074+
in
4075+
let callbackArgumentsFitsOnOneLine =
4076+
let pexpFunDoc = printPexpFun ~inCallback:ArgumentsFitOnOneLine expr cmtTblCopy in
4077+
let doc = Doc.concat [lblDoc; pexpFunDoc] in
4078+
printComments doc cmtTblCopy expr.pexp_loc
4079+
in
40534080
(
40544081
Doc.concat (List.rev acc),
4055-
Doc.concat [lblDoc; callbackFitsOnOneLine],
4056-
Doc.concat [lblDoc; callbackArgumetnsFitsOnOneLine]
4082+
callbackFitsOnOneLine,
4083+
callbackArgumentsFitsOnOneLine
40574084
)
40584085
| arg::args ->
40594086
let argDoc = printArgument arg cmtTbl in
@@ -4090,11 +4117,30 @@ and printArgumentsWithCallbackInLastPosition ~uncurried args cmtTbl =
40904117
* )
40914118
*)
40924119
let breakAllArgs = printArguments ~uncurried args cmtTblCopy2 in
4093-
Doc.customLayout [
4094-
fitsOnOneLine;
4095-
arugmentsFitOnOneLine;
4096-
breakAllArgs;
4097-
]
4120+
4121+
(* Sometimes one of the non-callback arguments will break.
4122+
* There might be a single line comment in there, or a multiline string etc.
4123+
* showDialog(
4124+
* `
4125+
* Do you really want to leave this workspace?
4126+
* Some more text with detailed explanations...
4127+
* `,
4128+
* ~danger=true,
4129+
* // comment --> here a single line comment
4130+
* ~confirmText="Yes, I am sure!",
4131+
* ~onConfirm={() => ()},
4132+
* )
4133+
* In this case, we always want the arguments broken over multiple lines,
4134+
* like a normal function call.
4135+
*)
4136+
if Doc.willBreak printedArgs then
4137+
breakAllArgs
4138+
else
4139+
Doc.customLayout [
4140+
fitsOnOneLine;
4141+
arugmentsFitOnOneLine;
4142+
breakAllArgs;
4143+
]
40984144

40994145
and printArguments ~uncurried (args : (Asttypes.arg_label * Parsetree.expression) list) cmtTbl =
41004146
match args with
@@ -4357,23 +4403,20 @@ and printExprFunParameters ~inCallback ~uncurried ~hasConstraint parameters cmtT
43574403
let printedParamaters = Doc.concat [
43584404
if shouldHug || inCallback then Doc.nil else Doc.softLine;
43594405
Doc.join
4360-
~sep:(
4361-
Doc.concat [
4362-
Doc.comma; if inCallback then Doc.line else Doc.line
4363-
]
4364-
)
4406+
~sep:(Doc.concat [Doc.comma; Doc.line])
43654407
(List.map (fun p -> printExpFunParameter p cmtTbl) parameters)
43664408
] in
43674409
Doc.group (
43684410
Doc.concat [
43694411
lparen;
43704412
if shouldHug || inCallback then
43714413
printedParamaters
4372-
else Doc.indent printedParamaters;
4373-
if shouldHug || inCallback then
4374-
Doc.nil
43754414
else
4376-
Doc.concat [Doc.trailingComma; Doc.softLine];
4415+
Doc.concat [
4416+
Doc.indent printedParamaters;
4417+
Doc.trailingComma;
4418+
Doc.softLine;
4419+
];
43774420
Doc.rparen;
43784421
]
43794422
)

tests/printer/expr/__snapshots__/render.spec.js.snap

+75
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,81 @@ let /* a */ decoratorTags /* b */ = items->Js.Array2.filter(items => {
15801580
items.category === ChristmasLighting ||
15811581
items.category === Unknown
15821582
})
1583+
1584+
// callback in last position
1585+
showDialog(
1586+
\`
1587+
Do you really want to leave this workspace?
1588+
Some more text with detailed explanations...
1589+
\`,
1590+
~danger=true,
1591+
~confirmText=\\"Yes, I am sure!\\",
1592+
~onConfirm={() => ()},
1593+
)
1594+
1595+
// callback in first position
1596+
showDialog(
1597+
~onConfirm={() => ()},
1598+
~danger=true,
1599+
~confirmText=\\"Yes, I am sure!\\",
1600+
\`
1601+
Do you really want to leave this workspace?
1602+
Some more text with detailed explanations...
1603+
\`,
1604+
)
1605+
1606+
// callback in last position, with comment in between args
1607+
showDialog(
1608+
dialogMessage,
1609+
// comment
1610+
~danger=true,
1611+
~confirmText=\\"Yes, I am sure!\\",
1612+
~onConfirm=() => (),
1613+
)
1614+
1615+
// callback in last position, with comment in between args
1616+
showDialog(
1617+
dialogMessage,
1618+
~danger=true,
1619+
/* comment below */
1620+
~confirmText=\\"Yes, I am sure!\\",
1621+
~onConfirm=() => (),
1622+
)
1623+
1624+
// callback in first position, with single line comment in between args
1625+
showDialog(
1626+
~onConfirm=() => (),
1627+
dialogMessage,
1628+
// comment
1629+
~danger=true,
1630+
~confirmText=\\"Yes, I am sure!\\",
1631+
)
1632+
1633+
// callback in first position, with comment in between args
1634+
showDialog(
1635+
~onConfirm=() => (),
1636+
dialogMessage,
1637+
~danger=true,
1638+
/* comment below */
1639+
~confirmText=\\"Yes, I am sure!\\",
1640+
)
1641+
1642+
React.useEffect5(
1643+
(
1644+
context.activate,
1645+
context.chainId,
1646+
dispatch,
1647+
setTriedLoginAlready,
1648+
triedLoginAlready,
1649+
),
1650+
() => {
1651+
doThings()
1652+
None
1653+
}, // intentionally only running on mount (make sure it's only mounted once :))
1654+
)
1655+
1656+
apply(a, b, c, /* before */ () => () /* after */)
1657+
apply(/* before */ () => () /* after */, a, b, c)
15831658
"
15841659
`;
15851660

tests/printer/expr/callback.js

+69
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,72 @@ let /* a */ decoratorTags /* b */ = items->Js.Array2.filter(items => {
319319
|| items.category === ChristmasLighting
320320
|| items.category === Unknown
321321
})
322+
323+
// callback in last position
324+
showDialog(
325+
`
326+
Do you really want to leave this workspace?
327+
Some more text with detailed explanations...
328+
`,
329+
~danger=true,
330+
~confirmText="Yes, I am sure!",
331+
~onConfirm={() => ()},
332+
)
333+
334+
// callback in first position
335+
showDialog(
336+
~onConfirm={() => ()},
337+
~danger=true,
338+
~confirmText="Yes, I am sure!",
339+
`
340+
Do you really want to leave this workspace?
341+
Some more text with detailed explanations...
342+
`,
343+
)
344+
345+
// callback in last position, with comment in between args
346+
showDialog(dialogMessage,
347+
// comment
348+
~danger=true, ~confirmText="Yes, I am sure!", ~onConfirm=() => ())
349+
350+
// callback in last position, with comment in between args
351+
showDialog(
352+
dialogMessage,
353+
~danger=true,
354+
/* comment below */
355+
~confirmText="Yes, I am sure!",
356+
~onConfirm=() => ())
357+
358+
// callback in first position, with single line comment in between args
359+
showDialog(
360+
~onConfirm=() => (),
361+
dialogMessage,
362+
// comment
363+
~danger=true,
364+
~confirmText="Yes, I am sure!"
365+
)
366+
367+
// callback in first position, with comment in between args
368+
showDialog(
369+
~onConfirm=() => (),
370+
dialogMessage,
371+
~danger=true,
372+
/* comment below */
373+
~confirmText="Yes, I am sure!",
374+
)
375+
376+
React.useEffect5((
377+
context.activate,
378+
context.chainId,
379+
dispatch,
380+
setTriedLoginAlready,
381+
triedLoginAlready,
382+
),
383+
() => {
384+
doThings()
385+
None
386+
}, // intentionally only running on mount (make sure it's only mounted once :))
387+
)
388+
389+
apply(a, b, c, /* before */ () => () /* after */)
390+
apply(/* before */ () => () /* after */, a, b, c)

0 commit comments

Comments
 (0)