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

Commit eae2a01

Browse files
committed
More robust parse recovery after ".".
See rescript-lang/rescript-vscode#416 for examples where parser recovery goes wrong in template expressions. Basically, if the token after "." is consumed in recovery, the entire template expression is eaten up and never recovers. This PR changes error recovery to not consume the token after Dot so the parser can recover properly inside a template.
1 parent da10fed commit eae2a01

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

src/res_core.ml

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,16 @@ let parseValuePath p =
728728
Parser.next p;
729729
Location.mkloc ident (mkLoc startPos p.prevEndPos)
730730

731+
let parseValuePathAfterDot p =
732+
let startPos = p.Parser.startPos in
733+
match p.Parser.token with
734+
| Lident _
735+
| Uident _ ->
736+
parseValuePath p
737+
| token ->
738+
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
739+
Location.mkloc (Longident.Lident "_") (mkLoc startPos p.prevEndPos)
740+
731741
let parseValuePathTail p startPos ident =
732742
let rec loop p path =
733743
match p.Parser.token with
@@ -2052,7 +2062,7 @@ and parsePrimaryExpr ~operand ?(noCall=false) p =
20522062
match p.Parser.token with
20532063
| Dot ->
20542064
Parser.next p;
2055-
let lident = parseValuePath p in
2065+
let lident = parseValuePathAfterDot p in
20562066
begin match p.Parser.token with
20572067
| Equal when noCall = false ->
20582068
Parser.leaveBreadcrumb p Grammar.ExprSetField;
@@ -3591,11 +3601,16 @@ and parseValueOrConstructor p =
35913601
let lident = buildLongident (ident::acc) in
35923602
Ast_helper.Exp.ident ~loc (Location.mkloc lident loc)
35933603
| token ->
3594-
Parser.next p;
3595-
let loc = mkLoc startPos p.prevEndPos in
3596-
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
3597-
let lident = buildLongident ("_"::acc) in
3598-
Ast_helper.Exp.ident ~loc (Location.mkloc lident loc)
3604+
if acc = [] then (
3605+
Parser.next p;
3606+
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
3607+
Recover.defaultExpr()
3608+
) else (
3609+
let loc = mkLoc startPos p.prevEndPos in
3610+
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
3611+
let lident = buildLongident ("_"::acc) in
3612+
Ast_helper.Exp.ident ~loc (Location.mkloc lident loc)
3613+
)
35993614
in
36003615
aux p []
36013616

0 commit comments

Comments
 (0)