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

Commit 1e0f307

Browse files
committed
Fix issue overlapping argument with default value
1 parent 623f196 commit 1e0f307

File tree

5 files changed

+95
-30
lines changed

5 files changed

+95
-30
lines changed

cli/reactjs_jsx_v4.ml

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -729,10 +729,10 @@ let argToType ~newtypes ~(typeConstraints : core_type option) types
729729
:: types
730730
| _ -> types
731731

732-
let argWithDefaultValue (name, default, _, _, _, _) =
733-
match default with
734-
| Some default when isOptional name -> Some (getLabel name, default)
735-
| _ -> None
732+
let hasDefaultValue nameArgList =
733+
nameArgList
734+
|> List.exists (fun (name, default, _, _, _, _) ->
735+
Option.is_some default && isOptional name)
736736

737737
let argToConcreteType types (name, attrs, loc, type_) =
738738
match name with
@@ -1016,26 +1016,34 @@ let transformStructureItem ~config mapper item =
10161016
(argToType ~newtypes ~typeConstraints)
10171017
[] namedArgList
10181018
in
1019-
let namedArgWithDefaultValueList =
1020-
List.filter_map argWithDefaultValue namedArgList
1019+
let vbMatch (name, default, _, _, _, _) =
1020+
let label = getLabel name in
1021+
match default with
1022+
| Some default ->
1023+
Vb.mk
1024+
(Pat.var (Location.mknoloc label))
1025+
(Exp.match_
1026+
(Exp.ident
1027+
{txt = Ldot (Lident "props", label); loc = Location.none})
1028+
[
1029+
Exp.case
1030+
(Pat.construct
1031+
(Location.mknoloc @@ Lident "Some")
1032+
(Some (Pat.var (Location.mknoloc label))))
1033+
(Exp.ident (Location.mknoloc @@ Lident label));
1034+
Exp.case
1035+
(Pat.construct (Location.mknoloc @@ Lident "None") None)
1036+
default;
1037+
])
1038+
| None ->
1039+
Vb.mk
1040+
(Pat.var (Location.mknoloc label))
1041+
(Exp.ident @@ Location.mknoloc @@ Ldot (Lident "props", label))
10211042
in
1022-
let vbMatch (label, default) =
1023-
Vb.mk
1024-
(Pat.var (Location.mknoloc label))
1025-
(Exp.match_
1026-
(Exp.ident {txt = Lident label; loc = Location.none})
1027-
[
1028-
Exp.case
1029-
(Pat.construct
1030-
(Location.mknoloc @@ Lident "Some")
1031-
(Some (Pat.var (Location.mknoloc label))))
1032-
(Exp.ident (Location.mknoloc @@ Lident label));
1033-
Exp.case
1034-
(Pat.construct (Location.mknoloc @@ Lident "None") None)
1035-
default;
1036-
])
1043+
let vbMatchList =
1044+
if hasDefaultValue namedArgList then List.map vbMatch namedArgList
1045+
else []
10371046
in
1038-
let vbMatchList = List.map vbMatch namedArgWithDefaultValueList in
10391047
(* type props = { ... } *)
10401048
let propsRecordType =
10411049
makePropsRecordType ~coreTypeOfAttr ~typVarsOfCoreType "props"
@@ -1163,11 +1171,17 @@ let transformStructureItem ~config mapper item =
11631171
(fun expr (_, pattern) -> Exp.fun_ Nolabel None pattern expr)
11641172
expression patternsWithNolabel
11651173
in
1174+
(* ({a, b, _}: props<'a, 'b>) *)
11661175
let recordPattern =
11671176
match patternsWithLabel with
11681177
| [] -> Pat.any ()
11691178
| _ -> Pat.record (List.rev patternsWithLabel) Open
11701179
in
1180+
let recordPattern =
1181+
if hasDefaultValue namedArgList then
1182+
Pat.var {txt = "props"; loc = emptyLoc}
1183+
else recordPattern
1184+
in
11711185
let expression =
11721186
Exp.fun_ Nolabel None
11731187
(Pat.constraint_ recordPattern

tests/ppx/react/defaultValueProp.res

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module C0 = {
2+
@react.component
3+
let make = (~a=2, ~b=a*2) => <div />
4+
}
5+
6+
module C1 = {
7+
@react.component
8+
let make = (~a=2, ~b) => <div />
9+
}

tests/ppx/react/expected/aliasProps.res.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ module C0 = {
44
type props<'priority, 'text> = {priority: 'priority, text?: 'text}
55

66
@react.component
7-
let make = ({priority: _, ?text, _}: props<'priority, 'text>) => {
8-
let text = switch text {
7+
let make = (props: props<'priority, 'text>) => {
8+
let text = switch props.text {
99
| Some(text) => text
1010
| None => "Test"
1111
}
12+
and priority = props.priority
1213

1314
React.string(text)
1415
}
@@ -23,11 +24,12 @@ module C1 = {
2324
type props<'priority, 'text> = {priority: 'priority, text?: 'text}
2425

2526
@react.component
26-
let make = ({priority: p, ?text, _}: props<'priority, 'text>) => {
27-
let text = switch text {
27+
let make = (props: props<'priority, 'text>) => {
28+
let text = switch props.text {
2829
| Some(text) => text
2930
| None => "Test"
3031
}
32+
and priority = props.priority
3133

3234
React.string(p ++ text)
3335
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module C0 = {
2+
type props<'a, 'b> = {a?: 'a, b?: 'b}
3+
@react.component
4+
let make = (props: props<'a, 'b>) => {
5+
let b = switch props.b {
6+
| Some(b) => b
7+
| None => a * 2
8+
}
9+
and a = switch props.a {
10+
| Some(a) => a
11+
| None => 2
12+
}
13+
14+
ReactDOM.jsx("div", {})
15+
}
16+
let make = {
17+
let \"DefaultValueProp$C0" = (props: props<_>) => make(props)
18+
\"DefaultValueProp$C0"
19+
}
20+
}
21+
22+
module C1 = {
23+
type props<'a, 'b> = {a?: 'a, b: 'b}
24+
25+
@react.component
26+
let make = (props: props<'a, 'b>) => {
27+
let b = props.b
28+
and a = switch props.a {
29+
| Some(a) => a
30+
| None => 2
31+
}
32+
33+
ReactDOM.jsx("div", {})
34+
}
35+
let make = {
36+
let \"DefaultValueProp$C1" = (props: props<_>) => make(props)
37+
38+
\"DefaultValueProp$C1"
39+
}
40+
}

tests/ppx/react/expected/uncurriedProps.res.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
type props<'a> = {a?: 'a}
33

44
@react.component
5-
let make = ({?a, _}: props<(. unit) => unit>) => {
6-
let a = switch a {
5+
let make = (props: props<(. unit) => unit>) => {
6+
let a = switch props.a {
77
| Some(a) => a
88
| None => (. ()) => ()
99
}
@@ -30,8 +30,8 @@ module Foo = {
3030
type props<'callback> = {callback?: 'callback}
3131

3232
@react.component
33-
let make = ({?callback, _}: props<(. string, bool, bool) => unit>) => {
34-
let callback = switch callback {
33+
let make = (props: props<(. string, bool, bool) => unit>) => {
34+
let callback = switch props.callback {
3535
| Some(callback) => callback
3636
| None => (. _, _, _) => ()
3737
}

0 commit comments

Comments
 (0)