Skip to content

Commit 49212ab

Browse files
authored
fix misparsing in/after JSX (#6677) (#6686)
1 parent 5a0a21d commit 49212ab

File tree

6 files changed

+90
-14
lines changed

6 files changed

+90
-14
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
1313
# 11.1.0-rc.5 (Unreleased)
1414

15+
#### :bug: Bug Fix
16+
17+
- Fix misparsing in/after JSX. https://github.com/rescript-lang/rescript-compiler/pull/6686
18+
1519
# 11.1.0-rc.4
1620

1721
#### :bug: Bug Fix

jscomp/syntax/src/res_core.ml

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,6 +2612,7 @@ and parseJsxOpeningOrSelfClosingElement ~startPos p =
26122612
let childrenStartPos = p.Parser.startPos in
26132613
Parser.next p;
26142614
let childrenEndPos = p.Parser.startPos in
2615+
Scanner.popMode p.scanner Jsx;
26152616
Parser.expect GreaterThan p;
26162617
let loc = mkLoc childrenStartPos childrenEndPos in
26172618
makeListExpression loc [] None (* no children *)
@@ -2621,8 +2622,6 @@ and parseJsxOpeningOrSelfClosingElement ~startPos p =
26212622
Parser.next p;
26222623
let spread, children = parseJsxChildren p in
26232624
let childrenEndPos = p.Parser.startPos in
2624-
Scanner.popMode p.scanner Jsx;
2625-
Scanner.setJsxMode p.scanner;
26262625
let () =
26272626
match p.token with
26282627
| LessThanSlash -> Parser.next p
@@ -2634,12 +2633,14 @@ and parseJsxOpeningOrSelfClosingElement ~startPos p =
26342633
in
26352634
match p.Parser.token with
26362635
| (Lident _ | Uident _) when verifyJsxOpeningClosingName p name -> (
2636+
Scanner.popMode p.scanner Jsx;
26372637
Parser.expect GreaterThan p;
26382638
let loc = mkLoc childrenStartPos childrenEndPos in
26392639
match (spread, children) with
26402640
| true, child :: _ -> child
26412641
| _ -> makeListExpression loc children None)
26422642
| token -> (
2643+
Scanner.popMode p.scanner Jsx;
26432644
let () =
26442645
if Grammar.isStructureItemStart token then
26452646
let closing = "</" ^ string_of_pexp_ident name ^ ">" in
@@ -2660,6 +2661,7 @@ and parseJsxOpeningOrSelfClosingElement ~startPos p =
26602661
| true, child :: _ -> child
26612662
| _ -> makeListExpression loc children None))
26622663
| token ->
2664+
Scanner.popMode p.scanner Jsx;
26632665
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
26642666
makeListExpression Location.none [] None
26652667
in
@@ -2687,7 +2689,6 @@ and parseJsxOpeningOrSelfClosingElement ~startPos p =
26872689
* jsx-children ::= primary-expr* * => 0 or more
26882690
*)
26892691
and parseJsx p =
2690-
Scanner.popMode p.scanner Jsx;
26912692
Scanner.setJsxMode p.Parser.scanner;
26922693
Parser.leaveBreadcrumb p Grammar.Jsx;
26932694
let startPos = p.Parser.startPos in
@@ -2700,7 +2701,6 @@ and parseJsx p =
27002701
parseJsxFragment p
27012702
| _ -> parseJsxName p
27022703
in
2703-
Scanner.popMode p.scanner Jsx;
27042704
Parser.eatBreadcrumb p;
27052705
{jsxExpr with pexp_attributes = [jsxAttr]}
27062706

@@ -2714,9 +2714,10 @@ and parseJsxFragment p =
27142714
Parser.expect GreaterThan p;
27152715
let _spread, children = parseJsxChildren p in
27162716
let childrenEndPos = p.Parser.startPos in
2717+
if p.token = LessThan then p.token <- Scanner.reconsiderLessThan p.scanner;
27172718
Parser.expect LessThanSlash p;
2718-
Parser.expect GreaterThan p;
27192719
Scanner.popMode p.scanner Jsx;
2720+
Parser.expect GreaterThan p;
27202721
let loc = mkLoc childrenStartPos childrenEndPos in
27212722
makeListExpression loc children None
27222723

@@ -2768,6 +2769,7 @@ and parseJsxProp p =
27682769
Some (label, attrExpr))
27692770
(* {...props} *)
27702771
| Lbrace -> (
2772+
Scanner.popMode p.scanner Jsx;
27712773
Parser.next p;
27722774
match p.Parser.token with
27732775
| DotDotDot -> (
@@ -2786,6 +2788,7 @@ and parseJsxProp p =
27862788
match p.Parser.token with
27872789
| Rbrace ->
27882790
Parser.next p;
2791+
Scanner.setJsxMode p.scanner;
27892792
Some (label, attrExpr)
27902793
| _ -> None)
27912794
| _ -> None)
@@ -2795,6 +2798,7 @@ and parseJsxProps p =
27952798
parseRegion ~grammar:Grammar.JsxAttribute ~f:parseJsxProp p
27962799

