Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#### :boom: Breaking Change

- Fix return type of `String.charCodeAt`. https://github.com/rescript-lang/rescript/pull/7864
- Remove support of JSX children spread. https://github.com/rescript-lang/rescript/pull/7869

#### :eyeglasses: Spec Compliance

Expand Down
5 changes: 2 additions & 3 deletions analysis/src/CompletionFrontEnd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
(Jsx_container_element
{jsx_container_element_children = children}) ->
children
| _ -> JSXChildrenItems []
| _ -> []
in
let compName_loc = compName.loc in
let compName_lid =
Expand Down Expand Up @@ -1412,8 +1412,7 @@ let completionWithParser1 ~currentFile ~debug ~offset ~path ~posCursor
(Jsx_container_element
{
jsx_container_element_closing_tag = None;
jsx_container_element_children =
JSXChildrenSpreading _ | JSXChildrenItems (_ :: _);
jsx_container_element_children = _ :: _;
}) ) ->
None
| Some jsxProps, _ ->
Expand Down
4 changes: 2 additions & 2 deletions analysis/src/CompletionJsx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ let extractJsxProps ~(compName : Longident.t Location.loc) ~props ~children =
let open Parsetree in
let childrenStart =
match children with
| JSXChildrenItems [] -> None
| JSXChildrenSpreading child | JSXChildrenItems (child :: _) ->
| [] -> None
| child :: _ ->
if child.pexp_loc.loc_ghost then None else Some (Loc.start child.pexp_loc)
in
let props =
Expand Down
5 changes: 1 addition & 4 deletions analysis/src/SemanticTokens.ml
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,7 @@ let command ~debug ~emitter ~path =
~pos:(Pos.ofLexing posOfGreatherthanAfterProps);

(* children *)
(match children with
| Parsetree.JSXChildrenSpreading child -> iterator.expr iterator child
| Parsetree.JSXChildrenItems children ->
List.iter (iterator.expr iterator) children);
List.iter (iterator.expr iterator) children;

(* closing tag *)
closing_tag_opt
Expand Down
4 changes: 1 addition & 3 deletions compiler/frontend/bs_ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,7 @@ module M = struct
end

module E = struct
let map_jsx_children sub = function
| JSXChildrenSpreading e -> JSXChildrenSpreading (sub.expr sub e)
| JSXChildrenItems xs -> JSXChildrenItems (List.map (sub.expr sub) xs)
let map_jsx_children sub xs = List.map (sub.expr sub) xs

let map_jsx_prop sub = function
| JSXPropPunning (optional, name) ->
Expand Down
4 changes: 1 addition & 3 deletions compiler/ml/ast_iterator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,7 @@ module M = struct
end

module E = struct
let iter_jsx_children sub = function
| JSXChildrenSpreading e -> sub.expr sub e
| JSXChildrenItems xs -> List.iter (sub.expr sub) xs
let iter_jsx_children sub xs = List.iter (sub.expr sub) xs

let iter_jsx_prop sub = function
| JSXPropPunning (_, name) -> iter_loc sub name
Expand Down
4 changes: 1 addition & 3 deletions compiler/ml/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,7 @@ module M = struct
end

module E = struct
let map_jsx_children sub = function
| JSXChildrenSpreading e -> JSXChildrenSpreading (sub.expr sub e)
| JSXChildrenItems xs -> JSXChildrenItems (List.map (sub.expr sub) xs)
let map_jsx_children sub xs = List.map (sub.expr sub) xs

let map_jsx_prop sub = function
| JSXPropPunning (optional, name) ->
Expand Down
4 changes: 2 additions & 2 deletions compiler/ml/ast_mapper_from0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ module E = struct
match e.pexp_desc with
| Pexp_construct ({txt = Longident.Lident "[]" | Longident.Lident "::"}, _)
->
JSXChildrenItems (visit e)
| _ -> JSXChildrenSpreading (sub.expr sub e)
visit e
| _ -> [sub.expr sub e]

let try_map_jsx_prop (sub : mapper) (lbl : Asttypes.Noloc.arg_label)
(e : expression) : Parsetree.jsx_prop option =
Expand Down
3 changes: 1 addition & 2 deletions compiler/ml/ast_mapper_to0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,7 @@ module E = struct

