@@ -1543,6 +1543,68 @@ let _starts_with_uppercase s =
15431543 Char. uppercase_ascii c = c
15441544
15451545module AutomaticExpr = struct
1546+ let loc_from_prop = function
1547+ | JSXPropPunning (_ , {loc} ) -> loc
1548+ | JSXPropValue (_ , _ , {pexp_loc} ) -> pexp_loc
1549+ | JSXPropSpreading (loc , _ ) -> loc
1550+
1551+ let mk_record_from_props (jsx_expr_loc : Location.t ) (props : jsx_props ) :
1552+ expression =
1553+ (* Create an artificial range from the first till the last prop *)
1554+ let loc =
1555+ match props with
1556+ | [] -> jsx_expr_loc
1557+ | head :: tail ->
1558+ let rec visit props =
1559+ match props with
1560+ | [] -> head
1561+ | [last] -> last
1562+ | _ :: rest -> visit rest
1563+ in
1564+ let first_item = head |> loc_from_prop in
1565+ let last_item = visit tail |> loc_from_prop in
1566+ {
1567+ loc_start = first_item.loc_start;
1568+ loc_end = last_item.loc_end;
1569+ loc_ghost = true ;
1570+ }
1571+ in
1572+ (* key should be filtered out *)
1573+ let props =
1574+ props
1575+ |> List. filter (function
1576+ | JSXPropPunning (_, {txt = " key" })
1577+ | JSXPropValue ({txt = "key" } , _ , _ ) ->
1578+ false
1579+ | _ -> true )
1580+ in
1581+ let props, spread_props =
1582+ match props with
1583+ | JSXPropSpreading (_ , expr ) :: rest -> (rest, Some expr)
1584+ | _ -> (props, None )
1585+ in
1586+
1587+ let record_fields =
1588+ props
1589+ |> List. map (function
1590+ | JSXPropPunning (is_optional , name ) ->
1591+ ( {txt = Lident name.txt; loc = name.loc},
1592+ Exp. ident {txt = Lident name.txt; loc = name.loc},
1593+ is_optional )
1594+ | JSXPropValue (name , is_optional , value ) ->
1595+ ({txt = Lident name.txt; loc = name.loc}, value, is_optional)
1596+ | JSXPropSpreading (loc , _ ) ->
1597+ (* There can only be one spread expression and it is expected to be the first prop *)
1598+ Jsx_common. raise_error ~loc
1599+ " JSX: use {...p} {x: v} not {x: v} {...p} \n \
1600+ \ multiple spreads {...p} {...p} not allowed." )
1601+ in
1602+ {
1603+ pexp_desc = Pexp_record (record_fields, spread_props);
1604+ pexp_loc = loc;
1605+ pexp_attributes = [] ;
1606+ }
1607+
15461608 let mk_children_props (config : Jsx_common.jsx_config ) mapper
15471609 (children : jsx_children ) =
15481610 let record_of_children children =
@@ -1628,8 +1690,7 @@ module AutomaticExpr = struct
16281690 {loc = Location. none; txt = Ldot (element_binding, " jsxKeyed" )},
16291691 [key_prop; (nolabel, unit_expr ~loc: Location. none)] )
16301692 in
1631- (* TODO *)
1632- let props = empty_record ~loc in
1693+ let props = mk_record_from_props loc props in
16331694
16341695 Exp. apply ~loc ~attrs jsx_expr
16351696 ([(nolabel, component_name_expr); (nolabel, props)] @ key_and_unit)
0 commit comments