Skip to content

Commit 56fe3bc

Browse files
authored
Fix function assignment formatting and unify formatter paths (#8611)
* Fix formatting of function assignments to refs Signed-off-by: Christoph Knittel <ck@cca.io> * Unify assignment formatting across refs and fields Signed-off-by: Christoph Knittel <ck@cca.io> * Unify standalone and callback function printing Signed-off-by: Christoph Knittel <ck@cca.io> * Remove obsolete formatter helpers and parameters Signed-off-by: Christoph Knittel <ck@cca.io> * Add changelog entry for formatter improvements Signed-off-by: Christoph Knittel <ck@cca.io> * Match surrounding changelog spacing Signed-off-by: Christoph Knittel <ck@cca.io> * Reformat existing sources with updated formatter Signed-off-by: Christoph Knittel <ck@cca.io> * Refresh test source locations after formatting Signed-off-by: Christoph Knittel <ck@cca.io> --------- Signed-off-by: Christoph Knittel <ck@cca.io>
1 parent 5c24235 commit 56fe3bc

21 files changed

Lines changed: 540 additions & 218 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#### :bug: Bug fix
3737

38+
- Fix excessive parentheses and indentation in function assignments to refs, align record and array assignment formatting across refs and fields, and preserve function return-type parentheses and consistent JSX fragment layout in callbacks. https://github.com/rescript-lang/rescript/pull/8611
3839
- Fix a recursive module with an empty signature discarding its right-hand side. Lambda-to-Lam conversion rewrote `Pupdate_mod` to unit when the module's shape had no fields, dropping the primitive's arguments - one of which is the right-hand side - so `module rec M: {} = { let () = Console.log("effect") }` emitted nothing for `M`. The elision now happens where the bindings are produced, with the right-hand side still in hand. https://github.com/rescript-lang/rescript/pull/8608
3940
- Fix `Int.Ref.increment` and `Int.Ref.decrement` evaluating their argument twice: `Int.Ref.increment(mkRef())` emitted `mkRef().contents = mkRef().contents + 1 | 0`. The `%incr` and `%decr` builtins lowered to an assignment that repeated the argument expression; they now bind the reference before the read-modify-write. Inlining decisions around an increment are taken on the code it stands for rather than on a single primitive node. https://github.com/rescript-lang/rescript/pull/8608
4041
- Fix a compiler crash on a polymorphic variant whose numeric name exceeds the `int32` range. `#99999999999("a")` and the same name in a pattern failed with `Failure("Int32.of_string")` and no location, because the range check ran in the frontend AST pass and matched only payload-free expressions. It now runs in `Typecore`, next to the integer literal decoding whose overflow error it mirrors, and covers both label positions. A bare `type t = [#99999999999]` still compiles, since nothing decodes a row field name. https://github.com/rescript-lang/rescript/pull/8608

compiler/syntax/src/res_parens.ml

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -275,20 +275,6 @@ let field_expr expr =
275275
| _ when Parsetree_viewer.expr_is_await expr -> Parenthesized
276276
| _ -> Nothing)
277277

278-
let set_field_expr_rhs expr =
279-
let opt_braces, _ = Parsetree_viewer.process_braces_attr expr in
280-
match opt_braces with
281-
| Some ({Location.loc = braces_loc}, _) -> Braced braces_loc
282-
| None -> (
283-
match expr with
284-
| {
285-
Parsetree.pexp_desc =
286-
Pexp_constraint ({pexp_desc = Pexp_pack _}, {ptyp_desc = Ptyp_package _});
287-
} ->
288-
Nothing
289-
| {pexp_desc = Pexp_constraint _} -> Parenthesized
290-
| _ -> Nothing)
291-
292278
let ternary_operand expr =
293279
let opt_braces, _ = Parsetree_viewer.process_braces_attr expr in
294280
match opt_braces with

compiler/syntax/src/res_parens.mli

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ val assert_or_await_expr_rhs : ?in_await:bool -> Parsetree.expression -> kind
1515

1616
val field_expr : Parsetree.expression -> kind
1717

18-
val set_field_expr_rhs : Parsetree.expression -> kind
19-
2018
val ternary_operand : Parsetree.expression -> kind
2119

