Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 89561df

Browse files
committed
fix loc error when required props not supplied
1 parent d24718d commit 89561df

File tree

1 file changed

+77
-50
lines changed

1 file changed

+77
-50
lines changed

cli/reactjs_jsx_ppx.ml

+77-50
Original file line numberDiff line numberDiff line change
@@ -1385,15 +1385,15 @@ module V4 = struct
13851385
type 'a children = ListLiteral of 'a | Exact of 'a
13861386

13871387
(* if children is a list, convert it to an array while mapping each element. If not, just map over it, as usual *)
1388-
let transformChildrenIfListUpper ~loc ~mapper theList =
1388+
let transformChildrenIfListUpper ~mapper theList =
13891389
let rec transformChildren_ theList accum =
13901390
(* not in the sense of converting a list to an array; convert the AST
13911391
reprensentation of a list to the AST reprensentation of an array *)
13921392
match theList with
13931393
| {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} -> (
13941394
match accum with
13951395
| [singleElement] -> Exact singleElement
1396-
| accum -> ListLiteral (Exp.array ~loc (List.rev accum)))
1396+
| accum -> ListLiteral (Exp.array (List.rev accum)))
13971397
| {
13981398
pexp_desc =
13991399
Pexp_construct
@@ -1404,13 +1404,13 @@ module V4 = struct
14041404
in
14051405
transformChildren_ theList []
14061406

1407-
let transformChildrenIfList ~loc ~mapper theList =
1407+
let transformChildrenIfList ~mapper theList =
14081408
let rec transformChildren_ theList accum =
14091409
(* not in the sense of converting a list to an array; convert the AST
14101410
reprensentation of a list to the AST reprensentation of an array *)
14111411
match theList with
14121412
| {pexp_desc = Pexp_construct ({txt = Lident "[]"}, None)} ->
1413-
Exp.array ~loc (List.rev accum)
1413+
Exp.array (List.rev accum)
14141414
| {
14151415
pexp_desc =
14161416
Pexp_construct
@@ -1421,7 +1421,7 @@ module V4 = struct
14211421
in
14221422
transformChildren_ theList []
14231423

1424-
let extractChildren ?(removeLastPositionUnit = false) ~loc propsAndChildren =
1424+
let extractChildren ?(removeLastPositionUnit = false) propsAndChildren =
14251425
let rec allButLast_ lst acc =
14261426
match lst with
14271427
| [] -> []
@@ -1445,7 +1445,7 @@ module V4 = struct
14451445
with
14461446
| [], props ->
14471447
(* no children provided? Place a placeholder list *)
1448-
( Exp.construct ~loc {loc; txt = Lident "[]"} None,
1448+
( Exp.construct {loc = Location.none; txt = Lident "[]"} None,
14491449
if removeLastPositionUnit then allButLast props else props )
14501450
| [(_, childrenExpr)], props ->
14511451
(childrenExpr, if removeLastPositionUnit then allButLast props else props)
@@ -1523,7 +1523,7 @@ module V4 = struct
15231523
*)
15241524

15251525
(* make record from props and spread props if exists *)
1526-
let recordFromProps ?(removeKey = false) callArguments =
1526+
let recordFromProps ~loc ?(removeKey = false) callArguments =
15271527
let rec removeLastPositionUnitAux props acc =
15281528
match props with
15291529
| [] -> acc
@@ -1561,19 +1561,19 @@ module V4 = struct
15611561
| [] ->
15621562
{
15631563
pexp_desc = Pexp_record (fields, None);
1564-
pexp_loc = Location.none;
1564+
pexp_loc = loc;
15651565
pexp_attributes = [];
15661566
}
15671567
| [spreadProps] ->
15681568
{
15691569
pexp_desc = Pexp_record (fields, Some spreadProps);
1570-
pexp_loc = Location.none;
1570+
pexp_loc = loc;
15711571
pexp_attributes = [];
15721572
}
15731573
| spreadProps :: _ ->
15741574
{
15751575
pexp_desc = Pexp_record (fields, Some spreadProps);
1576-
pexp_loc = Location.none;
1576+
pexp_loc = loc;
15771577
pexp_attributes = [];
15781578
}
15791579

@@ -1640,13 +1640,13 @@ module V4 = struct
16401640
let makePropsRecordTypeSig propsName loc namedTypeList =
16411641
Sig.type_ Nonrecursive (makeTypeDecls propsName loc namedTypeList)
16421642

1643-
let transformUppercaseCall3 ~config modulePath mapper loc attrs callArguments
1644-
=
1643+
let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc
1644+
attrs callArguments =
16451645
let children, argsWithLabels =
1646-
extractChildren ~loc ~removeLastPositionUnit:true callArguments
1646+
extractChildren ~removeLastPositionUnit:true callArguments
16471647
in
16481648
let argsForMake = argsWithLabels in
1649-
let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in
1649+
let childrenExpr = transformChildrenIfListUpper ~mapper children in
16501650
let recursivelyTransformedArgsForMake =
16511651
argsForMake
16521652
|> List.map (fun (label, expression) ->
@@ -1674,7 +1674,8 @@ module V4 = struct
16741674
| _ ->
16751675
[
16761676
( labelled "children",
1677-
Exp.ident ~loc {loc; txt = Ldot (Lident "React", "null")} );
1677+
Exp.ident
1678+
{loc = Location.none; txt = Ldot (Lident "React", "null")} );
16781679
])
16791680
in
16801681

@@ -1702,9 +1703,10 @@ module V4 = struct
17021703
match config.mode with
17031704
(* The new jsx transform *)
17041705
| "automatic" ->
1705-
let record = recordFromProps ~removeKey:true args in
1706+
let record = recordFromProps ~loc:jsxExprLoc ~removeKey:true args in
17061707
let props =
1707-
if isEmptyRecord record then recordWithOnlyKey ~loc else record
1708+
if isEmptyRecord record then recordWithOnlyKey ~loc:jsxExprLoc
1709+
else record
17081710
in
17091711
let keyProp =
17101712
args |> List.filter (fun (arg_label, _) -> "key" = getLabel arg_label)
@@ -1727,22 +1729,30 @@ module V4 = struct
17271729
[] )
17281730
in
17291731
Exp.apply ~attrs jsxExpr
1730-
([(nolabel, Exp.ident {txt = ident; loc}); (nolabel, props)] @ key)
1732+
([
1733+
(nolabel, Exp.ident {txt = ident; loc = callExprLoc});
1734+
(nolabel, props);
1735+
]
1736+
@ key)
17311737
| _ -> (
1732-
let record = recordFromProps args in
1738+
let record = recordFromProps ~loc:jsxExprLoc args in
17331739
(* check if record which goes to Foo.make({ ... } as record) empty or not
17341740
if empty then change it to {key: @optional None} only for upper case jsx
17351741
This would be redundant regarding PR progress https://github.com/rescript-lang/syntax/pull/299
17361742
*)
17371743
let props =
1738-
if isEmptyRecord record then recordWithOnlyKey ~loc else record
1744+
if isEmptyRecord record then recordWithOnlyKey ~loc:jsxExprLoc
1745+
else record
17391746
in
17401747
match !childrenArg with
17411748
| None ->
17421749
Exp.apply ~attrs
17431750
(Exp.ident
17441751
{loc = Location.none; txt = Ldot (Lident "React", "createElement")})
1745-
[(nolabel, Exp.ident {txt = ident; loc}); (nolabel, props)]
1752+
[
1753+
(nolabel, Exp.ident {txt = ident; loc = callExprLoc});
1754+
(nolabel, props);
1755+
]
17461756
| Some children ->
17471757
Exp.apply ~attrs
17481758
(Exp.ident
@@ -1751,22 +1761,23 @@ module V4 = struct
17511761
txt = Ldot (Lident "React", "createElementVariadic");
17521762
})
17531763
[
1754-
(nolabel, Exp.ident {txt = ident; loc});
1764+
(nolabel, Exp.ident {txt = ident; loc = callExprLoc});
17551765
(nolabel, props);
17561766
(nolabel, children);
17571767
])
17581768
[@@raises Invalid_argument]
17591769

