Skip to content

Commit

Permalink
Merge pull request #1333 from voodoos/construct-part-I.I-module-holes
Browse files Browse the repository at this point in the history
Add Module holes to the parser and AST
  • Loading branch information
voodoos authored May 11, 2021
2 parents ae21420 + f8bfb48 commit e0f4648
Show file tree
Hide file tree
Showing 41 changed files with 4,777 additions and 4,400 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ git version
ocaml/ocaml-lsp#375)
- fix location of module definitions done via functors (#1329, fixes #1199)
- fix -cmt-path dirs mistakenly added to build path (#1330)
- add new module holes that can replace module expressions (#1333)

merlin 4.2
==========
Expand Down
1 change: 1 addition & 0 deletions src/analysis/type_enclosing.ml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ let from_nodes ~path =
ret (Type (env, t))
| Type_declaration { typ_id = id; typ_type = t} ->
ret (Type_decl (env, id, t))
| Module_expr {mod_type = Types.Mty_for_hole} -> None
| Module_expr {mod_type = m}
| Module_type {mty_type = m}
| Module_binding {mb_expr = {mod_type = m}}
Expand Down
5 changes: 5 additions & 0 deletions src/analysis/typedtrie.ml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ let remove_indir_me me =
| Typedtree.Tmod_apply (me1, me2, _) -> `Apply (me1, me2)
| Typedtree.Tmod_constraint (me, _, _, _) -> `Mod_expr me
| Typedtree.Tmod_unpack _ -> `Unpack
| Typedtree.Tmod_hole -> `Hole

let remove_indir_mty mty =
match mty.Typedtree.mty_desc with
Expand Down Expand Up @@ -287,10 +288,13 @@ let rec build ~local_buffer ~trie browses : t =
Apply { funct; arg }
| `Unpack -> (* TODO! *)
Leaf
| `Hole ->
Leaf
and functor_ : _ -> Trie.functor_ = function
| `Alias path
| `Ident path -> Named (Namespaced_path.of_path ~namespace:`Mod path)
| `Str _
| `Hole
| `Sg _ -> assert false
| `Mod_expr me -> functor_ (remove_indir_me me)
| `Mod_type _ -> assert false
Expand Down Expand Up @@ -380,6 +384,7 @@ let rec build ~local_buffer ~trie browses : t =
| `Sg sg ->
let sg = lazy (build ~local_buffer ~trie [of_signature sg]) in
f (Included (Items sg))
| `Hole -> f Leaf
in
helper packed
end
Expand Down
23 changes: 17 additions & 6 deletions src/frontend/query_commands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -622,14 +622,25 @@ let dispatch pipeline (type a) : a Query_protocol.t -> a =
let verbosity = verbosity pipeline in
let nodes = Mbrowse.of_typedtree (Mtyper.get_typedtree typer) in
let ppf = Format.str_formatter in
let print ~nodes loc env type_ () =
match type_ with
| `Exp type_expr ->
Type_utils.print_type_with_decl ~verbosity env ppf type_expr
| `Mod module_type ->
(* For module_expr holes we need the type of the next enclosing
to get a useful result *)
match Mbrowse.enclosing (loc.Location.loc_start) [nodes] with
| _ :: (_, Browse_raw.Module_expr { mod_type; _}) :: _ ->
Printtyp.modtype env ppf mod_type
| _ ->
Printtyp.modtype env ppf module_type
in
let loc_and_types_of_holes node =
List.map (Browse_raw.all_holes node)
~f:(fun (loc, env, type_expr) ->
List.map (Browse_raw.all_holes node) ~f:(
fun (loc, env, type_) ->
Printtyp.wrap_printing_env env ~verbosity
(fun () ->
Type_utils.print_type_with_decl ~verbosity env ppf type_expr);
(loc, Format.flush_str_formatter ())
)
(print ~nodes loc env type_);
(loc, Format.flush_str_formatter ()))
in
List.concat_map ~f:loc_and_types_of_holes nodes

Expand Down
10 changes: 9 additions & 1 deletion src/ocaml/merlin_specific/browse_raw.ml
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ and of_module_expr_desc = function
app (Module_type_constraint mtc)
| Tmod_unpack (e,_) ->
of_expression e
| Tmod_hole -> id_fold

and of_structure_item_desc = function
| Tstr_eval (e,_) ->
Expand Down Expand Up @@ -903,7 +904,14 @@ let all_holes (env, node) =
exp_type;
exp_env;
_
} -> (exp_loc, exp_env, exp_type) :: acc
} -> (exp_loc, exp_env, `Exp exp_type) :: acc
| Module_expr {
mod_desc = Tmod_hole;
mod_loc;
mod_type;
mod_env;
_
} -> (mod_loc, mod_env, `Mod mod_type) :: acc
| _ -> aux acc (env, node)
in
fold_node f env node acc
Expand Down
6 changes: 5 additions & 1 deletion src/ocaml/merlin_specific/browse_raw.mli
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,8 @@ val node_is_constructor : node ->

val node_of_binary_part : Env.t -> Cmt_format.binary_part -> node

val all_holes : Env.t * node -> (Location.t * Env.t * Types.type_expr) list
val all_holes :
Env.t * node ->
(Location.t *
Env.t *
[`Exp of Types.type_expr | `Mod of Types.module_type]) list
1 change: 1 addition & 0 deletions src/ocaml/merlin_specific/typer_raw.ml
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ module Rewrite_loc = struct
Pmod_constraint (u_module_expr me, u_module_type mt)
| Pmod_unpack e -> Pmod_unpack (u_expression e)
| Pmod_extension ext -> Pmod_extension (u_extension ext)
| Pmod_hole -> Pmod_hole

and u_structure l = List.map ~f:u_structure_item l

Expand Down
1 change: 1 addition & 0 deletions src/ocaml/parsing/ast_helper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ let mk ?(loc = !default_loc) ?(attrs = []) d =
let constraint_ ?loc ?attrs m mty = mk ?loc ?attrs (Pmod_constraint (m, mty))
let unpack ?loc ?attrs e = mk ?loc ?attrs (Pmod_unpack e)
let extension ?loc ?attrs a = mk ?loc ?attrs (Pmod_extension a)
let hole ?loc ?attrs () = mk ?loc ?attrs Pmod_hole
end

module Sig = struct
Expand Down
1 change: 1 addition & 0 deletions src/ocaml/parsing/ast_helper.mli
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ module Mod:
module_expr
val unpack: ?loc:loc -> ?attrs:attrs -> expression -> module_expr
val extension: ?loc:loc -> ?attrs:attrs -> extension -> module_expr
val hole: ?loc:loc -> ?attrs:attrs -> unit -> module_expr
end

(** Signature items *)
Expand Down
1 change: 1 addition & 0 deletions src/ocaml/parsing/ast_iterator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ module M = struct
sub.module_expr sub m; sub.module_type sub mty
| Pmod_unpack e -> sub.expr sub e
| Pmod_extension x -> sub.extension sub x
| Pmod_hole -> ()

let iter_structure_item sub {pstr_loc = loc; pstr_desc = desc} =
sub.location sub loc;
Expand Down
1 change: 1 addition & 0 deletions src/ocaml/parsing/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ module M = struct
(sub.module_type sub mty)
| Pmod_unpack e -> unpack ~loc ~attrs (sub.expr sub e)
| Pmod_extension x -> extension ~loc ~attrs (sub.extension sub x)
| Pmod_hole -> hole ~loc ~attrs ()

let map_structure_item sub {pstr_loc = loc; pstr_desc = desc} =
let open Str in
Expand Down
2 changes: 2 additions & 0 deletions src/ocaml/parsing/parsetree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,8 @@ and module_expr_desc =
(* (val E) *)
| Pmod_extension of extension
(* [%id] *)
| Pmod_hole
(* _ *)

and structure = structure_item list

Expand Down
2 changes: 2 additions & 0 deletions src/ocaml/parsing/pprintast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,8 @@ and module_expr ctxt f x =
| Pmod_unpack e ->
pp f "(val@ %a)" (expression ctxt) e
| Pmod_extension e -> extension ctxt f e
| Pmod_hole ->
pp f "_"

and structure ctxt f x = list ~sep:"@\n" (structure_item ctxt) f x

Expand Down
2 changes: 2 additions & 0 deletions src/ocaml/parsing/printast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,8 @@ and module_expr i ppf x =
| Pmod_extension (s, arg) ->
line i ppf "Pmod_extension \"%s\"\n" s.txt;
payload i ppf arg
| Pmod_hole ->
line i ppf "Pmod_hole"

and structure i ppf x = list i structure_item ppf x

Expand Down
5,426 changes: 2,733 additions & 2,693 deletions src/ocaml/preprocess/parser_raw.ml

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions src/ocaml/preprocess/parser_raw.mly
Original file line number Diff line number Diff line change
Expand Up @@ -656,8 +656,8 @@ let expr_of_lwt_bindings ~loc lbs body =

let default_pattern () = Pat.any ~loc:!default_loc ()

let default_module_expr () = Mod.structure ~loc:!default_loc[]
let default_module_type () = Mty.signature ~loc:!default_loc[]
let default_module_expr () = Mod.structure ~loc:!default_loc []
let default_module_type () = Mty.signature ~loc:!default_loc []
]

/* Tokens */
Expand Down Expand Up @@ -1341,6 +1341,9 @@ module_expr [@recovery default_module_expr ()]:
| (* An extension. *)
ex = extension
{ Pmod_extension ex }
| (* A hole. *)
UNDERSCORE
{ Pmod_hole }
)
{ $1 }
;
Expand Down
Loading

0 comments on commit e0f4648

Please sign in to comment.