Skip to content

Commit b12d83b

Browse files
committed
syntax support
1 parent 80588b6 commit b12d83b

16 files changed

+138
-41
lines changed

jscomp/build_tests/super_errors/expected/dict_pattern_inference.res.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11

22
We've found a bug for you!
3-
/.../fixtures/dict_pattern_inference.res:3:36-42
3+
/.../fixtures/dict_pattern_inference.res:3:27-33
44

55
1 │ let foo = dict =>
66
2 │ switch dict {
7-
3 │ | @res.dictPattern {one: 1, two: "hello"} => Js.log("one")
7+
3 │ | dict{"one": 1, "two": "hello"} => Js.log("one")
88
4 │ | _ => Js.log("not one")
99
5 │ }
1010

jscomp/build_tests/super_errors/expected/dict_pattern_inference_constrained.res.expected

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11

2-
Warning number 9
3-
/.../fixtures/dict_pattern_inference_constrained.res:3:22-29
4-
5-
1 │ let foo = dict =>
6-
2 │ switch dict {
7-
3 │ | @res.dictPattern {one: 1} =>
8-
4 │ let _: dict<string> = dict
9-
5 │ Js.log("one")
10-
11-
the following labels are not bound in this record pattern: dictValuesType
12-
Either bind these labels explicitly or add ', _' to the pattern.
13-
14-
152
We've found a bug for you!
163
/.../fixtures/dict_pattern_inference_constrained.res:4:27-30
174

185
2 ┆ switch dict {
19-
3 ┆ | @res.dictPattern {one: 1} =>
6+
3 ┆ | dict{"one": 1} =>
207
4 ┆ let _: dict<string> = dict
218
5 ┆ Js.log("one")
229
6 ┆ | _ => Js.log("not one")

jscomp/build_tests/super_errors/expected/dict_pattern_regular_record.res.expected

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,10 @@
11

2-
Warning number 9
3-
/.../fixtures/dict_pattern_regular_record.res:5:22-33
4-
5-
3 │ let constrainedAsDict = (dict: x) =>
6-
4 │ switch dict {
7-
5 │ | @res.dictPattern {one: "one"} => Js.log("one")
8-
6 │ | _ => Js.log("not one")
9-
7 │ }
10-
11-
the following labels are not bound in this record pattern: dictValuesType
12-
Either bind these labels explicitly or add ', _' to the pattern.
13-
14-
152
We've found a bug for you!
16-
/.../fixtures/dict_pattern_regular_record.res:5:22-33
3+
/.../fixtures/dict_pattern_regular_record.res:5:5-22
174

185
3 │ let constrainedAsDict = (dict: x) =>
196
4 │ switch dict {
20-
5 │ | @res.dictPattern {one: "one"} => Js.log("one")
7+
5 │ | dict{"one": "one"} => Js.log("one")
218
6 │ | _ => Js.log("not one")
229
7 │ }
2310

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
let foo = dict =>
22
switch dict {
3-
| @res.dictPattern {one: 1, two: "hello"} => Js.log("one")
3+
| dict{"one": 1, "two": "hello"} => Js.log("one")
44
| _ => Js.log("not one")
55
}

jscomp/build_tests/super_errors/fixtures/dict_pattern_inference_constrained.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
let foo = dict =>
22
switch dict {
3-
| @res.dictPattern {one: 1} =>
3+
| dict{"one": 1} =>
44
let _: dict<string> = dict
55
Js.log("one")
66
| _ => Js.log("not one")

jscomp/build_tests/super_errors/fixtures/dict_pattern_regular_record.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ type x = {one: int}
22

33
let constrainedAsDict = (dict: x) =>
44
switch dict {
5-
| @res.dictPattern {one: "one"} => Js.log("one")
5+
| dict{"one": "one"} => Js.log("one")
66
| _ => Js.log("not one")
77
}

jscomp/syntax/src/res_core.ml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,9 @@ let rec parse_pattern ?(alias = true) ?(or_ = true) p =
11271127
| List ->
11281128
Parser.next p;
11291129
parse_list_pattern ~start_pos ~attrs p
1130+
| Dict ->
1131+
Parser.next p;
1132+
parse_dict_pattern ~start_pos ~attrs p
11301133
| Module -> parse_module_pattern ~attrs p
11311134
| Percent ->
11321135
let extension = parse_extension p in
@@ -1397,6 +1400,29 @@ and parse_list_pattern ~start_pos ~attrs p =
13971400
let pat = make_list_pattern loc patterns None in
13981401
{pat with ppat_loc = loc; ppat_attributes = attrs}
13991402

1403+
and parse_dict_pattern_row p =
1404+
match p.Parser.token with
1405+
| String s ->
1406+
let loc = mk_loc p.start_pos p.end_pos in
1407+
Parser.next p;
1408+
let fieldName = Location.mkloc (Longident.Lident s) loc in
1409+
Parser.expect Colon p;
1410+
let optional = parse_optional_label p in
1411+
let pat = parse_pattern p in
1412+
Some (fieldName, make_pattern_optional ~optional pat)
1413+
| _ -> None
1414+
1415+
and parse_dict_pattern ~start_pos ~attrs (p : Parser.t) =
1416+
let fields =
1417+
parse_comma_delimited_region p ~grammar:DictRows ~closing:Rbrace
1418+
~f:parse_dict_pattern_row
1419+
in
1420+
Parser.expect Rbrace p;
1421+
let loc = mk_loc start_pos p.prev_end_pos in
1422+
Ast_helper.Pat.record ~loc
1423+
~attrs:((Location.mknoloc "res.dictPattern", PStr []) :: attrs)
1424+
fields Open
1425+
14001426
and parse_array_pattern ~attrs p =
14011427
let start_pos = p.start_pos in
14021428
Parser.expect Lbracket p;

jscomp/syntax/src/res_parsetree_viewer.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ let has_res_pat_variant_spread_attribute attrs =
105105
| _ -> false)
106106
attrs
107107

108+
let has_dict_pattern_attribute attrs =
109+
attrs
110+
|> List.find_opt (fun (({txt}, _) : Parsetree.attribute) ->
111+
txt = "res.dictPattern")
112+
|> Option.is_some
113+
108114
let collect_array_expressions expr =
109115
match expr.pexp_desc with
110116
| Pexp_array exprs -> (exprs, None)
@@ -228,7 +234,7 @@ let filter_parsing_attrs attrs =
228234
( "res.arity" | "res.braces" | "ns.braces" | "res.iflet"
229235
| "res.namedArgLoc" | "res.optional" | "res.ternary" | "res.async"
230236
| "res.await" | "res.template" | "res.taggedTemplate"
231-
| "res.patVariantSpread" );
237+
| "res.patVariantSpread" | "res.dictPattern" );
232238
},
233239
_ ) ->
234240
false

