Skip to content

Commit a8c25fd

Browse files
authored
Attach res.doc to polyvariant (#8155)
* Attach res.doc to polyvariant * Refactor * Update CHANGELOG * Handle inherited poly types
1 parent 2e90f88 commit a8c25fd

File tree

7 files changed

+179
-42
lines changed

7 files changed

+179
-42
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- Fix rewatch swallowing parse warnings (%todo). https://github.com/rescript-lang/rescript/pull/8135
2929
- Rewatch: log errors and warnings to `stderr`. https://github.com/rescript-lang/rescript/pull/8147 https://github.com/rescript-lang/rescript/pull/8148
3030
- Rewatch: warn about deprecated package specs `es6`/`es6-global`. https://github.com/rescript-lang/rescript/pull/8146
31+
- Attach res.doc to polyvariant. https://github.com/rescript-lang/rescript/pull/8155
3132

3233
#### :memo: Documentation
3334

compiler/syntax/src/res_core.ml

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5265,24 +5265,25 @@ and parse_constr_decl_args p =
52655265
in
52665266
(constr_args, res)
52675267

5268+
(* Helper to check if current token is a bar or doc comment followed by a bar *)
5269+
and is_bar_or_doc_comment_then_bar p =
5270+
Parser.lookahead p (fun state ->
5271+
match state.Parser.token with
5272+
| DocComment _ -> (
5273+
Parser.next state;
5274+
match state.token with
5275+
| Bar -> true
5276+
| _ -> false)
5277+
| Bar -> true
5278+
| _ -> false)
5279+
52685280
(* constr-decl ::=
52695281
* | constr-name
52705282
* | attrs constr-name
52715283
* | constr-name const-args
52725284
* | attrs constr-name const-args *)
52735285
and parse_type_constructor_declaration_with_bar p =
5274-
let is_constructor_with_bar p =
5275-
Parser.lookahead p (fun state ->
5276-
match state.Parser.token with
5277-
| DocComment _ -> (
5278-
Parser.next state;
5279-
match state.token with
5280-
| Bar -> true
5281-
| _ -> false)
5282-
| Bar -> true
5283-
| _ -> false)
5284-
in
5285-
if is_constructor_with_bar p then (
5286+
if is_bar_or_doc_comment_then_bar p then (
52865287
let doc_comment_attrs =
52875288
match p.Parser.token with
52885289
| DocComment (loc, s) ->
@@ -5905,29 +5906,84 @@ and parse_tag_spec_full p =
59055906

59065907
and parse_tag_specs p =
59075908
match p.Parser.token with
5908-
| Bar ->
5909-
Parser.next p;
5910-
let row_field = parse_tag_spec p in
5911-
row_field :: parse_tag_specs p
5909+
| (Bar | DocComment _) when is_bar_or_doc_comment_then_bar p ->
5910+
let doc_comment_attrs =
5911+
match p.Parser.token with
5912+
| DocComment (loc, s) ->
5913+
Parser.next p;
5914+
[doc_comment_to_attribute loc s]
5915+
| _ -> []
5916+
in
5917+
Parser.expect Bar p;
5918+
let tag = parse_tag_spec p in
5919+
let tag_with_doc =
5920+
match tag with
5921+
| Parsetree.Rtag (name, attrs, contains_constant, types) ->
5922+
Parsetree.Rtag
5923+
(name, doc_comment_attrs @ attrs, contains_constant, types)
5924+
| Rinherit typ ->
5925+
Rinherit
5926+
{typ with ptyp_attributes = doc_comment_attrs @ typ.ptyp_attributes}
5927+
in
5928+
tag_with_doc :: parse_tag_specs p
59125929
| _ -> []
59135930

59145931
and parse_tag_spec p =
5915-
let attrs = parse_attributes p in
5932+
let doc_comment_attrs =
5933+
match p.Parser.token with
5934+
| DocComment (loc, s) ->
5935+
Parser.next p;
5936+
[doc_comment_to_attribute loc s]
5937+
| _ -> []
5938+
in
5939+
let attrs = doc_comment_attrs @ parse_attributes p in
59165940
match p.Parser.token with
59175941
| Hash -> parse_polymorphic_variant_type_spec_hash ~attrs ~full:false p
59185942
| _ ->
59195943
let typ = parse_typ_expr ~attrs p in
59205944
Parsetree.Rinherit typ
59215945

59225946
and parse_tag_spec_first p =
5923-
let attrs = parse_attributes p in
59245947
match p.Parser.token with
5925-
| Bar ->
5926-
Parser.next p;
5927-
[parse_tag_spec p]
5928-
| Hash -> [parse_polymorphic_variant_type_spec_hash ~attrs ~full:false p]
5948+
| (Bar | DocComment _) when is_bar_or_doc_comment_then_bar p ->
5949+
let doc_comment_attrs =
5950+
match p.Parser.token with
5951+
| DocComment (loc, s) ->
5952+
Parser.next p;
5953+
[doc_comment_to_attribute loc s]
5954+
| _ -> []
5955+
in
5956+
Parser.expect Bar p;
5957+
let tag = parse_tag_spec p in
5958+
(match tag with
5959+
| Parsetree.Rtag (name, attrs, contains_constant, types) ->
5960+
Parsetree.Rtag (name, doc_comment_attrs @ attrs, contains_constant, types)
5961+
| Rinherit typ ->
5962+
Rinherit
5963+
{typ with ptyp_attributes = doc_comment_attrs @ typ.ptyp_attributes})
5964+
:: parse_tag_specs p
5965+
| DocComment _ | Hash | At -> (
5966+
let doc_comment_attrs =
5967+
match p.Parser.token with
5968+
| DocComment (loc, s) ->
5969+
Parser.next p;
5970+
[doc_comment_to_attribute loc s]
5971+
| _ -> []
5972+
in
5973+
let attrs = doc_comment_attrs @ parse_attributes p in
5974+
match p.Parser.token with
5975+
| Hash -> [parse_polymorphic_variant_type_spec_hash ~attrs ~full:false p]
5976+
| _ -> (
5977+
let typ = parse_typ_expr ~attrs p in
5978+
match p.token with
5979+
| Rbracket ->
5980+
(* example: [ListStyleType.t] *)
5981+
[Parsetree.Rinherit typ]
5982+
| _ ->
5983+
Parser.expect Bar p;
5984+
[Parsetree.Rinherit typ; parse_tag_spec p]))
59295985
| _ -> (
5930-
let typ = parse_typ_expr ~attrs p in
5986+
let typ = parse_typ_expr p in
59315987
match p.token with
59325988
| Rbracket ->
59335989
(* example: [ListStyleType.t] *)

compiler/syntax/src/res_printer.ml

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,18 +1893,44 @@ and print_typ_expr ?inline_record_definitions ~(state : State.t)
18931893
typ_expr.ptyp_loc.Location.loc_start.pos_lnum
18941894
< typ_expr.ptyp_loc.loc_end.pos_lnum
18951895
in
1896-
let print_row_field = function
1896+
let print_row_field i = function
18971897
| Parsetree.Rtag ({txt; loc}, attrs, true, []) ->
1898-
let doc =
1898+
let comment_attrs, attrs =
1899+
ParsetreeViewer.partition_doc_comment_attributes attrs
1900+
in
1901+
let comment_doc =
1902+
match comment_attrs with
1903+
| [] -> Doc.nil
1904+
| comment_attrs ->
1905+
print_doc_comments ~sep:Doc.hard_line ~state cmt_tbl comment_attrs
1906+
in
1907+
let bar =
1908+
if i > 0 || comment_attrs <> [] then Doc.text "| "
1909+
else Doc.if_breaks (Doc.text "| ") Doc.nil
1910+
in
1911+
let tag_doc =
18991912
Doc.group
19001913
(Doc.concat
19011914
[
19021915
print_attributes ~state attrs cmt_tbl;
19031916
Doc.concat [Doc.text "#"; print_poly_var_ident txt];
19041917
])
19051918
in
1906-
print_comments doc cmt_tbl loc
1907-
| Rtag ({txt}, attrs, truth, types) ->
1919+
Doc.concat [comment_doc; bar; print_comments tag_doc cmt_tbl loc]
1920+
| Rtag ({txt; loc}, attrs, truth, types) ->
1921+
let comment_attrs, attrs =
1922+
ParsetreeViewer.partition_doc_comment_attributes attrs
1923+
in
1924+
let comment_doc =
1925+
match comment_attrs with
1926+
| [] -> Doc.nil
1927+
| comment_attrs ->
1928+
print_doc_comments ~sep:Doc.hard_line ~state cmt_tbl comment_attrs
1929+
in
1930+
let bar =
1931+
if i > 0 || comment_attrs <> [] then Doc.text "| "
1932+
else Doc.if_breaks (Doc.text "| ") Doc.nil
1933+
in
19081934
let do_type t =
19091935
match t.Parsetree.ptyp_desc with
19101936
| Ptyp_tuple _ -> print_typ_expr ~state t cmt_tbl
@@ -1919,21 +1945,25 @@ and print_typ_expr ?inline_record_definitions ~(state : State.t)
19191945
let cases =
19201946
if truth then Doc.concat [Doc.line; Doc.text "& "; cases] else cases
19211947
in
1922-
Doc.group
1923-
(Doc.concat
1924-
[
1925-
print_attributes ~state attrs cmt_tbl;
1926-
Doc.concat [Doc.text "#"; print_poly_var_ident txt];
1927-
cases;
1928-
])
1929-
| Rinherit core_type -> print_typ_expr ~state core_type cmt_tbl
1930-
in
1931-
let docs = List.map print_row_field row_fields in
1932-
let cases = Doc.join ~sep:(Doc.concat [Doc.line; Doc.text "| "]) docs in
1933-
let cases =
1934-
if docs = [] then cases
1935-
else Doc.concat [Doc.if_breaks (Doc.text "| ") Doc.nil; cases]
1948+
let tag_doc =
1949+
Doc.group
1950+
(Doc.concat
1951+
[
1952+
print_attributes ~state attrs cmt_tbl;
1953+
Doc.concat [Doc.text "#"; print_poly_var_ident txt];
1954+
cases;
1955+
])
1956+
in
1957+
Doc.concat [comment_doc; bar; print_comments tag_doc cmt_tbl loc]
1958+
| Rinherit core_type ->
1959+
let bar =
1960+
if i > 0 then Doc.text "| "
1961+
else Doc.if_breaks (Doc.text "| ") Doc.nil
1962+
in
1963+
Doc.concat [bar; print_typ_expr ~state core_type cmt_tbl]
19361964
in
1965+
let docs = List.mapi print_row_field row_fields in
1966+
let cases = Doc.join ~sep:Doc.line docs in
19371967
let opening_symbol =
19381968
if closed_flag = Open then Doc.concat [Doc.greater_than; Doc.line]
19391969
else if labels_opt = None then Doc.soft_line

tests/syntax_tests/data/parsing/grammar/typexpr/expected/polyVariant.res.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,11 @@ module type Conjunctive =
1212
type nonrec t = [ s]
1313
type nonrec t = [ ListStyleType.t]
1414
type nonrec number = [ `1 | `42 | `4244 ]
15-
type nonrec complexNumbericPolyVar = [ `1 of string | `2 of (int * string) ]
15+
type nonrec complexNumbericPolyVar = [ `1 of string | `2 of (int * string) ]
16+
type nonrec withDocComments =
17+
[ `Foo [@res.doc " First variant "] | `Bar [@res.doc " Second variant "]
18+
| `Baz of (int * string) [@res.doc " Third variant with args "]]
19+
type nonrec singleDocComment = [ `Only [@res.doc " Single variant "]]
20+
type nonrec mixedDocComments =
21+
[ `NoComment | `WithComment [@res.doc " With comment "]
22+
| `AnotherNoComment ]

tests/syntax_tests/data/parsing/grammar/typexpr/polyVariant.res

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,25 @@ type complexNumbericPolyVar = [
2626
| #1(string)
2727
| #2(int, string)
2828
]
29+
30+
// Doc comments on polymorphic variants
31+
type withDocComments = [
32+
/** First variant */
33+
| #Foo
34+
/** Second variant */
35+
| #Bar
36+
/** Third variant with args */
37+
| #Baz(int, string)
38+
]
39+
40+
type singleDocComment = [
41+
/** Single variant */
42+
#Only
43+
]
44+
45+
type mixedDocComments = [
46+
| #NoComment
47+
/** With comment */
48+
| #WithComment
49+
| #AnotherNoComment
50+
]

tests/syntax_tests/data/printer/typexpr/expected/variant.res.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,13 @@ type foo = [
123123
| // before baz
124124
#Baz
125125
] // after baz
126+
127+
// doc comments on inherited polyvariant types
128+
type rgb = [#Red | #Green | #Blue]
129+
type color = [
130+
| /** Primary colors from RGB */ rgb
131+
/** A warm color */
132+
| #Orange
133+
/** Another warm color */
134+
| #Yellow
135+
]

tests/syntax_tests/data/printer/typexpr/variant.res

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,14 @@ type foo = [
117117
// before baz
118118
| #Baz // after baz
119119
]
120+
121+
// doc comments on inherited polyvariant types
122+
type rgb = [#Red | #Green | #Blue]
123+
type color = [
124+
/** Primary colors from RGB */
125+
| rgb
126+
/** A warm color */
127+
| #Orange
128+
/** Another warm color */
129+
| #Yellow
130+
]

0 commit comments

Comments
 (0)