Skip to content

Commit ab733da

Browse files
committed
merge extractors
1 parent 4ebeb19 commit ab733da

File tree

3 files changed

+63
-112
lines changed

3 files changed

+63
-112
lines changed

src/ppx_import.ml

Lines changed: 55 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -536,9 +536,6 @@ let rec module_type ~tool_name ~input_name ?(subst = []) modtype =
536536
(* Ex: module type%import Hashable = sig ... end *)
537537
raise_error ~loc:pmty_loc
538538
"[%%import] inline module type declaration is not supported"
539-
| Pmty_with (modtype, constraints) ->
540-
let subst = constraints |> List.map subst_of_constraint in
541-
module_type ~tool_name ~input_name ~subst modtype
542539
| Pmty_functor (_, _) ->
543540
raise_error ~loc:pmty_loc "[%%import] module type doesn't support functor"
544541
| Pmty_typeof _ ->
@@ -547,6 +544,9 @@ let rec module_type ~tool_name ~input_name ?(subst = []) modtype =
547544
raise_error ~loc:pmty_loc "[%%import] module type doesn't support extension"
548545
| Pmty_alias _ ->
549546
raise_error ~loc:pmty_loc "[%%import] module type doesn't support alias"
547+
| Pmty_with (modtype, constraints) ->
548+
let subst = constraints |> List.map subst_of_constraint in
549+
module_type ~tool_name ~input_name ~subst modtype
550550
| Pmty_ident longident ->
551551
let {txt = lid; loc} = longident in
552552
if tool_name = "ocamldep" then
@@ -648,89 +648,68 @@ let module_declaration_expand_intf ~ctxt modtype_decl =
648648
in
649649
Ppxlib.{psig_desc = Psig_modtype md_decl; psig_loc = loc}
650650

