Skip to content

Commit

Permalink
Parse list and list spread in JSX
Browse files Browse the repository at this point in the history
fixes #1467
  • Loading branch information
anmonteiro committed May 29, 2018
1 parent 102442d commit aeebd5a
Show file tree
Hide file tree
Showing 7 changed files with 2,918 additions and 2,586 deletions.
9 changes: 9 additions & 0 deletions formatTest/typeCheckedTests/expected_output/jsx.re
Original file line number Diff line number Diff line change
Expand Up @@ -553,3 +553,12 @@ let div = (~onClick, ~children, ()) => ();
<div onClick=onClickHandler>
<> "foobar" </>
</div>;

/* https://github.com/facebook/reason/issues/1467 */
<Foo> 1 2 </Foo>;

<Foo> 1 2 3 4 </Foo>;

<Foo> <> 1 2 3 4 </> </Foo>;

<Foo> <> 1 2 3 </> </Foo>;
9 changes: 9 additions & 0 deletions formatTest/typeCheckedTests/input/jsx.re
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,12 @@ let onClickHandler = () => ();
let div = (~onClick, ~children, ()) => ();

<div onClick=onClickHandler> <> "foobar" </> </div>;

/* https://github.com/facebook/reason/issues/1467 */
<Foo> ...[1, 2] </Foo>;

<Foo> [1, 2] [3,4] </Foo>;

<Foo> <> [1, 2] [3,4] </> </Foo>;

<Foo> <> ...[1, 2, 3] </> </Foo>;
2 changes: 2 additions & 0 deletions formatTest/unit_tests/expected_output/jsx.re
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,5 @@ let x = foo /></ bar;
<div onClick=this##handleClick>
<> foo bar </>
</div>;

<Foo> 1 2 other </Foo>;
2 changes: 2 additions & 0 deletions formatTest/unit_tests/input/jsx.re
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,5 @@ let x = foo /></ bar;
<div onClick=this##handleClick>
<> foo(bar) </>
</div>;

<Foo> ...[[1,2] , other] </Foo>;
5,414 changes: 2,836 additions & 2,578 deletions src/reason-parser/reason_parser.messages.checked-in

Large diffs are not rendered by default.

64 changes: 58 additions & 6 deletions src/reason-parser/reason_parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,11 @@ let raise_record_trailing_semi_error loc =
let msg = "Record entries are separated by comma; we've found a semicolon instead." in
raise Reason_syntax_util.(Error(loc, (Syntax_error msg)))

let mklist lst startp endp =
let seq, ext_opt = lst in
let loc = mklocation startp endp in
make_real_exp (mktailexp_extension loc seq ext_opt)

%}


Expand Down Expand Up @@ -2618,12 +2623,30 @@ jsx_start_tag_and_args_without_leading_less:
(jsx_component lident $2, lident) }
;

jsx_expr_list:
LBRACKET expr_comma_seq_extension RBRACKET
{ mklist $2 $startpos($2) $endpos($2) }

jsx_children_including_list:
| simple_expr_no_call { $1 }
| jsx_expr_list { $1 }

