@@ -25,6 +25,19 @@ open Ast_helper
2525open Location
2626module Pt = Parsetree
2727
28+ let jsx_prop_loc_attr = " res.jsxPropLoc"
29+ let jsx_spread_loc_attr = " res.jsxSpreadLoc"
30+
31+ let extract_internal_loc_attr attr_name attrs =
32+ let rec loop rev_acc = function
33+ | [] -> (None , List. rev rev_acc)
34+ | (({txt; loc} , payload ) as attr ) :: rest ->
35+ if txt = attr_name && payload = PStr [] then
36+ (Some loc, List. rev_append rev_acc rest)
37+ else loop (attr :: rev_acc) rest
38+ in
39+ loop [] attrs
40+
2841type mapper = {
2942 attribute : mapper -> attribute -> Pt .attribute ;
3043 attributes : mapper -> attribute list -> Pt .attribute list ;
@@ -331,9 +344,22 @@ module E = struct
331344
332345 let try_map_jsx_prop (sub : mapper ) (lbl : Asttypes.Noloc.arg_label )
333346 (e : expression ) : Parsetree.jsx_prop option =
347+ let map_expr_with_loc_attr attr_name fallback make_prop =
348+ let loc, attrs = extract_internal_loc_attr attr_name e.pexp_attributes in
349+ let e = {e with pexp_attributes = attrs} in
350+ let expr = sub.expr sub e in
351+ make_prop
352+ (match loc with
353+ | Some loc -> loc
354+ | None -> fallback expr)
355+ expr
356+ in
334357 match (lbl, e) with
335- | Asttypes.Noloc. Labelled "_spreadProps" , expr ->
336- Some (Parsetree. JSXPropSpreading (Location. none, sub.expr sub expr))
358+ | Asttypes.Noloc. Labelled "_spreadProps" , _expr ->
359+ Some
360+ (map_expr_with_loc_attr jsx_spread_loc_attr
361+ (fun expr -> expr.pexp_loc)
362+ (fun loc expr -> Parsetree. JSXPropSpreading (loc, expr)))
337363 | ( Asttypes.Noloc. Labelled name,
338364 {pexp_desc = Pexp_ident {txt = Longident. Lident v}; pexp_loc = name_loc}
339365 )
@@ -344,14 +370,18 @@ module E = struct
344370 )
345371 when name = v ->
346372 Some (Parsetree. JSXPropPunning (true , {txt = name; loc = name_loc}))
347- | Asttypes.Noloc. Labelled name , exp ->
373+ | Asttypes.Noloc. Labelled name , _exp ->
348374 Some
349- (Parsetree. JSXPropValue
350- ({txt = name; loc = Location. none}, false , sub.expr sub exp))
351- | Asttypes.Noloc. Optional name , exp ->
375+ (map_expr_with_loc_attr jsx_prop_loc_attr
376+ (fun expr -> expr.pexp_loc)
377+ (fun loc expr ->
378+ Parsetree. JSXPropValue ({txt = name; loc}, false , expr)))
379+ | Asttypes.Noloc. Optional name , _exp ->
352380 Some
353- (Parsetree. JSXPropValue
354- ({txt = name; loc = Location. none}, true , sub.expr sub exp))
381+ (map_expr_with_loc_attr jsx_prop_loc_attr
382+ (fun expr -> expr.pexp_loc)
383+ (fun loc expr ->
384+ Parsetree. JSXPropValue ({txt = name; loc}, true , expr)))
355385 | _ -> None
356386
357387 let extract_props_and_children (sub : mapper ) items =
0 commit comments