651-
let type_declaration_expander ~ctxt payload =
652-
let return_error e =
653-
let loc = Ppxlib.Expansion_context.Extension.extension_point_loc ctxt in
654-
let ext = Ppxlib.Location.error_extensionf ~loc "%s" e in
655-
Ppxlib.Ast_builder.Default.pstr_extension ext [] ~loc
656-
in
651+
type extracted_payload =
652+
| Type_decl of Ppxlib.rec_flag * Ppxlib.type_declaration list
653+
| Module_type_decl of Ppxlib.module_type_declaration
654+
655+
let type_extractor =
656+
Ppxlib.Ast_pattern.(
657+
pstr (pstr_type __ __ ^:: nil)
658+
||| psig (psig_type __ __ ^:: nil)
659+
|> map2 ~f:(fun rec_flag type_decl -> Type_decl (rec_flag, type_decl)) )
660+
661+
let module_type_extractor =
662+
Ppxlib.Ast_pattern.(
663+
psig (psig_modtype __ ^:: nil)
664+
||| pstr (pstr_modtype __ ^:: nil)
665+
|> map1 ~f:(fun modtype -> Module_type_decl modtype) )
666+
667+
let extractor = Ppxlib.Ast_pattern.(type_extractor ||| module_type_extractor)
668+
669+
let expander ~ctxt payload =
657670
match payload with
658-
| Parsetree.PStr [{pstr_desc = Pstr_type (rec_flag, type_decls); _}]
659-
|Parsetree.PSig [{psig_desc = Psig_type (rec_flag, type_decls); _}] ->
671+
| Type_decl (rec_flag, type_decls) ->
660672
type_declaration_expand ~ctxt rec_flag type_decls
661-
| Parsetree.PStr [{pstr_desc = Pstr_modtype modtype_decl; _}]
662-
|Parsetree.PSig [{psig_desc = Psig_modtype modtype_decl; _}] ->
673+
| Module_type_decl modtype_decl ->
663674
module_declaration_expand ~ctxt modtype_decl
664-
| Parsetree.PStr [{pstr_desc = _; _}] | Parsetree.PSig [{psig_desc = _; _}] ->
665-
return_error
666-
"[%%import] Expected a type declaration or a module type declaration"
667-
| Parsetree.PStr (_ :: _) | Parsetree.PSig (_ :: _) ->
668-
return_error
669-
"[%%import] Expected exactly one item in the structure or signature, but \
670-
found multiple items"
671-
| Parsetree.PStr [] | Parsetree.PSig [] ->
672-
return_error
673-
"[%%import] Expected exactly one item in the structure or signature, but \
674-
found none"
675-
| Parsetree.PTyp _ ->
676-
return_error
677-
"[%%import] Type pattern (PTyp) is not supported, only type and module \
678-
type declarations are allowed"
679-
| Parsetree.PPat (_, _) ->
680-
return_error
681-
"[%%import] Pattern (PPat) is not supported, only type and module type \
682-
declarations are allowed"
683-
684-
let type_declaration_extension =
675+
676+
let import_extension =
685677
Ppxlib.Extension.V3.declare "import" Ppxlib.Extension.Context.structure_item
686-
Ppxlib.Ast_pattern.(__)
687-
type_declaration_expander
688-
689-
let type_declaration_expander_intf ~ctxt payload =
690-
let return_error e =
691-
let loc = Ppxlib.Expansion_context.Extension.extension_point_loc ctxt in
692-
let ext = Ppxlib.Location.error_extensionf ~loc "%s" e in
693-
Ppxlib.Ast_builder.Default.psig_extension ext [] ~loc
694-
in
678+
extractor expander
679+
680+
let import_declaration_rule =
681+
Ppxlib.Context_free.Rule.extension import_extension
682+
683+
let type_extractor_intf =
684+
Ppxlib.Ast_pattern.(
685+
pstr (pstr_type __ __ ^:: nil)
686+
||| psig (psig_type __ __ ^:: nil)
687+
|> map2 ~f:(fun rec_flag type_decl -> Type_decl (rec_flag, type_decl)) )
688+
689+
let module_type_extractor_intf =
690+
Ppxlib.Ast_pattern.(
691+
psig (psig_modtype __ ^:: nil)
692+
||| pstr (pstr_modtype __ ^:: nil)
693+
|> map1 ~f:(fun modtype -> Module_type_decl modtype) )
694+
695+
let extractor_intf =
696+
Ppxlib.Ast_pattern.(type_extractor_intf ||| module_type_extractor_intf)
697+
698+
let expander_intf ~ctxt payload =
695699
match payload with
696-
| Parsetree.PStr [{pstr_desc = Pstr_type (rec_flag, type_decls); _}]
697-
|Parsetree.PSig [{psig_desc = Psig_type (rec_flag, type_decls); _}] ->
700+
| Type_decl (rec_flag, type_decls) ->
698701
type_declaration_expand_intf ~ctxt rec_flag type_decls
699-
| Parsetree.PStr [{pstr_desc = Pstr_modtype modtype_decl; _}]
700-
|Parsetree.PSig [{psig_desc = Psig_modtype modtype_decl; _}] ->
702+
| Module_type_decl modtype_decl ->
701703
module_declaration_expand_intf ~ctxt modtype_decl
702-
| Parsetree.PStr [{pstr_desc = _; _}] | Parsetree.PSig [{psig_desc = _; _}] ->
703-
return_error
704-
"[%%import] Expected a type declaration or a module type declaration"
705-
| Parsetree.PStr (_ :: _) | Parsetree.PSig (_ :: _) ->
706-
return_error
707-
"[%%import] Expected exactly one item in the structure or signature, but \
708-
found multiple items"
709-
| Parsetree.PStr [] | Parsetree.PSig [] ->
710-
return_error
711-
"[%%import] Expected exactly one item in the structure or signature, but \
712-
found none"
713-
| Parsetree.PTyp _ ->
714-
return_error
715-
"[%%import] Type pattern (PTyp) is not supported, only type and module \
716-
type declarations are allowed"
717-
| Parsetree.PPat (_, _) ->
718-
return_error
719-
"[%%import] Pattern (PPat) is not supported, only type and module type \
720-
declarations are allowed"
721-
722-
let type_declaration_extension_intf =
723-
Ppxlib.Extension.V3.declare "import" Ppxlib.Extension.Context.signature_item
724-
Ppxlib.Ast_pattern.(__)
725-
type_declaration_expander_intf
726704

727-
let type_declaration_rule =
728-
Ppxlib.Context_free.Rule.extension type_declaration_extension
705+
let import_extension_intf =
706+
Ppxlib.Extension.V3.declare "import" Ppxlib.Extension.Context.signature_item
707+
extractor_intf expander_intf
729708

730-
let type_declaration_rule_intf =
731-
Ppxlib.Context_free.Rule.extension type_declaration_extension_intf
709+
let import_declaration_rule_intf =
710+
Ppxlib.Context_free.Rule.extension import_extension_intf
732711

733712
let () =
734713
Ppxlib.Driver.V2.register_transformation
735-
~rules:[type_declaration_rule; type_declaration_rule_intf]
714+
~rules:[import_declaration_rule; import_declaration_rule_intf]
736715
"ppx_import"

src_test/ppx_deriving/errors/run.t

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ It's been fixed for later versions in https://github.com/ocaml/ocaml/pull/8541
116116
1 | [%%import:
117117
2 | type b = int
118118
3 | type a = string]
119-
Error: [%%import] Expected exactly one item in the structure or signature,
120-
but found multiple items
119+
Error: [] expected
121120

