Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ppx_expand command with support for ppx_deriving #1764

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4a9486e
expand-node boilerplate
PizieDust Mar 18, 2024
c298306
Add parsetree processing functions
PizieDust Mar 18, 2024
bff7ee7
Mbrowse for parsetrees
PizieDust Mar 18, 2024
f732486
Browse_raw for parsetrees
PizieDust Mar 18, 2024
6c92b16
expand node logic
PizieDust Mar 18, 2024
bfd199d
add tests
PizieDust Mar 18, 2024
156d31e
refactor logic
PizieDust Apr 2, 2024
1e69de0
better json response
PizieDust Apr 2, 2024
69c5a59
use lexing locations
PizieDust Apr 2, 2024
00d5981
refactor type exceptions
PizieDust Apr 2, 2024
95dc061
discard tests of external dependencies
PizieDust Apr 2, 2024
adc61d3
custom ppx deriver that just renames
PizieDust Apr 2, 2024
c90b945
tests for expand-node feature
PizieDust Apr 2, 2024
4df0492
ensure location invariants by setting loc_ghost to true
PizieDust Apr 2, 2024
6058f97
cover all ghost locations
PizieDust Apr 3, 2024
e5b7765
updated changelog
PizieDust Apr 3, 2024
b412a7b
add eof to tests
PizieDust Apr 3, 2024
72c624a
better alignment
PizieDust May 8, 2024
d2d00d4
refactoring for better outputs
PizieDust May 8, 2024
a4db7b3
output deriver pos range for lsp
PizieDust May 8, 2024
d916c57
refactor ppx-expand logic
PizieDust May 8, 2024
a2e98d6
better tests
PizieDust May 8, 2024
2290c17
return list of ppx nodes and not only the head
PizieDust May 9, 2024
ecf3599
remove unused code
PizieDust May 10, 2024
8586b19
proper naming
PizieDust May 10, 2024
03fbae7
add ppx_rewriter for test
PizieDust May 10, 2024
9b5ec3a
add test for ppx extension nodes
PizieDust May 10, 2024
400a21d
add extension nodes and refactor code
PizieDust May 10, 2024
26f97ed
ppx extension tests
PizieDust May 10, 2024
3731578
restrict selection only to expressions under the cursor
PizieDust May 11, 2024
6ce434a
add support for ppx_deriving
PizieDust May 13, 2024
db3065a
update tests
PizieDust May 13, 2024
17b6886
refactor ppx rewriter logic
PizieDust May 13, 2024
afb472c
Merge branch 'master' of github.com:PizieDust/merlin into deriving_alt
PizieDust May 13, 2024
5930014
linting
PizieDust May 13, 2024
bec3e98
refactor logic, remove redundanct code
PizieDust May 13, 2024
4293202
support ppx_deriving
PizieDust May 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ merlin NEXT_VERSION
- Ignore SIGPIPE in the Merlin server process (#1746)
- Fix lexing of quoted strings in comments (#1754, fixes #1753)
- Improve cursor position detection in longidents (#1756)
- Implement new expand-node command for expanding PPX annotations (#1745)

merlin 4.14
===========
Expand Down
15 changes: 15 additions & 0 deletions src/frontend/ocamlmerlin/new/new_commands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,21 @@ Otherwise, Merlin looks for the documentation for the entity under the cursor (a
end
;

command "expand-node"
~doc: "Returns the generated code of a PPX."
~spec: [
arg "-position" "<position> Position to complete"
(marg_position (fun pos _pos -> pos));
]
~default: `None
begin fun buffer pos ->
match pos with
| `None -> failwith "-position <pos> is mandatory"
| #Msource.position as pos ->
run buffer (Query_protocol.Expand_node pos)
end
;

command "enclosing"
~spec: [
arg "-position" "<position> Position to complete"
Expand Down
15 changes: 15 additions & 0 deletions src/frontend/ocamlmerlin/query_json.ml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ let dump (type a) : a t -> json =
]
| Syntax_document pos ->
mk "syntax-document" [ ("position", mk_position pos) ]
| Expand_node pos ->
mk "ppx-expand" [ ("position", mk_position pos) ]
| Locate (prefix, look_for, pos) ->
mk "locate" [
"prefix", (match prefix with
Expand Down Expand Up @@ -392,6 +394,19 @@ let json_of_response (type a) (query : a t) (response : a) : json =
("url", `String info.documentation);
]
| `No_documentation -> `String "No documentation found")
| Expand_node _, resp ->
let str = match resp with
| `Found ppx_info ->
`Assoc
[
("code", `String ppx_info.code);
("deriver", `Assoc [
("start", Lexing.json_of_position ppx_info.deriver.a_start);
("end", Lexing.json_of_position ppx_info.deriver.a_end);
])
]
| `No_deriver -> `String "No PPX deriver/extension node found on this position"
in str
| Locate_type _, resp -> json_of_locate resp
| Locate _, resp -> json_of_locate resp
| Jump _, resp ->
Expand Down
56 changes: 56 additions & 0 deletions src/frontend/query_commands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,62 @@ let dispatch pipeline (type a) : a Query_protocol.t -> a =
| Some res -> `Found res
| None -> `No_documentation)

| Expand_node pos ->
let pos = Mpipeline.get_lexing_pos pipeline pos in
let parsetree = Mpipeline.reader_parsetree pipeline in
let ppx_parsetree = Mpipeline.ppx_parsetree pipeline in
let nodes = Mtyper.node_at_p parsetree pos in
let ppx_expansion ~ppx ~a_start ~a_end =
`Found ({
code = ppx;
deriver = {
a_start;
a_end
}
})
in
let check_at_pos (loc:Warnings.loc) =
Location_aux.compare_pos pos loc = 0
in
let has_ppx_deriver (attr:Parsetree.attribute) =
check_at_pos attr.attr_loc &&
attr.attr_name.txt = "deriving"
in
let has_ppx_extension (node:Browse_raw_p.node) =
match node with
| Expression {pexp_desc = Pexp_extension _; pexp_loc = loc; _} ->
check_at_pos loc
| _ -> false
in
let extension = List.find_opt ~f:has_ppx_extension nodes in
begin match extension with
| Some (Expression ({pexp_desc = Pexp_extension _; _} as exp)) ->
let nodes = Mtyper.node_at_p ppx_parsetree pos in
let derived_nodes =
Mbrowse_p.get_ext_children ~cursor_pos:pos ~expression_loc:(exp.pexp_loc) nodes in
ppx_expansion
~ppx:(Mbrowse_p.pprint_deriver_nodes () derived_nodes)
~a_start:(exp.pexp_loc.loc_start)
~a_end:(exp.pexp_loc.loc_end)
| Some _ | None ->
let nodes = Mtyper.node_at_p parsetree pos in
let has_deriving_attribute =
List.find_opt ~f:has_ppx_deriver
(List.concat_map ~f:(fun node ->
Browse_raw_p.node_attributes node) nodes)
in
(match has_deriving_attribute with
| Some attribute ->
let nodes = Mtyper.node_at_p ppx_parsetree pos in
let derived_nodes = Mbrowse_p.get_children ~cursor_pos:pos nodes in
ppx_expansion
~ppx:(Mbrowse_p.pprint_deriver_nodes () derived_nodes)
~a_start:(attribute.attr_loc.loc_start)
~a_end:(attribute.attr_loc.loc_end)
| None ->
`No_deriver)
end

| Locate (patho, ml_or_mli, pos) ->
let typer = Mpipeline.typer_result pipeline in
let local_defs = Mtyper.get_typedtree typer in
Expand Down
17 changes: 17 additions & 0 deletions src/frontend/query_protocol.ml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ type syntax_doc_result =
documentation : string
}

type ppx_deriver_pos =
{
a_start : Lexing.position;
a_end : Lexing.position;
}

type ppx_expand_result =
{
code : string;
deriver : ppx_deriver_pos
}

type is_tail_position = [`No | `Tail_position | `Tail_call]

type _ _bool = bool
Expand Down Expand Up @@ -145,6 +157,11 @@ type _ t =
-> [ `Found of syntax_doc_result
| `No_documentation
] t
| Expand_node
: Msource.position
-> [ `Found of ppx_expand_result
| `No_deriver
] t
| Locate_type
: Msource.position
-> [ `Found of string option * Lexing.position
Expand Down
Loading
Loading