2220
val jsx_prop_expr : Parsetree.expression -> kind

compiler/syntax/src/res_parsetree_viewer.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,7 @@ let should_indent_binary_expr expr =
547547
}
548548
when is_binary_operator operator ->
549549
is_equality_operator operator
550-
|| (not (same_precedence_sub_expression operator lhs))
551-
|| operator = ":="
550+
|| not (same_precedence_sub_expression operator lhs)
552551
| _ -> false
553552

554553
let should_inline_rhs_binary_expr rhs =

compiler/syntax/src/res_printer.ml

Lines changed: 90 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,128 +3133,56 @@ and print_if_chain ~state pexp_attributes ifs else_expr cmt_tbl =
31333133
in
31343134
Doc.concat [print_attributes ~state attrs cmt_tbl; if_docs; else_doc]
31353135

3136-
and print_object_set_expr ~state (expr : Parsetree.expression) obj member rhs
3137-
cmt_tbl =
3136+
and print_assignment_rhs ~operator rhs rhs_doc =
3137+
(* Delimited expressions handle their own indentation. Binary expressions
3138+
and switches can break after the assignment operator. *)
3139+
let should_indent =
3140+
(not (Parsetree_viewer.is_braced_expr rhs))
3141+
&& (Parsetree_viewer.is_binary_expression rhs
3142+
||
3143+
match rhs.pexp_desc with
3144+
| Pexp_match _ -> not (Parsetree_viewer.is_if_let_expr rhs)
3145+
| _ -> false)
3146+
in
3147+
Doc.concat
3148+
[
3149+
Doc.text operator;
3150+
(if should_indent then
3151+
Doc.group (Doc.indent (Doc.concat [Doc.line; rhs_doc]))
3152+
else Doc.concat [Doc.space; rhs_doc]);
3153+
]
3154+
3155+
and print_object_set_expr ~state obj member rhs cmt_tbl =
31383156
let rhs_doc =
31393157
let doc = print_expression_with_comments ~state rhs cmt_tbl in
31403158
match Parens.expr rhs with
31413159
| Parens.Parenthesized -> add_parens doc
31423160
| Braced braces -> print_braces doc rhs braces
31433161
| Nothing -> doc
31443162
in
3145-
(* TODO: unify indentation of "=" *)
3146-
let should_indent =
3147-
(not (Parsetree_viewer.is_braced_expr rhs))
3148-
&& Parsetree_viewer.is_binary_expression rhs
3149-
in
3150-
let doc =
3151-
Doc.group
3152-
(Doc.concat
3153-
[
3154-
print_object_get_doc ~state ~expr_loc:expr.pexp_loc obj member cmt_tbl;
3155-
Doc.text " =";
3156-
(if should_indent then
3157-
Doc.group (Doc.indent (Doc.concat [Doc.line; rhs_doc]))
3158-
else Doc.concat [Doc.space; rhs_doc]);
3159-
])
3160-
in
3161-
ignore expr;
3162-
doc
3163+
Doc.group
3164+
(Doc.concat
3165+
[
3166+
print_object_get_doc ~state obj member cmt_tbl;
3167+
print_assignment_rhs ~operator:" =" rhs rhs_doc;
3168+
])
31633169

3164-
and print_object_get_doc ~state ~expr_loc parent_expr
3165-
(label : string Location.loc) cmt_tbl =
3170+
and print_object_get_doc ~state parent_expr (label : string Location.loc)
3171+
cmt_tbl =
31663172
let parent_doc =
31673173
let doc = print_expression_with_comments ~state parent_expr cmt_tbl in
31683174
match Parens.unary_expr_operand parent_expr with
31693175
| Parens.Parenthesized -> add_parens doc
31703176
| Braced braces -> print_braces doc parent_expr braces
31713177
| Nothing -> doc
31723178
in
3173-
ignore expr_loc;
31743179
let member =
31753180
let member_doc = print_comments (Doc.text label.txt) cmt_tbl label.loc in
31763181
Doc.concat [Doc.text "\""; member_doc; Doc.text "\""]
31773182
in
31783183
Doc.group (Doc.concat [parent_doc; Doc.lbracket; member; Doc.rbracket])
31793184

