Skip to content

Commit 0d8bdd9

Browse files
committed
Add naive support for Papply in reconstruct identifier
This treat an application as a single components so it is not a satisfing long-term solution. A better approach would be to change the return type of [reconstruct_identifier] to account for module application. This fixes #1610
1 parent bfaa163 commit 0d8bdd9

File tree

2 files changed

+99
-29
lines changed

2 files changed

+99
-29
lines changed

src/kernel/mreader_lexer.ml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
open Std
3030

31+
let {Logger. log} = Logger.for_section "mreader_lexer"
32+
3133
type keywords = Lexer_raw.keywords
3234

3335
type triple = Parser_raw.token * Lexing.position * Lexing.position
@@ -223,6 +225,15 @@ let is_operator = function
223225
»
224226
*)
225227

228+
let print_token fmt = function
229+
| LIDENT s -> Format.fprintf fmt "LIDENT %s" s
230+
| UIDENT s -> Format.fprintf fmt "UIDENT %s" s
231+
| LPAREN -> Format.fprintf fmt "LPAREN"
232+
| RPAREN -> Format.fprintf fmt "RPAREN"
233+
| DOT -> Format.fprintf fmt "DOT"
234+
| EOF -> Format.fprintf fmt "EOF"
235+
| _ -> Format.fprintf fmt "OTHER";;
236+
226237
let reconstruct_identifier_from_tokens tokens pos =
227238
let rec look_for_component acc = function
228239

@@ -246,6 +257,36 @@ let reconstruct_identifier_from_tokens tokens pos =
246257
when is_operator token <> None && acc = [] ->
247258
look_for_dot [item] items
248259

260+
(* RPAREN UIDENT means that we are in presence of a functor application. *)
261+
| (RPAREN, _, end_pos) :: ((UIDENT _, _, _ ) as item) :: items
262+
when acc <> [] ->
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
289+
249290
(* An operator alone is an identifier on its own *)
250291
| (token, _, _ as item) :: items
251292
when is_operator token <> None && acc = [] ->
@@ -257,6 +298,11 @@ let reconstruct_identifier_from_tokens tokens pos =
257298

258299
| [] -> raise Not_found
259300

301+
and group_until_lparen acc = function
302+
| (LPAREN,_,_) :: items -> acc, items
303+
| item :: items -> group_until_lparen (item::acc) items
304+
| _ -> raise Not_found
305+
260306
and look_for_dot acc = function
261307
| (DOT,_,_) :: items -> look_for_component acc items
262308
| items -> check acc items
@@ -312,6 +358,9 @@ let reconstruct_identifier config source pos =
312358
let lexbuf = Lexing.from_string (Msource.text source) in
313359
Location.init lexbuf (Mconfig.filename config);
314360
let tokens = lex [] lexbuf in
361+
log ~title:"from_tokens" "%a" Logger.fmt (fun fmt ->
362+
Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ";@ ")
363+
(fun fmt (tok, _, _) -> print_token fmt tok) fmt tokens);
315364
reconstruct_identifier_from_tokens tokens pos
316365

317366
let is_uppercase {Location. txt = x; _} =

tests/test-dirs/locate/issue1610.t

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +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-
FIXME: we should jump to the functor's body, not the current definition
16-
This is due to an issue with identifier-reconstruction
17-
$ $MERLIN single locate -look-for ml -position 11:15 \
18-
> -filename main.ml <main.ml
19+
We should jump to the functor's body (line 7)
20+
$ $MERLIN single locate -look-for ml -position 15:18 \
21+
> -filename main.ml <main.ml | jq '.value.pos'
22+
{
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,
32+
"col": 2
33+
}
34+
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'
38+
{
39+
"line": 11,
40+
"col": 0
41+
}
42+
43+
Should jump to M's definition (line 6)
44+
$ $MERLIN single locate -look-for ml -position 15:11 \
45+
> -filename main.ml <main.ml | jq '.value.pos'
46+
{
47+
"line": 6,
48+
"col": 2
49+
}
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'
1954
{
20-
"class": "return",
21-
"value": {
22-
"file": "$TESTCASE_ROOT/main.ml",
23-
"pos": {
24-
"line": 11,
25-
"col": 0
26-
}
27-
},
28-
"notifications": []
55+
"line": 5,
56+
"col": 0
2957
}
3058

31-
It works as expected when the user inputs the expression manually
32-
$ $MERLIN single locate -prefix 'M(T).t' -look-for ml -position 11:15 \
33-
> -filename main.ml <main.ml
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'
3462
{
35-
"class": "return",
36-
"value": {
37-
"file": "$TESTCASE_ROOT/main.ml",
38-
"pos": {
39-
"line": 6,
40-
"col": 2
41-
}
42-
},
43-
"notifications": []
63+
"line": 7,
64+
"col": 4
4465
}

0 commit comments

Comments
 (0)