let map_jsx_children sub loc children =
match children with
| JSXChildrenSpreading e -> sub.expr sub e
| JSXChildrenItems xs ->
| xs ->
let list_expr = Ast_helper.Exp.make_list_expression loc xs None in
sub.expr sub list_expr

Expand Down
4 changes: 1 addition & 3 deletions compiler/ml/depend.ml
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,7 @@ let rec add_expr bv exp =
and_jsx_props bv props;
add_jsx_children bv children

and add_jsx_children bv = function
| JSXChildrenSpreading e -> add_expr bv e
| JSXChildrenItems xs -> List.iter (add_expr bv) xs
and add_jsx_children bv xs = List.iter (add_expr bv) xs

and add_jsx_prop bv = function
| JSXPropPunning (_, _) -> ()
Expand Down
4 changes: 1 addition & 3 deletions compiler/ml/parsetree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,7 @@ and jsx_prop =
Location.t
* expression

and jsx_children =
| JSXChildrenSpreading of expression
| JSXChildrenItems of expression list
and jsx_children = expression list

and jsx_props = jsx_prop list

Expand Down
14 changes: 3 additions & 11 deletions compiler/ml/pprintast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ and simple_expr ctxt f x =
pp f fmt (pattern ctxt) s expression e1 direction_flag df expression e2
expression e3
| Pexp_jsx_element (Jsx_fragment {jsx_fragment_children = children}) ->
pp f "<>%a</>" (list (simple_expr ctxt)) (collect_jsx_children children)
pp f "<>%a</>" (list (simple_expr ctxt)) children
| Pexp_jsx_element
(Jsx_unary_element
{
Expand Down Expand Up @@ -828,21 +828,13 @@ and simple_expr ctxt f x =
in
match props with
| [] ->
pp f "<%s>%a%s" name
(list (simple_expr ctxt))
(collect_jsx_children children)
closing_name
pp f "<%s>%a%s" name (list (simple_expr ctxt)) children closing_name
| _ ->
pp f "<%s %a>%a%s" name (print_jsx_props ctxt) props
(list (simple_expr ctxt))
(collect_jsx_children children)
closing_name)
children closing_name)
| _ -> paren true (expression ctxt) f x

and collect_jsx_children = function
| JSXChildrenSpreading e -> [e]
| JSXChildrenItems xs -> xs

and print_jsx_prop ctxt f = function
| JSXPropPunning (is_optional, name) ->
pp f "%s" (if is_optional then "?" ^ name.txt else name.txt)
Expand Down
4 changes: 1 addition & 3 deletions compiler/ml/printast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,7 @@ and expression i ppf x =

and jsx_children i ppf children =
line i ppf "jsx_children =\n";
match children with
| JSXChildrenSpreading e -> expression (i + 1) ppf e
| JSXChildrenItems xs -> list (i + 1) expression ppf xs
list (i + 1) expression ppf children

