From 1b38ed43c902805656b01c71495243839724e410 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 27 Jul 2024 21:57:31 -0700 Subject: [PATCH] feat: open any module expr (#2773) * feat: open any module expr * changelog, fix printing of pstr_open * fix --- CHANGES.md | 5 +++++ src/reason-parser/reason_parser.mly | 5 ++--- src/reason-parser/reason_pprint_ast.ml | 16 ++++++++-------- test/modules.t/input.re | 20 ++++++++++++++++++++ test/modules.t/run.t | 20 ++++++++++++++++++++ 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f2dfd5704..6c4fd416c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +## Unreleased + +- Extend open to arbitrary module expression (@anmonteiro, + [#2773](https://github.com/reasonml/reason/pull/2773)) + ## 3.12.0 - Add `\u{hex-escape}` syntax (@anmonteiro, diff --git a/src/reason-parser/reason_parser.mly b/src/reason-parser/reason_parser.mly index e9d04d25f..8603b45fa 100644 --- a/src/reason-parser/reason_parser.mly +++ b/src/reason-parser/reason_parser.mly @@ -2566,10 +2566,9 @@ seq_expr_no_seq [@recover.expr default_expr ()] (semi): | Some (ext_attrs, ext_id) -> mkexp ~loc (Pexp_extension (ext_id, PStr [mkstrexp exp ext_attrs])) } -| item_attributes LET? OPEN override_flag as_loc(mod_longident) SEMI seq_expr(SEMI?) +| item_attributes LET? OPEN override_flag module_expr SEMI seq_expr(SEMI?) { let loc = (mklocation $startpos($1) $endpos($4)) in - let me = Ast_helper.Mod.ident ~loc $5 in - let od = Ast_helper.Opn.mk ~override:$4 ~loc me in + let od = Ast_helper.Opn.mk ~override:$4 ~loc $5 in let exp = mkexp (Pexp_open(od, $7)) in { exp with pexp_attributes = $1 } } diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index 31144c30b..35bc91f45 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -162,7 +162,7 @@ let expression_immediate_extension_sugar x = | Some (name, expr) -> match expr.pexp_desc with | Pexp_for _ | Pexp_while _ | Pexp_ifthenelse _ | Pexp_function _ - | Pexp_newtype _ | Pexp_try _ | Pexp_match _ (* | Pexp_letmodule _ *) -> + | Pexp_newtype _ | Pexp_try _ | Pexp_match _ -> (Some name, expr) | _ -> (None, x) @@ -6236,8 +6236,9 @@ let printer = object(self:'self) | ([], Pexp_letop _) -> false | ([], Pexp_sequence _) -> false | ([], Pexp_letmodule _) -> false - | ([], Pexp_open (me, e)) -> - me.popen_override == Fresh && self#isSeriesOfOpensFollowedByNonSequencyExpression e + | ([], Pexp_open ({ popen_override; popen_expr = { pmod_desc = Pmod_ident _; _ }; _ }, e)) -> + popen_override == Fresh && self#isSeriesOfOpensFollowedByNonSequencyExpression e + | ([], Pexp_open _) -> false | ([], Pexp_letexception _) -> false | ([], Pexp_extension ({txt}, _)) -> txt = "mel.obj" | _ -> true @@ -6478,7 +6479,7 @@ let printer = object(self:'self) (atom ("."))) (self#formatNonSequencyExpression ~parent:x e)) else - Some (makeLetSequence (self#letList e)) + Some (makeLetSequence (self#letList x)) | Pexp_send (e, s) -> let needparens = match e.pexp_desc with | Pexp_apply (ee, _) -> @@ -7812,10 +7813,9 @@ let printer = object(self:'self) self#attach_std_item_attrs binding.pmb_attributes module_binding | Pstr_open od -> self#attach_std_item_attrs od.popen_attributes @@ - makeList ~postSpace:true [ - atom ("open" ^ (override od.popen_override)); - self#moduleExpressionToFormattedApplicationItems od.popen_expr; - ] + label ~space:true + (atom ("open" ^ (override od.popen_override))) + (self#moduleExpressionToFormattedApplicationItems od.popen_expr) | Pstr_modtype x -> let name = atom x.pmtd_name.txt in let letPattern = makeList ~postSpace:true [atom "module type"; name; atom "="] in diff --git a/test/modules.t/input.re b/test/modules.t/input.re index 9846a7660..3e7e4314b 100644 --- a/test/modules.t/input.re +++ b/test/modules.t/input.re @@ -540,3 +540,23 @@ let x = { module%foo rec X: Y = { let x = 1; } + +let f = () => { + open { + let x = 1; + }; + (); +}; + +let f = () => { + let open { + let x = 1; + }; + (); +}; + +open { + let x = 1; +}; + + diff --git a/test/modules.t/run.t b/test/modules.t/run.t index dc3fe3913..7c2d5cc62 100644 --- a/test/modules.t/run.t +++ b/test/modules.t/run.t @@ -706,4 +706,24 @@ Format modules module%foo rec X: Y = { let x = 1; }; + + let f = () => { + open { + let x = 1; + }; + + (); + }; + + let f = () => { + open { + let x = 1; + }; + + (); + }; + + open { + let x = 1; + }; /* From http://stackoverflow.com/questions/1986374/ higher-order-type-constructors-and-functors-in-ocaml */