1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
open! Import
type t = {
file_path : string;
main_module_name : string;
submodule_path : string loc list;
enclosing_module : string;
enclosing_value : string option;
value : string loc option;
in_expr : bool;
}
let remove_all_extensions basename =
match String.split_on_char ~sep:'.' basename with
| [] -> assert false
| name :: _ -> name
let top_level ~file_path =
let main_module_name =
file_path |> Stdlib.Filename.basename |> remove_all_extensions
|> String.capitalize_ascii
in
{
file_path;
main_module_name;
submodule_path = [];
enclosing_module = main_module_name;
enclosing_value = None;
value = None;
in_expr = false;
}
let file_path t = t.file_path
let main_module_name t = t.main_module_name
let enclosing_module t = t.enclosing_module
let enclosing_value t = t.enclosing_value
let submodule_path t =
List.rev_map ~f:(fun located -> located.txt) t.submodule_path
let value t = Option.map ~f:(fun located -> located.txt) t.value
let fully_qualified_path t =
let value = value t in
let submodule_path =
List.rev_map ~f:(fun located -> Some located.txt) t.submodule_path
in
let names = (Some t.main_module_name :: submodule_path) @ [ value ] in
String.concat ~sep:"." @@ List.filter_opt names
let enter_expr t = { t with in_expr = true }
let enter_module ~loc module_name t =
if t.in_expr then { t with enclosing_module = module_name }
else
{
t with
submodule_path = { txt = module_name; loc } :: t.submodule_path;
enclosing_module = module_name;
}
let enter_value ~loc value_name t =
if t.in_expr then { t with enclosing_value = Some value_name }
else
{
t with
value = Some { txt = value_name; loc };
enclosing_value = Some value_name;
}
let to_string_path t = String.concat ~sep:"." (t.file_path :: submodule_path t)
let with_string_path f ~loc ~path = f ~loc ~path:(to_string_path path);;
let module M = struct
let a = "lol"
end in
M.a