1760-
let transformLowercaseCall3 ~config mapper loc attrs callArguments id =
1761-
let componentNameExpr = constantString ~loc id in
1770+
let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs
1771+
callArguments id =
1772+
let componentNameExpr = constantString ~loc:callExprLoc id in
17621773
match config.mode with
17631774
(* the new jsx transform *)
17641775
| "automatic" ->
17651776
let children, nonChildrenProps =
1766-
extractChildren ~removeLastPositionUnit:true ~loc callArguments
1777+
extractChildren ~removeLastPositionUnit:true callArguments
17671778
in
17681779
let argsForMake = nonChildrenProps in
1769-
let childrenExpr = transformChildrenIfListUpper ~loc ~mapper children in
1780+
let childrenExpr = transformChildrenIfListUpper ~mapper children in
17701781
let recursivelyTransformedArgsForMake =
17711782
argsForMake
17721783
|> List.map (fun (label, expression) ->
@@ -1795,31 +1806,38 @@ module V4 = struct
17951806
| Pexp_record (labelDecls, _) when List.length labelDecls = 0 -> true
17961807
| _ -> false
17971808
in
1798-
let record = recordFromProps ~removeKey:true args in
1809+
let record = recordFromProps ~loc:jsxExprLoc ~removeKey:true args in
17991810
let props =
1800-
if isEmptyRecord record then recordWithOnlyKey ~loc else record
1811+
if isEmptyRecord record then recordWithOnlyKey ~loc:jsxExprLoc
1812+
else record
18011813
in
18021814
let keyProp =
18031815
args |> List.filter (fun (arg_label, _) -> "key" = getLabel arg_label)
18041816
in
18051817
let jsxExpr, key =
18061818
match (!childrenArg, keyProp) with
18071819
| None, (_, keyExpr) :: _ ->
1808-
( Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOM", "jsxKeyed")},
1820+
( Exp.ident
1821+
{loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsxKeyed")},
18091822
[(nolabel, keyExpr)] )
18101823
| None, [] ->
1811-
(Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOM", "jsx")}, [])
1824+
( Exp.ident
1825+
{loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsx")},
1826+
[] )
18121827
| Some _, (_, keyExpr) :: _ ->
1813-
( Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOM", "jsxsKeyed")},
1828+
( Exp.ident
1829+
{loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsxsKeyed")},
18141830
[(nolabel, keyExpr)] )
18151831
| Some _, [] ->
1816-
(Exp.ident ~loc {loc; txt = Ldot (Lident "ReactDOM", "jsxs")}, [])
1832+
( Exp.ident
1833+
{loc = Location.none; txt = Ldot (Lident "ReactDOM", "jsxs")},
1834+
[] )
18171835
in
1818-
Exp.apply ~loc ~attrs jsxExpr
1836+
Exp.apply ~attrs jsxExpr
18191837
([(nolabel, componentNameExpr); (nolabel, props)] @ key)
18201838
| _ ->
1821-
let children, nonChildrenProps = extractChildren ~loc callArguments in
1822-
let childrenExpr = transformChildrenIfList ~loc ~mapper children in
1839+
let children, nonChildrenProps = extractChildren callArguments in
1840+
let childrenExpr = transformChildrenIfList ~mapper children in
18231841
let createElementCall =
18241842
match children with
18251843
(* [@JSX] div(~children=[a]), coming from <div> a </div> *)
@@ -1848,9 +1866,12 @@ module V4 = struct
18481866
]
18491867
| nonEmptyProps ->
18501868
let propsCall =
1851-
Exp.apply ~loc
1852-
(Exp.ident ~loc
1853-
{loc; txt = Ldot (Lident "ReactDOMRe", "domProps")})
1869+
Exp.apply
1870+
(Exp.ident
1871+
{
1872+
loc = Location.none;
1873+
txt = Ldot (Lident "ReactDOMRe", "domProps");
1874+
})
18541875
(nonEmptyProps
18551876
|> List.map (fun (label, expression) ->
18561877
(label, mapper.expr mapper expression)))
@@ -1864,12 +1885,13 @@ module V4 = struct
18641885
(nolabel, childrenExpr);
18651886
]
18661887
in
1867-
Exp.apply
1868-
~loc (* throw away the [@JSX] attribute and keep the others, if any *)
1869-
~attrs
1888+
Exp.apply ~loc:jsxExprLoc ~attrs
18701889
(* ReactDOMRe.createElement *)
1871-
(Exp.ident ~loc
1872-
{loc; txt = Ldot (Lident "ReactDOMRe", createElementCall)})
1890+
(Exp.ident
1891+
{
1892+
loc = Location.none;
1893+
txt = Ldot (Lident "ReactDOMRe", createElementCall);
1894+
})
18731895
args
18741896
[@@raises Invalid_argument]
18751897

@@ -2547,7 +2569,8 @@ module V4 = struct
25472569
| _ -> [item]
25482570
[@@raises Invalid_argument]
25492571

2550-
let transformJsxCall ~config mapper callExpression callArguments attrs =
2572+
let transformJsxCall ~config mapper callExpression callArguments jsxExprLoc
2573+
attrs =
25512574
match callExpression.pexp_desc with
25522575
| Pexp_ident caller -> (
25532576
match caller with
@@ -2557,13 +2580,14 @@ module V4 = struct
25572580
"JSX: `createElement` should be preceeded by a module name.")
25582581
(* Foo.createElement(~prop1=foo, ~prop2=bar, ~children=[], ()) *)
25592582
| {loc; txt = Ldot (modulePath, ("createElement" | "make"))} ->
2560-
transformUppercaseCall3 ~config modulePath mapper loc attrs
2583+
transformUppercaseCall3 ~config modulePath mapper jsxExprLoc loc attrs
25612584
callArguments
25622585
(* div(~prop1=foo, ~prop2=bar, ~children=[bla], ()) *)
25632586
(* turn that into
25642587
ReactDOMRe.createElement(~props=ReactDOMRe.props(~props1=foo, ~props2=bar, ()), [|bla|]) *)
25652588
| {loc; txt = Lident id} ->
2566-
transformLowercaseCall3 ~config mapper loc attrs callArguments id
2589+
transformLowercaseCall3 ~config mapper jsxExprLoc loc attrs
2590+
callArguments id
25672591
| {txt = Ldot (_, anythingNotCreateElementOrMake)} ->
25682592
raise
25692593
(Invalid_argument
@@ -2586,8 +2610,11 @@ module V4 = struct
25862610
let expr ~config mapper expression =
25872611
match expression with
25882612
(* Does the function application have the @JSX attribute? *)
2589-
| {pexp_desc = Pexp_apply (callExpression, callArguments); pexp_attributes}
2590-
-> (
2613+
| {
2614+
pexp_desc = Pexp_apply (callExpression, callArguments);
2615+
pexp_attributes;
2616+
pexp_loc;
2617+
} -> (
25912618
let jsxAttribute, nonJSXAttributes =
25922619
List.partition
25932620
(fun (attribute, _) -> attribute.txt = "JSX")
@@ -2597,7 +2624,7 @@ module V4 = struct
25972624
(* no JSX attribute *)
25982625
| [], _ -> default_mapper.expr mapper expression
25992626
| _, nonJSXAttributes ->
2600-
transformJsxCall ~config mapper callExpression callArguments
2627+
transformJsxCall ~config mapper callExpression callArguments pexp_loc
26012628
nonJSXAttributes)
26022629
(* is it a list with jsx attribute? Reason <>foo</> desugars to [@JSX][foo]*)
26032630
| {
@@ -2624,7 +2651,7 @@ module V4 = struct
26242651
| "classic" | _ ->
26252652
Exp.ident ~loc {loc; txt = Ldot (Lident "ReasonReact", "fragment")}
26262653
in
2627-
let childrenExpr = transformChildrenIfList ~loc ~mapper listItems in
2654+
let childrenExpr = transformChildrenIfList ~mapper listItems in
26282655
let args =
26292656
[
26302657
(nolabel, fragment);

0 commit comments

Comments
 (0)