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

Commit 546cb85

Browse files
authored
Fix parsing punned record fields with module name (#479)
* Fix parsing punned record fields with module name * Add more tests * Move helper function to top and add comment. * Invoke removeModuleNameFromPunnedFieldValue for Uident only * Fix
1 parent 25b2a4e commit 546cb85

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

src/res_core.ml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ let hexValue ch =
493493
| 'A'..'F' -> (Char.code ch) + 32 - (Char.code 'a') + 10
494494
| _ -> 16 (* larger than any legal value *)
495495

496+
(* Transform A.a into a. For use with punned record fields as in {A.a, b}. *)
497+
let removeModuleNameFromPunnedFieldValue exp =
498+
match exp.Parsetree.pexp_desc with
499+
| Pexp_ident pathIdent -> {exp with pexp_desc = Pexp_ident { pathIdent with txt = Lident (Longident.last pathIdent.txt) }}
500+
| _ -> exp
501+
496502
let parseStringLiteral s =
497503
let len = String.length s in
498504
let b = Buffer.create (String.length s) in
@@ -2771,13 +2777,18 @@ and parseBracedOrRecordExpr p =
27712777
end
27722778
end
27732779
| Uident _ | Lident _ ->
2780+
let startToken = p.token in
27742781
let valueOrConstructor = parseValueOrConstructor p in
27752782
begin match valueOrConstructor.pexp_desc with
27762783
| Pexp_ident pathIdent ->
27772784
let identEndPos = p.prevEndPos in
27782785
begin match p.Parser.token with
27792786
| Comma ->
27802787
Parser.next p;
2788+
let valueOrConstructor = match startToken with
2789+
| Uident _ -> removeModuleNameFromPunnedFieldValue(valueOrConstructor)
2790+
| _ -> valueOrConstructor
2791+
in
27812792
let expr = parseRecordExpr ~startPos [(pathIdent, valueOrConstructor)] p in
27822793
Parser.expect Rbrace p;
27832794
expr
@@ -2939,14 +2950,20 @@ and parseRecordRow p =
29392950
in
29402951
match p.Parser.token with
29412952
| Lident _ | Uident _ ->
2953+
let startToken = p.token in
29422954
let field = parseValuePath p in
29432955
begin match p.Parser.token with
29442956
| Colon ->
29452957
Parser.next p;
29462958
let fieldExpr = parseExpr p in
29472959
Some (field, fieldExpr)
29482960
| _ ->
2949-
Some (field, Ast_helper.Exp.ident ~loc:field.loc field)
2961+
let value = Ast_helper.Exp.ident ~loc:field.loc field in
2962+
let value = match startToken with
2963+
| Uident _ -> removeModuleNameFromPunnedFieldValue(value)
2964+
| _ -> value
2965+
in
2966+
Some (field, value)
29502967
end
29512968
| _ -> None
29522969

tests/parsing/grammar/expressions/expected/record.res.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ let r = { a = expr }
22
let r = { a = expr }
33
let r = { Parsetree.pexp_attributes = [||]; Parsetree.loc = loc }
44
let r = { a; b; c }
5-
let r = { Parsetree.pexp_attributes; Parsetree.loc }
6-
let r = { Parsetree.pexp_attributes; Parsetree.loc }
5+
let r = { A.a = a; b }
6+
let r = { A.a = a; b; C.c = c }
7+
let r = { Parsetree.pexp_attributes = pexp_attributes; Parsetree.loc = loc }
8+
let r = { Parsetree.pexp_attributes = pexp_attributes; Parsetree.loc = loc }
79
let r = { a = (expr : int); b = (x : string) }
810
let r = { expr with pexp_attributes = [||] }
911
let r = { expr with pexp_attributes = [||]; pexp_loc = loc }

tests/parsing/grammar/expressions/record.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ let r = {Parsetree.pexp_attributes: [], Parsetree.loc: loc}
55

66
// punning
77
let r = {a, b, c}
8+
let r = {A.a, b}
9+
let r = {A.a, b, C.c}
810

911
let r = {Parsetree.pexp_attributes, Parsetree.loc}
1012
// trailing comma

0 commit comments

Comments
 (0)