From 7f7a1b0bb74a855583485d0216046388233ed4f9 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 22 Apr 2022 09:50:30 +0200 Subject: [PATCH 1/2] Recovery when encountering errors parsing long idents. More fine grained error recovery from parsing longidents. E.g. Foo. gives Foo._ instead of a default expression which erases info on what's parser already. From: https://github.com/rescript-lang/rescript-vscode/pull/388 --- src/res_core.ml | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/res_core.ml b/src/res_core.ml index 55266f6f..b03458b7 100644 --- a/src/res_core.ml +++ b/src/res_core.ml @@ -699,18 +699,27 @@ let parseValuePath p = | Lident ident -> Longident.Ldot(path, ident) | Uident uident -> Parser.next p; - Parser.expect Dot p; - aux p (Ldot (path, uident)) + if p.Parser.token = Dot then ( + Parser.expect Dot p; + aux p (Ldot (path, uident)) + ) else ( + Parser.err p (Diagnostics.unexpected p.Parser.token p.breadcrumbs); + path + ) | token -> Parser.err p (Diagnostics.unexpected token p.breadcrumbs); - Longident.Lident "_" + Longident.Ldot (path, "_") in let ident = match p.Parser.token with | Lident ident -> Longident.Lident ident | Uident ident -> - Parser.next p; - Parser.expect Dot p; - aux p (Lident ident) + if p.Parser.token = Dot then ( + Parser.expect Dot p; + aux p (Lident ident) + ) else ( + Parser.err p (Diagnostics.unexpected p.Parser.token p.breadcrumbs); + Longident.Lident ident + ) | token -> Parser.err p (Diagnostics.unexpected token p.breadcrumbs); Longident.Lident "_" @@ -730,7 +739,7 @@ let parseValuePathTail p startPos ident = loop p (Longident.Ldot (path, ident)) | token -> Parser.err p (Diagnostics.unexpected token p.breadcrumbs); - Location.mknoloc path + Location.mkloc (Longident.Ldot (path, "_")) (mkLoc startPos p.prevEndPos) in loop p ident @@ -753,7 +762,7 @@ let parseModuleLongIdentTail ~lowercase p startPos ident = end | t -> Parser.err p (Diagnostics.uident t); - Location.mkloc acc (mkLoc startPos p.prevEndPos) + Location.mkloc (Longident.Ldot (acc, "_")) (mkLoc startPos p.prevEndPos) in loop p ident @@ -3582,8 +3591,10 @@ and parseValueOrConstructor p = Ast_helper.Exp.ident ~loc (Location.mkloc lident loc) | token -> Parser.next p; + let loc = mkLoc startPos p.prevEndPos in Parser.err p (Diagnostics.unexpected token p.breadcrumbs); - Recover.defaultExpr() + let lident = buildLongident ("_"::acc) in + Ast_helper.Exp.ident ~loc (Location.mkloc lident loc) in aux p [] From 701d28342974a6739d68b339ffa50d4de53dda41 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 22 Apr 2022 19:05:03 +0200 Subject: [PATCH 2/2] Missing a Parser.next in copy-paste. --- src/res_core.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/res_core.ml b/src/res_core.ml index b03458b7..67204be9 100644 --- a/src/res_core.ml +++ b/src/res_core.ml @@ -713,6 +713,7 @@ let parseValuePath p = let ident = match p.Parser.token with | Lident ident -> Longident.Lident ident | Uident ident -> + Parser.next p; if p.Parser.token = Dot then ( Parser.expect Dot p; aux p (Lident ident)