jscomp/syntax/src/res_parsetree_viewer.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ val process_function_attributes :
2828

2929
val has_await_attribute : Parsetree.attributes -> bool
3030
val has_res_pat_variant_spread_attribute : Parsetree.attributes -> bool
31+
val has_dict_pattern_attribute : Parsetree.attributes -> bool
3132

3233
type if_condition_kind =
3334
| If of Parsetree.expression

jscomp/syntax/src/res_printer.ml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,6 +2416,25 @@ and print_pattern ~state (p : Parsetree.pattern) cmt_tbl =
24162416
Doc.concat [Doc.text "..."; print_ident_path ident cmt_tbl]
24172417
| Ppat_type ident ->
24182418
Doc.concat [Doc.text "#..."; print_ident_path ident cmt_tbl]
2419+
| Ppat_record (rows, _)
2420+
when ParsetreeViewer.has_dict_pattern_attribute p.ppat_attributes ->
2421+
Doc.concat
2422+
[
2423+
Doc.text "dict{";
2424+
Doc.indent
2425+
(Doc.concat
2426+
[
2427+
Doc.soft_line;
2428+
Doc.join
2429+
~sep:(Doc.concat [Doc.text ","; Doc.line])
2430+
(List.map
2431+
(fun row -> print_pattern_dict_row ~state row cmt_tbl)
2432+
rows);
2433+
]);
2434+
Doc.if_breaks (Doc.text ",") Doc.nil;
2435+
Doc.soft_line;
2436+
Doc.rbrace;
2437+
]
24192438
| Ppat_record (rows, open_flag) ->
24202439
Doc.group
24212440
(Doc.concat
@@ -2582,6 +2601,36 @@ and print_pattern_record_row ~state row cmt_tbl =
25822601
in
25832602
print_comments doc cmt_tbl loc_for_comments
25842603

2604+
and print_pattern_dict_row ~state
2605+
(row : Longident.t Location.loc * Parsetree.pattern) cmt_tbl =
2606+
match row with
2607+
| longident, pattern ->
2608+
let loc_for_comments =
2609+
{longident.loc with loc_end = pattern.ppat_loc.loc_end}
2610+
in
2611+
let rhs_doc =
2612+
let doc = print_pattern ~state pattern cmt_tbl in
2613+
let doc =
2614+
if Parens.pattern_record_row_rhs pattern then add_parens doc else doc
2615+
in
2616+
Doc.concat [print_optional_label pattern.ppat_attributes; doc]
2617+
in
2618+
let lbl_doc =
2619+
Doc.concat [Doc.text "\""; print_longident longident.txt; Doc.text "\""]
2620+
in
2621+
let doc =
2622+
Doc.group
2623+
(Doc.concat
2624+
[
2625+
lbl_doc;
2626+
Doc.text ":";
2627+
(if ParsetreeViewer.is_huggable_pattern pattern then
2628+
Doc.concat [Doc.space; rhs_doc]
2629+
else Doc.indent (Doc.concat [Doc.line; rhs_doc]));
2630+
])
2631+
in
2632+
print_comments doc cmt_tbl loc_for_comments
2633+
25852634
and print_expression_with_comments ~state expr cmt_tbl : Doc.t =
25862635
let doc = print_expression ~state expr cmt_tbl in
25872636
print_comments doc cmt_tbl expr.Parsetree.pexp_loc

0 commit comments

Comments
 (0)