122121
Ptyp
123122
$ cat >test.ml <<EOF
@@ -128,8 +127,7 @@ Ptyp
128127
File "test.ml", line 1, characters 0-18:
129128
1 | [%%import: string]
130129
^^^^^^^^^^^^^^^^^^
131-
Error: [%%import] Type pattern (PTyp) is not supported, only type and module
132-
type declarations are allowed
130+
Error: PStr expected
133131
[1]
134132

135133
Inline module type declaration

src_test/ppx_deriving/errors_lte_407/run.t

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ Abstract module error
3939

4040
$ dune build
4141
File "test.ml", line 1, characters 23-30:
42-
1 | module type%import T = Stuff.T
43-
^^^^^^^
4442
Error: Imported module is abstract
4543
[1]
4644

@@ -87,8 +85,6 @@ Cannot find module error
8785

8886
$ dune build
8987
File "test.ml", line 1, characters 23-32:
90-
1 | module type%import A = Stuff.S.M
91-
^^^^^^^^^
9288
Error: [%import]: cannot find the module type M in Stuff.S
9389
[1]
9490

@@ -110,11 +106,7 @@ Ptyp
110106

111107
$ dune build
112108
File "test.ml", line 1, characters 0-18:
113-
1 | [%%import: string]
114-
^^^^^^^^^^^^^^^^^^
115-
Error: [%%import] Invalid extension usage. [%%import] only supports structure
116-
items, signatures or type declarations, but a type pattern (PTyp) was
117-
found.
109+
Error: PStr expected
118110
[1]
119111

120112
Inline module type declaration
@@ -124,8 +116,6 @@ Inline module type declaration
124116

125117
$ dune build
126118
File "test.ml", line 1, characters 30-44:
127-
1 | module type%import Hashable = sig type t end
128-
^^^^^^^^^^^^^^
129119
Error: [%%import] inline module type declaration is not supported
130120
[1]
131121

@@ -135,9 +125,7 @@ Functor
135125
> EOF
136126

137127
$ dune build
138-
File "test.ml", line 1, characters 33-57:
139-
1 | module type%import Foo = functor (M : sig end) -> sig end
140-
^^^^^^^^^^^^^^^^^^^^^^^^
128+
File "test.ml", line 1, characters 25-57:
141129
Error: [%%import] module type doesn't support functor
142130
[1]
143131

@@ -148,8 +136,6 @@ Module type of
148136

149137
$ dune build
150138
File "test.ml", line 1, characters 29-45:
151-
1 | module type%import Example = module type of A
152-
^^^^^^^^^^^^^^^^
153139
Error: [%%import] module type doesn't support typeof
154140
[1]
155141

@@ -160,8 +146,6 @@ Pmty_extension
160146

161147
$ dune build
162148
File "test.ml", line 1, characters 23-35:
163-
1 | module type%import M = [%extension]
164-
^^^^^^^^^^^^
165149
Error: [%%import] module type doesn't support extension
166150
[1]
167151

@@ -186,8 +170,6 @@ Pwith_module
186170

187171
$ dune build
188172
File "test.ml", line 15, characters 16-30:
189-
15 | end with module StringHashable = StringHashable
190-
^^^^^^^^^^^^^^
191173
Error: [%%import]: Pwith_module constraint is not supported.
192174
[1]
193175

@@ -211,10 +193,8 @@ Pwith_modtype
211193
> EOF
212194

213195
$ dune build
214-
File "test.ml", line 15, characters 21-35:
215-
15 | end with module type StringHashable = StringHashable
216-
^^^^^^^^^^^^^^
217-
Error: [%%import]: Pwith_modtype constraint is not supported.
196+
File "test.ml", line 15, characters 16-20:
197+
Error: Syntax error
218198
[1]
219199

220200
Pwith_typesubst
@@ -224,8 +204,6 @@ Pwith_typesubst
224204

225205
$ dune build
226206
File "test.ml", line 1, characters 63-64:
227-
1 | module type%import HashableWith = Hashtbl.HashedType with type t := string
228-
^
229207
Error: [%%import]: Pwith_typesubst constraint is not supported.
230208
[1]
231209

@@ -249,10 +227,8 @@ Pwith_modtypesubst
249227
> EOF
250228

251229
$ dune build
252-
File "test.ml", line 15, characters 21-35:
253-
15 | end with module type StringHashable := StringHashable
254-
^^^^^^^^^^^^^^
255-
Error: [%%import]: Pwith_modtypesubst constraint is not supported.
230+
File "test.ml", line 15, characters 16-20:
231+
Error: Syntax error
256232
[1]
257233

258234
Pwith_modsubst
@@ -276,7 +252,5 @@ Pwith_modsubst
276252

277253
$ dune build
278254
File "test.ml", line 15, characters 16-30:
279-
15 | end with module StringHashable := StringHashable
280-
^^^^^^^^^^^^^^
281255
Error: [%%import]: Pwith_modsubst constraint is not supported.
282256
[1]

0 commit comments

Comments
 (0)