27972800
and parseJsxChildren p =
2801+
Scanner.popMode p.scanner Jsx;
27982802
let rec loop p children =
27992803
match p.Parser.token with
28002804
| Token.Eof | LessThanSlash -> children
@@ -2815,21 +2819,23 @@ and parseJsxChildren p =
28152819
let () = p.token <- token in
28162820
children
28172821
| token when Grammar.isJsxChildStart token ->
2818-
let () = Scanner.popMode p.scanner Jsx in
28192822
let child =
28202823
parsePrimaryExpr ~operand:(parseAtomicExpr p) ~noCall:true p
28212824
in
28222825
loop p (child :: children)
28232826
| _ -> children
28242827
in
2825-
match p.Parser.token with
2826-
| DotDotDot ->
2827-
Parser.next p;
2828-
(true, [parsePrimaryExpr ~operand:(parseAtomicExpr p) ~noCall:true p])
2829-
| _ ->
2830-
let children = List.rev (loop p []) in
2831-
Scanner.popMode p.scanner Jsx;
2832-
(false, children)
2828+
let spread, children =
2829+
match p.Parser.token with
2830+
| DotDotDot ->
2831+
Parser.next p;
2832+
(true, [parsePrimaryExpr ~operand:(parseAtomicExpr p) ~noCall:true p])
2833+
| _ ->
2834+
let children = List.rev (loop p []) in
2835+
(false, children)
2836+
in
2837+
Scanner.setJsxMode p.scanner;
2838+
(spread, children)
28332839

28342840
and parseBracedOrRecordExpr p =
28352841
let startPos = p.Parser.startPos in

jscomp/syntax/tests/parsing/grammar/expressions/expected/jsx.res.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,11 +580,13 @@ let _ =
580580
;;((div ~children:((span ~children:[] ())[@JSX ]) ())[@JSX ])
581581
;;((div ~children:[|a|] ())[@JSX ])
582582
;;((div ~children:(1, 2) ())[@JSX ])
583+
;;((div ~children:((array |. f)[@res.braces ]) ())[@JSX ])
583584
;;(([element])[@JSX ])
584585
;;(([(((fun a -> 1))[@res.braces ])])[@JSX ])
585586
;;(([((span ~children:[] ())[@JSX ])])[@JSX ])
586587
;;(([[|a|]])[@JSX ])
587588
;;(([(1, 2)])[@JSX ])
589+
;;(([((array |. f)[@res.braces ])])[@JSX ])
588590
let _ =
589591
((A.createElement ~x:(({js|y|js})[@res.namedArgLoc ]) ~_spreadProps:((str)
590592
[@res.namedArgLoc ]) ~children:[] ())

jscomp/syntax/tests/parsing/grammar/expressions/jsx.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,11 +507,13 @@ let _ = <View style=styles["backgroundImageWrapper"]>
507507
<div> ...<span /> </div>
508508
<div> ...[a] </div>
509509
<div> ...(1, 2) </div>
510+
<div> ...{array->f} </div>
510511

511512
<> ...element </>
512513
<> ...{(a) => 1} </>
513514
<> ...<span /> </>
514515
<> ...[a] </>
515516
<> ...(1, 2) </>
517+
<> ...{array->f} </>
516518

517519
let _ = <A x="y" {...str} />

jscomp/syntax/tests/printer/expr/expected/jsx.res.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,34 @@ let x = props =>
429429
{...props}
430430
className="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight"
431431
/>
432+
433+
let x = <C> ...{() => msg->React.string} </C>
434+
435+
let x = <C> ...{array->Array.map(React.string)} </C>
436+
437+
let x = <> {array->Array.map(React.string)} </>
438+
439+
let x = {
440+
let _ = <div />
441+
msg->React.string
442+
}
443+
444+
let x = {
445+
let _ = <div> {children} </div>
446+
msg->React.string
447+
}
448+
449+
let x = {
450+
let _ = <> {children} </>
451+
msg->React.string
452+
}
453+
454+
let x = {
455+
let _ = <C />
456+
msg->React.string
457+
}
458+
459+
let x = {
460+
let _ = <C> {children} </C>
461+
msg->React.string
462+
}

jscomp/syntax/tests/printer/expr/jsx.res

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,3 +414,34 @@ let x = props =>
414414
{...props}
415415
className="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight"
416416
/>
417+
418+
let x = <C> ...{() => msg->React.string} </C>
419+
420+
let x = <C> ...{array->Array.map(React.string)} </C>
421+
422+
let x = <> ...{array->Array.map(React.string)} </>
423+
424+
let x = {
425+
let _ = <div />
426+
msg->React.string
427+
}
428+
429+
let x = {
430+
let _ = <div> {children} </div>
431+
msg->React.string
432+
}
433+
434+
let x = {
435+
let _ = <> {children} </>
436+
msg->React.string
437+
}
438+
439+
let x = {
440+
let _ = <C />
441+
msg->React.string
442+
}
443+
444+
let x = {
445+
let _ = <C> {children} </C>
446+
msg->React.string
447+
}

0 commit comments

Comments
 (0)