Skip to content

Commit 91507bd

Browse files
committed
Make reconstruct_identifier aware of Papply
1 parent 70c9582 commit 91507bd

File tree

2 files changed

+72
-30
lines changed

2 files changed

+72
-30
lines changed

src/kernel/mreader_lexer.ml

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,34 @@ let reconstruct_identifier_from_tokens tokens pos =
258258
look_for_dot [item] items
259259

260260
(* RPAREN UIDENT means that we are in presence of a functor application. *)
261-
| (RPAREN, _, end_pos) :: ((UIDENT s, _, _ ) as _item) :: items
261+
| (RPAREN, _, end_pos) :: ((UIDENT _, _, _ ) as item) :: items
262262
when acc <> [] ->
263-
let app, start_pos, items =
264-
look_for_apply ~inside_paren:true [ s; ")"] items
265-
in
266-
look_for_dot ((UIDENT app, start_pos, end_pos ) :: acc) items
263+
let param_items, items = group_until_lparen [item] items in
264+
begin try
265+
begin try
266+
(* Is the cursor on the parameter ? *)
267+
look_for_dot [] (List.rev param_items)
268+
with Not_found ->
269+
(* Is the cursor on the functor or before ? *)
270+
look_for_component [] items
271+
end
272+
with Not_found ->
273+
(* The cursor must be after the application [M.N(F).|t]
274+
We make a single component with the applciation and continue *)
275+
match items with
276+
| (UIDENT f, start_pos, _ ) :: items ->
277+
let app =
278+
let param = List.map ~f:(function
279+
| (DOT, _, _ ) -> "."
280+
| (UIDENT s, _, _) -> s
281+
| _ -> raise Not_found
282+
) param_items
283+
in
284+
Format.sprintf "%s(%s)" f (String.concat ~sep:"" param)
285+
in
286+
look_for_dot ((UIDENT app, start_pos, end_pos ) :: acc) items
287+
| _ -> raise Not_found
288+
end
267289

268290
(* An operator alone is an identifier on its own *)
269291
| (token, _, _ as item) :: items
@@ -276,16 +298,9 @@ let reconstruct_identifier_from_tokens tokens pos =
276298

277299
| [] -> raise Not_found
278300

279-
(* FIXME: this function treats applications as a single component ["M(N.P)"].
280-
This prevent jumping to M, N or P. *)
281-
and look_for_apply ~inside_paren acc = function
282-
| (LPAREN, _, _) :: items when inside_paren ->
283-
look_for_apply ~inside_paren:false ("(" :: acc) items
284-
| (UIDENT s, _, _) :: items when inside_paren ->
285-
look_for_apply ~inside_paren (s :: "." :: acc) items
286-
| (UIDENT s, start_pos, _) :: items when not inside_paren ->
287-
let item = String.concat ~sep:"" (s :: acc) in
288-
item, start_pos, items
301+
and group_until_lparen acc = function
302+
| (LPAREN,_,_) :: items -> acc, items
303+
| item :: items -> group_until_lparen (item::acc) items
289304
| _ -> raise Not_found
290305

291306
and look_for_dot acc = function

tests/test-dirs/locate/issue1610.t

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,63 @@
33
> type 'a t
44
> end
55
>
6-
> module M (T : T) = struct
7-
> type t = int T.t
6+
> module N = struct
7+
> module M (T : T) = struct
8+
> type t = int T.t
9+
> end
810
> end
911
>
10-
> module T = struct type 'a t end
12+
> module F = struct
13+
> module T = struct type 'a t end
14+
> end
1115
>
12-
> type t = M(T).t
16+
> type u = N.M(F.T).t
1317
> EOF
1418

15-
We should jump to the functor's body
16-
$ $MERLIN single locate -look-for ml -position 11:15 \
19+
We should jump to the functor's body (line 7)
20+
$ $MERLIN single locate -look-for ml -position 15:18 \
1721
> -filename main.ml <main.ml | jq '.value.pos'
1822
{
19-
"line": 6,
23+
"line": 7,
24+
"col": 4
25+
}
26+
27+
Should jump to T's definition (line 12)
28+
$ $MERLIN single locate -look-for ml -position 15:15 \
29+
> -filename main.ml <main.ml | jq '.value.pos'
30+
{
31+
"line": 12,
2032
"col": 2
2133
}
2234

23-
FIXME: should jump to T's definition
24-
$ $MERLIN single locate -look-for ml -position 11:11 \
25-
> -filename main.ml <main.ml
35+
Should jump to F's definition (line 11)
36+
$ $MERLIN single locate -look-for ml -position 15:13 \
37+
> -filename main.ml <main.ml | jq '.value.pos'
2638
{
27-
"class": "return",
28-
"value": "didn't manage to find M(T)",
29-
"notifications": []
39+
"line": 11,
40+
"col": 0
3041
}
3142

32-
It also works as expected when the user inputs the expression manually
33-
$ $MERLIN single locate -prefix 'M(T).t' -look-for ml -position 11:15 \
43+
Should jump to M's definition (line 6)
44+
$ $MERLIN single locate -look-for ml -position 15:11 \
3445
> -filename main.ml <main.ml | jq '.value.pos'
3546
{
3647
"line": 6,
3748
"col": 2
3849
}
50+
51+
Should jump to N's definition (line 5)
52+
$ $MERLIN single locate -look-for ml -position 15:9 \
53+
> -filename main.ml <main.ml | jq '.value.pos'
54+
{
55+
"line": 5,
56+
"col": 0
57+
}
58+
59+
It also works as expected when the user inputs the expression manually
60+
$ $MERLIN single locate -prefix 'N.M(F.T).t' -look-for ml -position 15:18 \
61+
> -filename main.ml <main.ml | jq '.value.pos'
62+
{
63+
"line": 7,
64+
"col": 4
65+
}

0 commit comments

Comments
 (0)