From 754e8894bcc87cd5bca1cd5b52b7f5165df84c0c Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 30 Jul 2025 16:27:16 +0200 Subject: [PATCH 1/3] refactor printing type declarations to fix inline type declarations not being printed correctly in interface files --- compiler/syntax/src/res_printer.ml | 74 ++++++++++--------- .../printer/signature/expected/type.resi.txt | 4 + .../data/printer/signature/type.resi | 6 ++ 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index f10b404399..f6b392a48e 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -40,6 +40,13 @@ let add_braces doc = let add_async doc = Doc.concat [Doc.text "async "; doc] +let has_inline_type_definitions type_declarations = + type_declarations + |> List.find_opt (fun (td : Parsetree.type_declaration) -> + Res_parsetree_viewer.has_inline_record_definition_attribute + td.ptype_attributes) + |> Option.is_some + let get_first_leading_comment tbl loc = match Hashtbl.find tbl.CommentTable.leading loc with | comment :: _ -> Some comment @@ -587,29 +594,7 @@ and print_structure_item ~state (si : Parsetree.structure_item) cmt_tbl = | Asttypes.Recursive -> Doc.text "rec " in print_value_bindings ~state ~rec_flag value_bindings cmt_tbl - | Pstr_type (Recursive, type_declarations) - when type_declarations - |> List.find_opt (fun (td : Parsetree.type_declaration) -> - Res_parsetree_viewer.has_inline_record_definition_attribute - td.ptype_attributes) - |> Option.is_some -> - let inline_record_definitions, regular_declarations = - type_declarations - |> List.partition (fun (td : Parsetree.type_declaration) -> - Res_parsetree_viewer.has_inline_record_definition_attribute - td.ptype_attributes) - in - print_type_declarations ~inline_record_definitions ~state - ~rec_flag: - (if List.length regular_declarations > 1 then Doc.text "rec " - else Doc.nil) - regular_declarations cmt_tbl | Pstr_type (rec_flag, type_declarations) -> - let rec_flag = - match rec_flag with - | Asttypes.Nonrecursive -> Doc.nil - | Asttypes.Recursive -> Doc.text "rec " - in print_type_declarations ~state ~rec_flag type_declarations cmt_tbl | Pstr_primitive value_description -> print_value_description ~state value_description cmt_tbl @@ -985,11 +970,6 @@ and print_signature_item ~state (si : Parsetree.signature_item) cmt_tbl = | Parsetree.Psig_value value_description -> print_value_description ~state value_description cmt_tbl | Psig_type (rec_flag, type_declarations) -> - let rec_flag = - match rec_flag with - | Asttypes.Nonrecursive -> Doc.nil - | Asttypes.Recursive -> Doc.text "rec " - in print_type_declarations ~state ~rec_flag type_declarations cmt_tbl | Psig_typext type_extension -> print_type_extension ~state type_extension cmt_tbl @@ -1191,13 +1171,39 @@ and print_value_description ~state value_description cmt_tbl = else Doc.nil); ]) -and print_type_declarations ?inline_record_definitions ~state ~rec_flag - type_declarations cmt_tbl = - print_listi - ~get_loc:(fun n -> n.Parsetree.ptype_loc) - ~nodes:type_declarations - ~print:(print_type_declaration2 ?inline_record_definitions ~state ~rec_flag) - cmt_tbl +and print_type_declarations ~state ~rec_flag type_declarations cmt_tbl = + if has_inline_type_definitions type_declarations then + let inline_record_definitions, regular_declarations = + type_declarations + |> List.partition (fun (td : Parsetree.type_declaration) -> + Res_parsetree_viewer.has_inline_record_definition_attribute + td.ptype_attributes) + in + let adjusted_rec_flag = + match rec_flag with + | Recursive -> + if List.length regular_declarations > 1 then Doc.text "rec " + else Doc.nil + | Nonrecursive -> Doc.nil + in + print_listi + ~get_loc:(fun n -> n.Parsetree.ptype_loc) + ~nodes:regular_declarations + ~print: + (print_type_declaration2 ~inline_record_definitions ~state + ~rec_flag:adjusted_rec_flag) + cmt_tbl + else + print_listi + ~get_loc:(fun n -> n.Parsetree.ptype_loc) + ~nodes:type_declarations + ~print: + (print_type_declaration2 ~state + ~rec_flag: + (match rec_flag with + | Nonrecursive -> Doc.nil + | Recursive -> Doc.text "rec ")) + cmt_tbl (* * type_declaration = { diff --git a/tests/syntax_tests/data/printer/signature/expected/type.resi.txt b/tests/syntax_tests/data/printer/signature/expected/type.resi.txt index 898c72e462..aefddb698e 100644 --- a/tests/syntax_tests/data/printer/signature/expected/type.resi.txt +++ b/tests/syntax_tests/data/printer/signature/expected/type.resi.txt @@ -6,3 +6,7 @@ type color = | Red | Blue | Black + +type options = { + permissions: {all: bool}, +} diff --git a/tests/syntax_tests/data/printer/signature/type.resi b/tests/syntax_tests/data/printer/signature/type.resi index 898c72e462..2bcaabb688 100644 --- a/tests/syntax_tests/data/printer/signature/type.resi +++ b/tests/syntax_tests/data/printer/signature/type.resi @@ -6,3 +6,9 @@ type color = | Red | Blue | Black + +type options = { + permissions: { + all: bool + } +} From c2cebc08b21d4df2d3d4289e6b7b90a2d3702d1e Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 30 Jul 2025 16:31:15 +0200 Subject: [PATCH 2/3] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5079821730..533561135a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ #### :bug: Bug fix +- Fix formatting of nested records in `.resi` files. https://github.com/rescript-lang/rescript/pull/7741 + #### :memo: Documentation #### :nail_care: Polish From 28cc10cb9005d6b320ead70d02dd179a7b82ee6a Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 31 Jul 2025 20:51:59 +0200 Subject: [PATCH 3/3] for inline records, calculate force break from the record body itself --- compiler/syntax/src/res_printer.ml | 15 ++++++++------- .../data/printer/signature/expected/type.resi.txt | 6 +++++- .../syntax_tests/data/printer/signature/type.resi | 4 +++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index f6b392a48e..845cf31cde 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -1464,13 +1464,14 @@ and print_type_param ~state (param : Parsetree.core_type * Asttypes.variance) in Doc.concat [printed_variance; print_typ_expr ~state typ cmt_tbl] -and print_record_declaration ?inline_record_definitions ~state - (lds : Parsetree.label_declaration list) cmt_tbl = +and print_record_declaration ?check_break_from_loc ?inline_record_definitions + ~state (lds : Parsetree.label_declaration list) cmt_tbl = let force_break = - match (lds, List.rev lds) with - | first :: _, last :: _ -> + match (check_break_from_loc, lds, List.rev lds) with + | Some loc, _, _ -> loc.Location.loc_start.pos_lnum < loc.loc_end.pos_lnum + | _, first :: _, last :: _ -> first.pld_loc.loc_start.pos_lnum < last.pld_loc.loc_end.pos_lnum - | _ -> false + | _, _, _ -> false in Doc.breakable_group ~force_break (Doc.concat @@ -1805,8 +1806,8 @@ and print_typ_expr ?inline_record_definitions ~(state : State.t) inline_record_definitions |> find_inline_record_definition inline_record_name with - | Some {ptype_kind = Ptype_record lds} -> - print_record_declaration + | Some {ptype_kind = Ptype_record lds; ptype_loc} -> + print_record_declaration ~check_break_from_loc:ptype_loc ~inline_record_definitions:(inline_record_definitions |> Option.get) ~state lds cmt_tbl | _ -> assert false) diff --git a/tests/syntax_tests/data/printer/signature/expected/type.resi.txt b/tests/syntax_tests/data/printer/signature/expected/type.resi.txt index aefddb698e..100f94c2c4 100644 --- a/tests/syntax_tests/data/printer/signature/expected/type.resi.txt +++ b/tests/syntax_tests/data/printer/signature/expected/type.resi.txt @@ -8,5 +8,9 @@ type color = | Black type options = { - permissions: {all: bool}, + permissions: { + all: { + stuff: bool, + }, + }, } diff --git a/tests/syntax_tests/data/printer/signature/type.resi b/tests/syntax_tests/data/printer/signature/type.resi index 2bcaabb688..28bbe30cba 100644 --- a/tests/syntax_tests/data/printer/signature/type.resi +++ b/tests/syntax_tests/data/printer/signature/type.resi @@ -9,6 +9,8 @@ type color = type options = { permissions: { - all: bool + all: { + stuff: bool + } } }