diff --git a/CHANGELOG.md b/CHANGELOG.md index 86fab3a77e..f8142b4302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ - Fix `index out of bounds` exception thrown in rare cases by `rescript-editor-analysis.exe codeAction` command. https://github.com/rescript-lang/rescript/pull/7523 - Don't produce duplicate type definitions for recursive types on hover. https://github.com/rescript-lang/rescript/pull/7524 - Prop punning when types don't match results in I/O error: _none_: No such file or directory. https://github.com/rescript-lang/rescript/pull/7533 +- Fix doc comment before variant throwing syntax error. https://github.com/rescript-lang/rescript/pull/7535 #### :nail_care: Polish diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index aebd7bc62d..154969e2c2 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -4885,12 +4885,35 @@ and parse_constr_decl_args p = * | constr-name const-args * | attrs constr-name const-args *) and parse_type_constructor_declaration_with_bar p = - match p.Parser.token with - | Bar -> + let is_constructor_with_bar p = + Parser.lookahead p (fun state -> + match state.Parser.token with + | DocComment _ -> ( + Parser.next state; + match state.token with + | Bar -> true + | _ -> false) + | Bar -> true + | _ -> false) + in + if is_constructor_with_bar p then ( + let doc_comment_attrs = + match p.Parser.token with + | DocComment (loc, s) -> + Parser.next p; + [doc_comment_to_attribute loc s] + | _ -> [] + in let start_pos = p.Parser.start_pos in Parser.next p; - Some (parse_type_constructor_declaration ~start_pos p) - | _ -> None + let constr = parse_type_constructor_declaration ~start_pos p in + Some + { + constr with + Parsetree.pcd_attributes = + doc_comment_attrs @ constr.Parsetree.pcd_attributes; + }) + else None and parse_type_constructor_declaration ~start_pos p = Parser.leave_breadcrumb p Grammar.ConstructorDeclaration; @@ -4919,9 +4942,17 @@ and parse_type_constructor_declarations ?first p = let first_constr_decl = match first with | None -> + let doc_comment_attrs = + match p.Parser.token with + | DocComment (loc, s) -> + Parser.next p; + [doc_comment_to_attribute loc s] + | _ -> [] + in let start_pos = p.Parser.start_pos in ignore (Parser.optional p Token.Bar); - parse_type_constructor_declaration ~start_pos p + let constr = parse_type_constructor_declaration ~start_pos p in + {constr with pcd_attributes = doc_comment_attrs @ constr.pcd_attributes} | Some first_constr_decl -> first_constr_decl in first_constr_decl @@ -4947,7 +4978,7 @@ and parse_type_representation ?current_type_name_path ?inline_types_context p = in let kind = match p.Parser.token with - | Bar | Uident _ -> + | Bar | Uident _ | DocComment _ -> Parsetree.Ptype_variant (parse_type_constructor_declarations p) | Lbrace -> Parsetree.Ptype_record @@ -5500,7 +5531,7 @@ and parse_type_equation_and_representation ?current_type_name_path parse_record_or_object_decl ?current_type_name_path ?inline_types_context p | Private -> parse_private_eq_or_repr p - | Bar | DotDot -> + | Bar | DotDot | DocComment _ -> let priv, kind = parse_type_representation p in (None, priv, kind) | _ -> ( diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index 4d00515e30..7e2c76a32b 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -340,7 +340,8 @@ let print_list ~get_loc ~nodes ~print ?(force_break = false) t = in Doc.breakable_group ~force_break docs -let print_listi ~get_loc ~nodes ~print ?(force_break = false) t = +let print_listi ~get_loc ~nodes ~print ?(ignore_empty_lines = false) + ?(force_break = false) t = let rec loop i (prev_loc : Location.t) acc nodes = match nodes with | [] -> (prev_loc, Doc.concat (List.rev acc)) @@ -352,8 +353,10 @@ let print_listi ~get_loc ~nodes ~print ?(force_break = false) t = | Some comment -> (Comment.loc comment).loc_start in let sep = - if start_pos.pos_lnum - prev_loc.loc_end.pos_lnum > 1 then - Doc.concat [Doc.hard_line; Doc.hard_line] + if + start_pos.pos_lnum - prev_loc.loc_end.pos_lnum > 1 + && not ignore_empty_lines + then Doc.concat [Doc.hard_line; Doc.hard_line] else Doc.line in let doc = print_comments (print node t i) t loc in @@ -1542,7 +1545,7 @@ and print_constructor_declarations ~state ~private_flag ~print:(fun cd cmt_tbl i -> let doc = print_constructor_declaration2 ~state i cd cmt_tbl in print_comments doc cmt_tbl cd.Parsetree.pcd_loc) - ~force_break cmt_tbl + ~force_break cmt_tbl ~ignore_empty_lines:true in Doc.breakable_group ~force_break (Doc.indent (Doc.concat [Doc.line; private_flag; rows])) @@ -1555,7 +1558,8 @@ and print_constructor_declaration2 ~state i let comment_doc = match comment_attrs with | [] -> Doc.nil - | comment_attrs -> print_doc_comments ~state cmt_tbl comment_attrs + | comment_attrs -> + print_doc_comments ~sep:Doc.hard_line ~state cmt_tbl comment_attrs in let attrs = print_attributes ~state attrs cmt_tbl in let is_dot_dot_dot = cd.pcd_name.txt = "..." in @@ -1579,8 +1583,8 @@ and print_constructor_declaration2 ~state i in Doc.concat [ - bar; comment_doc; + bar; Doc.group (Doc.concat [ diff --git a/tests/tests/src/arith_syntax.res b/tests/tests/src/arith_syntax.res index e4e2980ba7..14be6752f1 100644 --- a/tests/tests/src/arith_syntax.res +++ b/tests/tests/src/arith_syntax.res @@ -1,16 +1,16 @@ type rec expression = - | /** non-negative integer constant */ - Numeral(float) - | /** Addition [e1 + e2] */ - Plus(expression, expression) - | /** Difference [e1 - e2] */ - Minus(expression, expression) - | /** Product [e1 * e2] */ - Times(expression, expression) - | /** Quotient [e1 / e2] */ - Divide(expression, expression) - | /** Opposite value [-e] */ - Negate(expression) + /** non-negative integer constant */ + | Numeral(float) + /** Addition [e1 + e2] */ + | Plus(expression, expression) + /** Difference [e1 - e2] */ + | Minus(expression, expression) + /** Product [e1 * e2] */ + | Times(expression, expression) + /** Quotient [e1 / e2] */ + | Divide(expression, expression) + /** Opposite value [-e] */ + | Negate(expression) | Variable(string) let rec str = e => diff --git a/tests/tests/src/condition_compilation_test.mjs b/tests/tests/src/condition_compilation_test.mjs index 533679e9e7..9ac6ac50a1 100644 --- a/tests/tests/src/condition_compilation_test.mjs +++ b/tests/tests/src/condition_compilation_test.mjs @@ -33,9 +33,9 @@ function eq(loc, x, y) { }; } -eq("File \"condition_compilation_test.res\", line 63, characters 5-12", 3, 3); +eq("File \"condition_compilation_test.res\", line 60, characters 5-12", 3, 3); -eq("File \"condition_compilation_test.res\", line 64, characters 5-12", v.contents, 2); +eq("File \"condition_compilation_test.res\", line 61, characters 5-12", v.contents, 2); Mt.from_pair_suites("Condition_compilation_test", suites.contents); diff --git a/tests/tests/src/condition_compilation_test.res b/tests/tests/src/condition_compilation_test.res index 5bf56bed1b..8c7a8629ac 100644 --- a/tests/tests/src/condition_compilation_test.res +++ b/tests/tests/src/condition_compilation_test.res @@ -15,11 +15,8 @@ type open_flag = | O_DSYNC | O_SYNC | O_RSYNC - | O_SHARE_DELETE - | O_CLOEXEC - | O_KEEPEXEC let vv = 3 diff --git a/tests/tests/src/gpr_1822_test.mjs b/tests/tests/src/gpr_1822_test.mjs index 053f75f08a..c6a595a565 100644 --- a/tests/tests/src/gpr_1822_test.mjs +++ b/tests/tests/src/gpr_1822_test.mjs @@ -34,7 +34,7 @@ let area; area = myShape.TAG === "Circle" ? 100 * 3.14 : 10 * myShape._1 | 0; -eq("File \"gpr_1822_test.res\", line 23, characters 3-10", area, 314); +eq("File \"gpr_1822_test.res\", line 22, characters 3-10", area, 314); Mt.from_pair_suites("Gpr_1822_test", suites.contents); diff --git a/tests/tests/src/gpr_1822_test.res b/tests/tests/src/gpr_1822_test.res index 0d9006280f..a83c2a036c 100644 --- a/tests/tests/src/gpr_1822_test.res +++ b/tests/tests/src/gpr_1822_test.res @@ -11,7 +11,6 @@ let eq = (loc, x, y) => { type shape = | Circle(int) - | Rectangle(int, int) let myShape = Circle(10) diff --git a/tests/tests/src/mutual_non_recursive_type.res b/tests/tests/src/mutual_non_recursive_type.res index 4b3a740bfb..e07c2a84b5 100644 --- a/tests/tests/src/mutual_non_recursive_type.res +++ b/tests/tests/src/mutual_non_recursive_type.res @@ -9,7 +9,7 @@ type t = | Ta(t) /* * u compilation error [nonrec applices to all] */ | Tb(int) and u = - | /** one attribute nonrecursive will affect all */ - H(t) /* refers to old t */ + /** one attribute nonrecursive will affect all */ + | H(t) /* refers to old t */ let v: u = H(OT) diff --git a/tests/tests/src/test_seq.res b/tests/tests/src/test_seq.res index 8927d6119a..fd9bead672 100644 --- a/tests/tests/src/test_seq.res +++ b/tests/tests/src/test_seq.res @@ -29,7 +29,6 @@ type rec spec = | Set_float(ref) /* Set the reference to the float argument */ | Tuple(list) /* Take several arguments according to the spec list */ - | Symbol(list, string => unit) /* Take one of the symbols as argument and call the function with the symbol. */ diff --git a/tests/tools_tests/src/DocExtractionRes.res b/tests/tools_tests/src/DocExtractionRes.res index e86ab142e3..444cb8e12c 100644 --- a/tests/tools_tests/src/DocExtractionRes.res +++ b/tests/tools_tests/src/DocExtractionRes.res @@ -28,12 +28,12 @@ let \"SomeConstant" = 12 module SomeInnerModule = { /*** Another module level docstring here.*/ type status = - | /** If this is started or not */ - Started(t) - | /** Stopped? */ - Stopped - | /** Now idle.*/ - Idle + /** If this is started or not */ + | Started(t) + /** Stopped? */ + | Stopped + /** Now idle.*/ + | Idle /** These are all the valid inputs.*/ type validInputs = [#something | #"needs-escaping" | #withPayload(int) | #status(status)] @@ -55,8 +55,8 @@ module AnotherModule = { /** Trying how it looks with an inline record in a variant. */ type someVariantWithInlineRecords = - | /** This has inline records...*/ - SomeStuff({ + /** This has inline records...*/ + | SomeStuff({ offline: bool, /** Is the user online? */ online?: bool,