@@ -1530,8 +1530,62 @@ let transform_jsx_call ~config mapper call_expression call_arguments
1530
1530
" JSX: `createElement` should be preceeded by a simple, direct module \
1531
1531
name."
1532
1532
1533
- let expr ~config mapper expression =
1533
+ let expr ~( config : Jsx_common.jsx_config ) mapper expression =
1534
1534
match expression with
1535
+ | {
1536
+ pexp_desc = Pexp_jsx_fragment (_, xs, _);
1537
+ pexp_loc = loc;
1538
+ pexp_attributes = attrs;
1539
+ } ->
1540
+ let loc = {loc with loc_ghost = true } in
1541
+ let fragment =
1542
+ match config.mode with
1543
+ | "automatic" ->
1544
+ Exp. ident ~loc {loc; txt = module_access_name config " jsxFragment" }
1545
+ | "classic" | _ ->
1546
+ Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " fragment" )}
1547
+ in
1548
+ let record_of_children children =
1549
+ Exp. record [(Location. mknoloc (Lident " children" ), children, false )] None
1550
+ in
1551
+ let apply_jsx_array expr =
1552
+ Exp. apply
1553
+ (Exp. ident
1554
+ {txt = module_access_name config " array" ; loc = Location. none})
1555
+ [(Nolabel , expr)]
1556
+ in
1557
+ let children_props =
1558
+ match xs with
1559
+ | [] -> empty_record ~loc: Location. none
1560
+ | [child] -> record_of_children (mapper.expr mapper child)
1561
+ | _ -> (
1562
+ match config.mode with
1563
+ | "automatic" ->
1564
+ record_of_children
1565
+ @@ apply_jsx_array (Exp. array (List. map (mapper.expr mapper) xs))
1566
+ | "classic" | _ -> empty_record ~loc: Location. none)
1567
+ in
1568
+ let args =
1569
+ (nolabel, fragment) :: (nolabel, children_props)
1570
+ ::
1571
+ (match config.mode with
1572
+ | "classic" when List. length xs > 1 ->
1573
+ [(nolabel, Exp. array (List. map (mapper.expr mapper) xs))]
1574
+ | _ -> [] )
1575
+ in
1576
+ Exp. apply ~loc ~attrs
1577
+ (* ReactDOM.createElement *)
1578
+ (match config.mode with
1579
+ | "automatic" ->
1580
+ if List. length xs > 1 then
1581
+ Exp. ident ~loc {loc; txt = module_access_name config " jsxs" }
1582
+ else Exp. ident ~loc {loc; txt = module_access_name config " jsx" }
1583
+ | "classic" | _ ->
1584
+ if List. length xs > 1 then
1585
+ Exp. ident ~loc
1586
+ {loc; txt = Ldot (Lident " React" , " createElementVariadic" )}
1587
+ else Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " createElement" )})
1588
+ args
1535
1589
(* Does the function application have the @JSX attribute? *)
1536
1590
| {
1537
1591
pexp_desc = Pexp_apply {funct = call_expression; args = call_arguments};
@@ -1549,87 +1603,6 @@ let expr ~config mapper expression =
1549
1603
| _ , non_jsx_attributes ->
1550
1604
transform_jsx_call ~config mapper call_expression call_arguments pexp_loc
1551
1605
non_jsx_attributes)
1552
- (* is it a list with jsx attribute? Reason <>foo</> desugars to [@JSX][foo]*)
1553
- | {
1554
- pexp_desc =
1555
- ( Pexp_construct
1556
- ({txt = Lident " ::" ; loc}, Some {pexp_desc = Pexp_tuple _})
1557
- | Pexp_construct ({txt = Lident " []" ; loc}, None ) );
1558
- pexp_attributes;
1559
- } as list_items -> (
1560
- let jsx_attribute, non_jsx_attributes =
1561
- List. partition
1562
- (fun (attribute , _ ) -> attribute.txt = " JSX" )
1563
- pexp_attributes
1564
- in
1565
- match (jsx_attribute, non_jsx_attributes) with
1566
- (* no JSX attribute *)
1567
- | [] , _ -> default_mapper.expr mapper expression
1568
- | _ , non_jsx_attributes ->
1569
- let loc = {loc with loc_ghost = true } in
1570
- let fragment =
1571
- match config.mode with
1572
- | "automatic" ->
1573
- Exp. ident ~loc {loc; txt = module_access_name config " jsxFragment" }
1574
- | "classic" | _ ->
1575
- Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " fragment" )}
1576
- in
1577
- let children_expr = transform_children_if_list ~mapper list_items in
1578
- let record_of_children children =
1579
- Exp. record
1580
- [(Location. mknoloc (Lident " children" ), children, false )]
1581
- None
1582
- in
1583
- let apply_jsx_array expr =
1584
- Exp. apply
1585
- (Exp. ident
1586
- {txt = module_access_name config " array" ; loc = Location. none})
1587
- [(Nolabel , expr)]
1588
- in
1589
- let count_of_children = function
1590
- | {pexp_desc = Pexp_array children } -> List. length children
1591
- | _ -> 0
1592
- in
1593
- let transform_children_to_props children_expr =
1594
- match children_expr with
1595
- | {pexp_desc = Pexp_array children } -> (
1596
- match children with
1597
- | [] -> empty_record ~loc: Location. none
1598
- | [child] -> record_of_children child
1599
- | _ -> (
1600
- match config.mode with
1601
- | "automatic" -> record_of_children @@ apply_jsx_array children_expr
1602
- | "classic" | _ -> empty_record ~loc: Location. none))
1603
- | _ -> (
1604
- match config.mode with
1605
- | "automatic" -> record_of_children @@ apply_jsx_array children_expr
1606
- | "classic" | _ -> empty_record ~loc: Location. none)
1607
- in
1608
- let args =
1609
- (nolabel, fragment)
1610
- :: (nolabel, transform_children_to_props children_expr)
1611
- ::
1612
- (match config.mode with
1613
- | "classic" when count_of_children children_expr > 1 ->
1614
- [(nolabel, children_expr)]
1615
- | _ -> [] )
1616
- in
1617
- Exp. apply
1618
- ~loc (* throw away the [@JSX] attribute and keep the others, if any *)
1619
- ~attrs: non_jsx_attributes
1620
- (* ReactDOM.createElement *)
1621
- (match config.mode with
1622
- | "automatic" ->
1623
- if count_of_children children_expr > 1 then
1624
- Exp. ident ~loc {loc; txt = module_access_name config " jsxs" }
1625
- else Exp. ident ~loc {loc; txt = module_access_name config " jsx" }
1626
- | "classic" | _ ->
1627
- if count_of_children children_expr > 1 then
1628
- Exp. ident ~loc
1629
- {loc; txt = Ldot (Lident " React" , " createElementVariadic" )}
1630
- else
1631
- Exp. ident ~loc {loc; txt = Ldot (Lident " React" , " createElement" )})
1632
- args)
1633
1606
(* Delegate to the default mapper, a deep identity traversal *)
1634
1607
| e -> default_mapper.expr mapper e
1635
1608
0 commit comments