and jsx_prop i ppf = function
| JSXPropPunning (opt, name) ->
Expand Down
16 changes: 6 additions & 10 deletions compiler/syntax/src/jsx_v4.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1182,8 +1182,8 @@ let append_children_prop (config : Jsx_common.jsx_config) mapper
(component_description : componentDescription) (props : jsx_props)
(children : jsx_children) : jsx_props =
match children with
| JSXChildrenItems [] -> props
| JSXChildrenItems [child] | JSXChildrenSpreading child ->
| [] -> props
| [child] ->
let expr =
(* I don't quite know why fragment and uppercase don't do this additional ReactDOM.someElement wrapping *)
match component_description with
Expand All @@ -1209,7 +1209,7 @@ let append_children_prop (config : Jsx_common.jsx_config) mapper
JSXPropValue
({txt = "children"; loc = child.pexp_loc}, is_optional, expr);
]
| JSXChildrenItems (head :: _ as xs) ->
| head :: _ as xs ->
let loc =
match List.rev xs with
| [] -> head.pexp_loc
Expand All @@ -1230,11 +1230,7 @@ let append_children_prop (config : Jsx_common.jsx_config) mapper
let mk_react_jsx (config : Jsx_common.jsx_config) mapper loc attrs
(component_description : componentDescription) (elementTag : expression)
(props : jsx_props) (children : jsx_children) : expression =
let more_than_one_children =
match children with
| JSXChildrenSpreading _ -> false
| JSXChildrenItems xs -> List.length xs > 1
in
let more_than_one_children = List.length children > 1 in
let props_with_children =
append_children_prop config mapper component_description props children
in
Expand Down Expand Up @@ -1314,12 +1310,12 @@ let expr ~(config : Jsx_common.jsx_config) mapper expression =
(* For example 'input' *)
let component_name_expr = constant_string ~loc:tag_loc name in
mk_react_jsx config mapper loc attrs LowercasedComponent
component_name_expr props (JSXChildrenItems [])
component_name_expr props []
| JsxUpperTag _ | JsxQualifiedLowerTag _ ->
(* MyModule.make *)
let make_id = mk_uppercase_tag_name_expr tag_name in
mk_react_jsx config mapper loc attrs UppercasedComponent make_id props
(JSXChildrenItems [])
[]
| JsxTagInvalid name ->
Jsx_common.raise_error ~loc
"JSX: element name is neither upper- or lowercase, got \"%s\"" name)
Expand Down
14 changes: 2 additions & 12 deletions compiler/syntax/src/res_ast_debugger.ml
Original file line number Diff line number Diff line change
Expand Up @@ -707,12 +707,7 @@ module SexpAst = struct
| Pexp_extension ext ->
Sexp.list [Sexp.atom "Pexp_extension"; extension ext]
| Pexp_await e -> Sexp.list [Sexp.atom "Pexp_await"; expression e]
| Pexp_jsx_element (Jsx_fragment {jsx_fragment_children = children}) ->
let xs =
match children with
| JSXChildrenSpreading e -> [e]
| JSXChildrenItems xs -> xs
in
| Pexp_jsx_element (Jsx_fragment {jsx_fragment_children = xs}) ->
Sexp.list
[
Sexp.atom "Pexp_jsx_fragment"; Sexp.list (map_empty ~f:expression xs);
Expand All @@ -728,13 +723,8 @@ module SexpAst = struct
(Jsx_container_element
{
jsx_container_element_props = props;
jsx_container_element_children = children;
jsx_container_element_children = xs;
}) ->
let xs =
match children with
| JSXChildrenSpreading e -> [e]
| JSXChildrenItems xs -> xs
in
Sexp.list
[
Sexp.atom "Pexp_jsx_container_element";
Expand Down
15 changes: 3 additions & 12 deletions compiler/syntax/src/res_comments_table.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1658,12 +1658,7 @@ and walk_expression expr t comments =
let opening_token = {expr.pexp_loc with loc_end = opening_greater_than} in
let on_same_line, rest = partition_by_on_same_line opening_token comments in
attach t.trailing opening_token on_same_line;
let exprs =
match children with
| Parsetree.JSXChildrenSpreading e -> [e]
| Parsetree.JSXChildrenItems xs -> xs
in
let xs = exprs |> List.map (fun e -> Expression e) in
let xs = children |> List.map (fun e -> Expression e) in
walk_list xs t rest
| Pexp_jsx_element
(Jsx_unary_element
Expand Down Expand Up @@ -1769,7 +1764,7 @@ and walk_expression expr t comments =
partition_leading_trailing rest closing_tag_loc
in
match children with
| Parsetree.JSXChildrenItems [] -> (
| [] -> (
(* attach all comments to the closing tag if there are no children *)
match closing_tag with
| None ->
Expand Down Expand Up @@ -1801,11 +1796,7 @@ and walk_expression expr t comments =
(* if the closing tag is on the same line, attach comments to the opening tag *)
attach t.leading closing_tag_loc comments_for_children)
| children ->
let children_nodes =
match children with
| Parsetree.JSXChildrenSpreading e -> [Expression e]
| Parsetree.JSXChildrenItems xs -> List.map (fun e -> Expression e) xs
in
let children_nodes = List.map (fun e -> Expression e) children in

walk_list children_nodes t comments_for_children
(* It is less likely that there are comments inside the closing tag,
Expand Down
14 changes: 1 addition & 13 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2999,19 +2999,7 @@ and parse_jsx_children p : Parsetree.jsx_children =
loop p (child :: children)
| _ -> children
in
let children =
match p.Parser.token with
| DotDotDot ->
Parser.next p;
let expr =
parse_primary_expr ~operand:(parse_atomic_expr p) ~no_call:true p
in
Parsetree.JSXChildrenSpreading expr
| _ ->
let children = List.rev (loop p []) in
Parsetree.JSXChildrenItems children
in
children
List.rev (loop p [])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tsnobip inside the loop you probably want to match ... and give a better parse error.


and parse_braced_or_record_expr p =
let start_pos = p.Parser.start_pos in
Expand Down
34 changes: 15 additions & 19 deletions compiler/syntax/src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4516,8 +4516,8 @@ and print_jsx_container_tag ~state tag_name
(* <div className="test" /> *)
let has_children =
match children with
| JSXChildrenSpreading _ | JSXChildrenItems (_ :: _) -> true
| JSXChildrenItems [] -> false
| _ :: _ -> true
| [] -> false
in
let line_sep = get_line_sep_for_jsx_children children in
let print_children children =
Expand Down Expand Up @@ -4606,8 +4606,8 @@ and print_jsx_fragment ~state (opening_greater_than : Lexing.position)
in
let has_children =
match children with
| JSXChildrenItems [] -> false
| JSXChildrenSpreading _ | JSXChildrenItems (_ :: _) -> true
| [] -> false
| _ :: _ -> true
in
let line_sep = get_line_sep_for_jsx_children children in
Doc.group
Expand All @@ -4621,18 +4621,15 @@ and print_jsx_fragment ~state (opening_greater_than : Lexing.position)
])

and get_line_sep_for_jsx_children (children : Parsetree.jsx_children) =
match children with
| JSXChildrenSpreading _ -> Doc.line
| JSXChildrenItems children ->
if
List.length children > 1
|| List.exists
(function
| {Parsetree.pexp_desc = Pexp_jsx_element _} -> true
| _ -> false)
children
then Doc.hard_line
else Doc.line
if
List.length children > 1
|| List.exists
(function
| {Parsetree.pexp_desc = Pexp_jsx_element _} -> true
| _ -> false)
children
then Doc.hard_line
else Doc.line

and print_jsx_children ~state (children : Parsetree.jsx_children) cmt_tbl =
let open Parsetree in
Expand Down Expand Up @@ -4669,9 +4666,8 @@ and print_jsx_children ~state (children : Parsetree.jsx_children) cmt_tbl =
print_comments (add_parens_or_braces expr_doc) cmt_tbl braces_loc
in
match children with
| JSXChildrenItems [] -> Doc.nil
| JSXChildrenSpreading child -> Doc.concat [Doc.dotdotdot; print_expr child]
| JSXChildrenItems children ->
| [] -> Doc.nil
| children ->
let rec visit acc children =
match children with
| [] -> acc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,3 @@ let handleClick = (href, event) =>
@react.component
let make = (~href, ~className="", ~children) =>
<a href className onClick={event => handleClick(href, event)}> children </a>

<Animated> ...{x => <div />} </Animated>

<div> ...element </div>
<div> ...{a => 1} </div>
<div> ...<span /> </div>
<div> ...[a, b] </div>
<div> ...{(1, 2)} </div>
8 changes: 0 additions & 8 deletions tests/syntax_tests/data/conversion/reason/jsxProps.res
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,3 @@ let handleClick = (href, event) =>
@react.component
let make = (~href, ~className="", ~children) =>
<a href className onClick={event => handleClick(href, event)}> children </a>

<Animated> ...{x => <div />} </Animated>

<div> ...element </div>
<div> ...{a => 1} </div>
<div> ...<span /> </div>
<div> ...[a, b] </div>
<div> ...{(1, 2)} </div>
Loading
Loading