jsx:
| LESSGREATER simple_expr_no_call* LESSSLASHGREATER
{ let loc = mklocation $symbolstartpos $endpos in
let body = mktailexp_extension loc $2 None in
makeFrag loc body
}
| LESSGREATER jsx_expr_list+ LESSSLASHGREATER
{ let loc = mklocation $symbolstartpos $endpos in
let body = mktailexp_extension loc $2 None in
makeFrag loc body
}
| LESSGREATER DOTDOTDOT jsx_children_including_list LESSSLASHGREATER
{ let loc = mklocation $symbolstartpos $endpos in
let body = $3 (*mktailexp_extension loc $3 None*) in
makeFrag loc body
}
| jsx_start_tag_and_args SLASHGREATER
{ let (component, _) = $1 in
let loc = mklocation $symbolstartpos $endpos in
Expand All @@ -2644,7 +2667,18 @@ jsx:
(Nolabel, mkexp_constructor_unit loc loc)
] loc
}
| jsx_start_tag_and_args GREATER DOTDOTDOT simple_expr_no_call LESSSLASHIDENTGREATER
| jsx_start_tag_and_args GREATER jsx_expr_list+ LESSSLASHIDENTGREATER
{ let (component, start) = $1 in
let loc = mklocation $symbolstartpos $endpos in
(* TODO: Make this tag check simply a warning *)
let endName = Longident.parse $4 in
let _ = ensureTagsAreEqual start endName loc in
component [
(Labelled "children", mktailexp_extension loc $3 None);
(Nolabel, mkexp_constructor_unit loc loc)
] loc
}
| jsx_start_tag_and_args GREATER DOTDOTDOT jsx_children_including_list LESSSLASHIDENTGREATER
(* <Foo> ...bar </Foo> or <Foo> ...((a) => 1) </Foo> *)
{ let (component, start) = $1 in
let loc = mklocation $symbolstartpos $endpos in
Expand All @@ -2665,6 +2699,16 @@ jsx_without_leading_less:
let body = mktailexp_extension loc $2 None in
makeFrag loc body
}
| GREATER jsx_expr_list+ LESSSLASHGREATER
{ let loc = mklocation $symbolstartpos $endpos in
let body = mktailexp_extension loc $2 None in
makeFrag loc body
}
| GREATER DOTDOTDOT jsx_children_including_list LESSSLASHGREATER
{ let loc = mklocation $symbolstartpos $endpos in
let body = $3 (*mktailexp_extension loc $3 None*) in
makeFrag loc body
}
| jsx_start_tag_and_args_without_leading_less SLASHGREATER {
let (component, _) = $1 in
let loc = mklocation $symbolstartpos $endpos in
Expand All @@ -2685,7 +2729,18 @@ jsx_without_leading_less:
(Nolabel, mkexp_constructor_unit loc loc)
] loc
}
| jsx_start_tag_and_args_without_leading_less GREATER DOTDOTDOT simple_expr_no_call LESSSLASHIDENTGREATER {
| jsx_start_tag_and_args_without_leading_less GREATER jsx_expr_list+ LESSSLASHIDENTGREATER
{ let (component, start) = $1 in
let loc = mklocation $symbolstartpos $endpos in
(* TODO: Make this tag check simply a warning *)
let endName = Longident.parse $4 in
let _ = ensureTagsAreEqual start endName loc in
component [
(Labelled "children", mktailexp_extension loc $3 None);
(Nolabel, mkexp_constructor_unit loc loc)
] loc
}
| jsx_start_tag_and_args_without_leading_less GREATER DOTDOTDOT jsx_children_including_list LESSSLASHIDENTGREATER {
let (component, start) = $1 in
let loc = mklocation $symbolstartpos $endpos in
(* TODO: Make this tag check simply a warning *)
Expand Down Expand Up @@ -3034,10 +3089,7 @@ simple_expr_call:
{ let (body, args) = $1 in
(body, List.rev_append $2 args) }
| LBRACKET expr_comma_seq_extension RBRACKET
{ let seq, ext_opt = $2 in
let loc = mklocation $startpos($2) $endpos($2) in
(make_real_exp (mktailexp_extension loc seq ext_opt), [])
}
{ (mklist $2 $startpos($2) $endpos($2), []) }
| simple_expr_template_constructor { ($1, []) }
;

Expand Down
4 changes: 2 additions & 2 deletions src/reason-parser/reason_pprint_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5637,9 +5637,9 @@ let printer = object(self:'self)
| ({txt="JSX"; loc}, PStr []) :: _ ->
begin match self#simplest_expression x with
| Some r -> self#formatChildren remaining (r :: processedRev)
| None -> self#formatChildren (remaining @ children) processedRev
| None -> self#formatChildren (children @ remaining) processedRev
end
| _ -> self#formatChildren (remaining @ children) processedRev
| _ -> self#formatChildren (children @ remaining) processedRev
end
| {pexp_desc = Pexp_apply(expr, l); pexp_attributes} :: remaining ->
self#formatChildren remaining (self#simplifyUnparseExpr (List.hd children) :: processedRev)
Expand Down

0 comments on commit aeebd5a

Please sign in to comment.