31803185
and print_expression ~state (e : Parsetree.expression) cmt_tbl =
3181-
let print_arrow e =
3182-
let async, parameters, return_expr = Parsetree_viewer.fun_expr e in
3183-
let attrs_on_arrow = e.pexp_attributes in
3184-
let return_expr, typ_constraint =
3185-
match return_expr.pexp_desc with
3186-
| Pexp_constraint (expr, typ) ->
3187-
( {
3188-
expr with
3189-
pexp_attributes =
3190-
List.concat [expr.pexp_attributes; return_expr.pexp_attributes];
3191-
},
3192-
Some typ )
3193-
| _ -> (return_expr, None)
3194-
in
3195-
let has_constraint =
3196-
match typ_constraint with
3197-
| Some _ -> true
3198-
| None -> false
3199-
in
3200-
let parameters_doc =
3201-
print_expr_fun_parameters ~state ~in_callback:NoCallback ~async
3202-
~has_constraint parameters cmt_tbl
3203-
in
3204-
let return_expr_doc =
3205-
let opt_braces, _ = Parsetree_viewer.process_braces_attr return_expr in
3206-
let should_inline =
3207-
match (return_expr.pexp_desc, opt_braces) with
3208-
| _, Some _ -> true
3209-
| ( ( Pexp_array _ | Pexp_tuple _
3210-
| Pexp_construct (_, Some _)
3211-
| Pexp_record _ ),
3212-
_ ) ->
3213-
true
3214-
| _ -> false
3215-
in
3216-
let should_indent =
3217-
match return_expr.pexp_desc with
3218-
| Pexp_sequence _ | Pexp_let _ | Pexp_letmodule _ | Pexp_letexception _
3219-
| Pexp_open _
3220-
| Pexp_jsx_element (Jsx_fragment _) ->
3221-
false
3222-
| _ -> true
3223-
in
3224-
let return_doc =
3225-
let doc = print_expression_with_comments ~state return_expr cmt_tbl in
3226-
match Parens.expr return_expr with
3227-
| Parens.Parenthesized -> add_parens doc
3228-
| Braced braces -> print_braces doc return_expr braces
3229-
| Nothing -> doc
3230-
in
3231-
if should_inline then Doc.concat [Doc.space; return_doc]
3232-
else
3233-
Doc.group
3234-
(if should_indent then Doc.indent (Doc.concat [Doc.line; return_doc])
3235-
else Doc.concat [Doc.space; return_doc])
3236-
in
3237-
let typ_constraint_doc =
3238-
match typ_constraint with
3239-
| Some typ ->
3240-
let typ_doc =
3241-
let doc = print_typ_expr ~state typ cmt_tbl in
3242-
if Parens.arrow_return_typ_expr typ then add_parens doc else doc
3243-
in
3244-
Doc.concat [Doc.text ": "; typ_doc]
3245-
| _ -> Doc.nil
3246-
in
3247-
let attrs = print_attributes ~state attrs_on_arrow cmt_tbl in
3248-
Doc.group
3249-
(Doc.concat
3250-
[
3251-
attrs;
3252-
parameters_doc;
3253-
typ_constraint_doc;
3254-
Doc.text " =>";
3255-
return_expr_doc;
3256-
])
3257-
in
32583186
let printed_expression =
32593187
match e.pexp_desc with
32603188
| Pexp_fun
@@ -3273,7 +3201,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
32733201
print_expression_with_comments ~state
32743202
(Parsetree_viewer.rewrite_underscore_apply e)
32753203
cmt_tbl
3276-
| Pexp_fun _ -> print_arrow e
3204+
| Pexp_fun _ -> print_pexp_fun ~state ~in_callback:NoCallback e cmt_tbl
32773205
| Parsetree.Pexp_constant c -> print_constant c
32783206
| Pexp_jsx_element
32793207
(Jsx_fragment
@@ -3917,9 +3845,9 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
39173845
let doc_typ = print_typ_expr ~state typ cmt_tbl in
39183846
Doc.concat [Doc.lparen; doc_expr; Doc.text " :> "; doc_typ; Doc.rparen]
39193847
| Pexp_object_get (parent_expr, label) ->
3920-
print_object_get_doc ~state ~expr_loc:e.pexp_loc parent_expr label cmt_tbl
3848+
print_object_get_doc ~state parent_expr label cmt_tbl
39213849
| Pexp_object_set (obj, member, rhs) ->
3922-
print_object_set_expr ~state e obj member rhs cmt_tbl
3850+
print_object_set_expr ~state obj member rhs cmt_tbl
39233851
| Pexp_await e ->
39243852
let printed_expression =
39253853
print_expression_with_comments ~state e cmt_tbl
@@ -3982,7 +3910,8 @@ and print_pexp_fun ~state ~in_callback e cmt_tbl =
39823910
let return_should_indent =
39833911
match return_expr.pexp_desc with
39843912
| Pexp_sequence _ | Pexp_let _ | Pexp_letmodule _ | Pexp_letexception _
3985-
| Pexp_open _ ->
3913+
| Pexp_open _
3914+
| Pexp_jsx_element (Jsx_fragment _) ->
39863915
false
39873916
| _ -> true
39883917
in
@@ -4020,17 +3949,27 @@ and print_pexp_fun ~state ~in_callback e cmt_tbl =
40203949
in
40213950
let typ_constraint_doc =
40223951
match typ_constraint with
4023-
| Some typ -> Doc.concat [Doc.text ": "; print_typ_expr ~state typ cmt_tbl]
3952+
| Some typ ->
3953+
let typ_doc =
3954+
let doc = print_typ_expr ~state typ cmt_tbl in
3955+
if Parens.arrow_return_typ_expr typ then add_parens doc else doc
3956+
in
3957+
Doc.concat [Doc.text ": "; typ_doc]
40243958
| _ -> Doc.nil
40253959
in
4026-
Doc.concat
4027-
[
4028-
print_attributes ~state attrs_on_arrow cmt_tbl;
4029-
parameters_doc;
4030-
typ_constraint_doc;
4031-
Doc.text " =>";
4032-
return_expr_doc;
4033-
]
3960+
let doc =
3961+
Doc.concat
3962+
[
3963+
print_attributes ~state ~inline:true attrs_on_arrow cmt_tbl;
3964+
parameters_doc;
3965+
typ_constraint_doc;
3966+
Doc.text " =>";
3967+
return_expr_doc;
3968+
]
3969+
in
3970+
match in_callback with
3971+
| NoCallback -> Doc.group doc
3972+
| FitsOnOneLine | ArgumentsFitOnOneLine -> doc
40343973

40353974
and print_ternary_operand ~state expr cmt_tbl =
40363975
let doc = print_expression_with_comments ~state expr cmt_tbl in
@@ -4042,7 +3981,7 @@ and print_ternary_operand ~state expr cmt_tbl =
40423981
and print_set_field_expr ~state attrs lhs longident_loc rhs loc cmt_tbl =
40433982
let rhs_doc =
40443983
let doc = print_expression_with_comments ~state rhs cmt_tbl in
4045-
match Parens.set_field_expr_rhs rhs with
3984+
match Parens.expr rhs with
40463985
| Parens.Parenthesized -> add_parens doc
40473986
| Braced braces -> print_braces doc rhs braces
40483987
| Nothing -> doc
@@ -4054,18 +3993,14 @@ and print_set_field_expr ~state attrs lhs longident_loc rhs loc cmt_tbl =
40543993
| Braced braces -> print_braces doc lhs braces
40553994
| Nothing -> doc
40563995
in
4057-
let should_indent = Parsetree_viewer.is_binary_expression rhs in
40583996
let doc =
40593997
Doc.group
40603998
(Doc.concat
40613999
[
40624000
lhs_doc;
40634001
Doc.dot;
40644002
print_lident_path longident_loc cmt_tbl;
4065-
Doc.text " =";
4066-
(if should_indent then
4067-
Doc.group (Doc.indent (Doc.concat [Doc.line; rhs_doc]))
4068-
else Doc.concat [Doc.space; rhs_doc]);
4003+
print_assignment_rhs ~operator:" =" rhs rhs_doc;
40694004
])
40704005
in
40714006
let doc =
@@ -4276,24 +4211,7 @@ and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
42764211
in
42774212
if is_lhs then add_parens doc else doc
42784213
| Pexp_object_set (obj, member, rhs) ->
4279-
let rhs_doc = print_expression_with_comments ~state rhs cmt_tbl in
4280-
let lhs_doc =
4281-
print_object_get_doc ~state ~expr_loc:expr.pexp_loc obj member
4282-
cmt_tbl
4283-
in
4284-
(* TODO: unify indentation of "=" *)
4285-
let should_indent = Parsetree_viewer.is_binary_expression rhs in
4286-
let doc =
4287-
Doc.group
4288-
(Doc.concat
4289-
[
4290-
lhs_doc;
4291-
Doc.text " =";
4292-
(if should_indent then
4293-
Doc.group (Doc.indent (Doc.concat [Doc.line; rhs_doc]))
4294-
else Doc.concat [Doc.space; rhs_doc]);
4295-
])
4296-
in
4214+
let doc = print_object_set_expr ~state obj member rhs cmt_tbl in
42974215
let doc =
42984216
match expr.pexp_attributes with
42994217
| [] -> doc
@@ -4304,12 +4222,27 @@ and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
43044222
if is_lhs then add_parens doc else doc
43054223
| _ -> (
43064224
let doc = print_expression_with_comments ~state expr cmt_tbl in
4307-
match Parens.binary_expr_operand ~is_lhs expr with
4225+
let parens =
4226+
match expr.pexp_desc with
4227+
| Pexp_fun _ when parent_operator = ":=" && not is_lhs ->
4228+
Parens.expr expr
4229+
| _ -> Parens.binary_expr_operand ~is_lhs expr
4230+
in
4231+
match parens with
43084232
| Parens.Parenthesized -> add_parens doc
43094233
| Braced braces -> print_braces doc expr braces
43104234
| Nothing -> doc)
43114235
in
4312-
flatten ~is_lhs ~is_multiline expr parent_operator
4236+
if
4237+
parent_operator = ":=" && (not is_lhs)
4238+
&& Parsetree_viewer.is_braced_expr expr
4239+
then
4240+
let doc = print_expression_with_comments ~state expr cmt_tbl in
4241+
match Parens.expr expr with
4242+
| Braced braces -> print_braces doc expr braces
4243+
| Parenthesized -> add_parens doc
4244+
| Nothing -> doc
4245+
else flatten ~is_lhs ~is_multiline expr parent_operator
43134246
in
43144247
match expr.pexp_desc with
43154248
| Pexp_apply
@@ -4351,23 +4284,25 @@ and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
43514284
in
43524285

43534286
let right =
4354-
let operator_with_rhs =
4355-
let rhs_doc =
4356-
print_operand
4357-
~is_lhs:(Parsetree_viewer.is_rhs_binary_operator operator)
4358-
~is_multiline rhs operator
4359-
in
4360-
Doc.concat
4361-
[
4362-
print_binary_operator
4363-
~inline_rhs:(Parsetree_viewer.should_inline_rhs_binary_expr rhs)
4364-
operator;
4365-
rhs_doc;
4366-
]
4287+
let rhs_doc =
4288+
print_operand
4289+
~is_lhs:(Parsetree_viewer.is_rhs_binary_operator operator)
4290+
~is_multiline rhs operator
43674291
in
4368-
if Parsetree_viewer.should_indent_binary_expr expr then
4369-
Doc.group (Doc.indent operator_with_rhs)
4370-
else operator_with_rhs
4292+
if operator = ":=" then print_assignment_rhs ~operator:" :=" rhs rhs_doc
4293+
else
4294+
let operator_with_rhs =
4295+
Doc.concat
4296+
[
4297+
print_binary_operator
4298+
~inline_rhs:(Parsetree_viewer.should_inline_rhs_binary_expr rhs)
4299+
operator;
4300+
rhs_doc;
4301+
]
4302+
in
4303+
if Parsetree_viewer.should_indent_binary_expr expr then
4304+
Doc.group (Doc.indent operator_with_rhs)
4305+
else operator_with_rhs
43714306
in
43724307
let doc =
43734308
Doc.group

0 commit comments

Comments
 (0)