···2020 | Subtree (addr, _) -> addr
2121 | Verbatim _ | Math (_, _) | Ident _ | Hash_ident _ | Xml_ident _ | Let (_, _, _) | Open _ | Scope _ | Put (_, _) | Default (_, _) | Get _ | Fun (_, _) | Object _ | Patch _ | Call (_, _) | Def (_, _, _) | Decl_xmlns (_, _) | Alloc _ | Namespace (_, _) | _ -> None
22222323-(* TODO: Think about this some more. *)
2424-let rec flatten (tree : Code.t) : Code.t =
2525- tree
2626- |> List.concat_map @@ fun (node : 'a Range.located) ->
2727- match node.value with
2828- | Code.Subtree (_, nodes)
2929- | Code.Scope nodes ->
3030- flatten nodes
3131- | _ -> [node]
3232-3333-let contains = fun
3434- ~(position : Lsp.Types.Position.t)
3535- (located : _ Range.located)
3636- ->
3737- let L.Position.{line = cursor_line; character = cursor_character} = position in
3838- match located.loc with
3939- | Some loc ->
4040- begin
4141- match Range.view loc with
4242- | `Range (start, end_) ->
4343- let start_pos = Lsp_shims.Loc.lsp_pos_of_pos start in
4444- let end_pos = Lsp_shims.Loc.lsp_pos_of_pos end_ in
4545- let at_or_after_start =
4646- cursor_line < end_pos.line
4747- || (cursor_line = start_pos.line && start_pos.character <= cursor_character)
4848- in
4949- let before_or_at_end =
5050- end_pos.line > cursor_line
5151- || (cursor_line = end_pos.line && cursor_character <= end_pos.character)
5252- in
5353- at_or_after_start && before_or_at_end
5454- | _ -> false
5555- end
5656- | None -> false
5757-5823let nodes_within (node : Code.node Range.located) =
5924 match node.value with
6025 | Code.Math (_, t)
···7035 | Code.Dx_const_content t
7136 | Code.Call (t, _)
7237 | Code.Subtree (_, t) ->
7373- Some t
3838+ t
7439 | Code.Dx_prop (_, t)
7540 | Code.Dx_query (_, _, t)
7641 | Code.Dx_sequent (_, t) ->
7777- Some (List.concat t)
4242+ (List.concat t)
7843 | Code.Object {methods; _} ->
7979- Some (methods |> List.map snd |> List.concat)
4444+ (methods |> List.map snd |> List.concat)
8045 | Code.Patch {obj; methods; _} ->
8146 let methods = (methods |> List.map snd |> List.concat) in
8282- Some (List.append obj methods)
4747+ (List.append obj methods)
8348 | Code.Text _
8449 | Code.Verbatim _
8550 | Code.Ident _
···9358 | Code.Dx_var _
9459 | Code.Comment _
9560 | Code.Error _ ->
9696- None
6161+ []
6262+6363+let flatten (tree : Code.t) : Code.t =
6464+ List.concat_map nodes_within tree
6565+6666+let contains = fun
6767+ ~(position : Lsp.Types.Position.t)
6868+ (located : _ Range.located)
6969+ ->
7070+ let L.Position.{line = cursor_line; character = cursor_character} = position in
7171+ match located.loc with
7272+ | Some loc ->
7373+ begin
7474+ match Range.view loc with
7575+ | `Range (start, end_) ->
7676+ let start_pos = Lsp_shims.Loc.lsp_pos_of_pos start in
7777+ let end_pos = Lsp_shims.Loc.lsp_pos_of_pos end_ in
7878+ let at_or_after_start =
7979+ cursor_line < end_pos.line
8080+ || (cursor_line = start_pos.line && start_pos.character <= cursor_character)
8181+ in
8282+ let before_or_at_end =
8383+ end_pos.line > cursor_line
8484+ || (cursor_line = end_pos.line && cursor_character <= end_pos.character)
8585+ in
8686+ at_or_after_start && before_or_at_end
8787+ | _ -> false
8888+ end
8989+ | None -> false
97909891let rec node_at ~(position : Lsp.Types.Position.t) (code : _ list) : Code.node Range.located option =
9992 let flattened = flatten code in
10093 match List.find_opt (contains ~position) flattened with
10194 | None -> None
10295 | Some n ->
103103- match Option.bind (nodes_within n) (node_at ~position) with
9696+ match (node_at ~position) (nodes_within n) with
10497 | Some inner -> Some inner
10598 | None -> Some n
10699
+20-13
lib/language_server/Definitions.ml
···55 *
66 *)
7788-(* open Forester_core *)
99-(* open Forester_frontend *)
88+open Forester_core
99+open Forester_compiler
10101111module L = Lsp.Types
1212+open State.Syntax
12131314let (let*) = Option.bind
1415···1819 =
1920 match params with
2021 | {textDocument;
2222+ position;
2123 _;
2224 } ->
2323- (* let server = State.get () in *)
2424- (* let host = server.config.host in *)
2525- (* let codes = server.parsed in *)
2626- (* let resolver = Compiler.make_resolver ~host: server.config.host codes in *)
2727- (* let* { code; _ } = Compiler.resolve ~host textDocument.uri codes in *)
2828- (* let* addr = Analysis.addr_at ~position code in *)
2929- (* let uri = URI_scheme.user_uri ~host: server.config.host addr in *)
3030- (* let* uri = Hashtbl.find_opt resolver uri in *)
3131- let range = L.Range.create ~start: {character = 1; line = 0} ~end_: {character = 1; line = 0} in
3232- Some
3333- (`Location [L.Location.{uri = textDocument.uri; range}])
2525+ let Lsp_state.{forest; _} = Lsp_state.get () in
2626+ let host = forest.config.host in
2727+ let uri = URI_scheme.lsp_uri_to_uri ~host textDocument.uri in
2828+ match Option.bind forest.={uri} Tree.to_code with
2929+ | None -> None
3030+ | Some code ->
3131+ match Analysis.addr_at ~position code.nodes with
3232+ | None -> assert false
3333+ | Some addr ->
3434+ let uri = URI_scheme.user_uri ~host addr in
3535+ let path = URI.Tbl.find forest.resolver uri in
3636+ let uri = Lsp.Uri.of_path path in
3737+ Logs.debug (fun m -> m "Definitions: %s" path);
3838+ let range = L.Range.create ~start: {character = 1; line = 0} ~end_: {character = 1; line = 0} in
3939+ Some
4040+ (`Location [L.Location.{uri; range}])
+7-4
lib/language_server/test/Test_lsp.ml
···9797 let@ () = Reporter.easy_run in
9898 let path = find_tree "tfmt-0005" in
9999 let textDocument : L.TextDocumentIdentifier.t = {uri = Lsp.Uri.of_path path} in
100100- let position = L.Position.create ~line: 17 ~character: 1 in
100100+ let position = L.Position.create ~line: 16 ~character: 13 in
101101 let params = L.DefinitionParams.create ~position ~textDocument () in
102102 let result =
103103 Handlers.Definitions.compute params |> function
104104 | Some (`Location locations) -> locations
105105- | _ -> assert false
105105+ | Some (`LocationLink _location_links) ->
106106+ assert false
107107+ (* location_links *)
108108+ | None -> assert false
106109 in
107110 Alcotest.(check int) "" 1 (List.length result);
108111 let start = L.Position.create ~character: 1 ~line: 0 in
109112 let end_ = L.Position.create ~character: 1 ~line: 0 in
110113 let range = L.Range.create ~start ~end_ in
111111- let uri = Lsp.Uri.of_path path in
114114+ let uri = Lsp.Uri.of_path @@ find_tree "tfmt-0006" in
112115 Alcotest.(check location)
113116 ""
114117 (L.Location.create ~range ~uri)
···269272 let result = Handlers.Inlay_hint.compute params in
270273 Alcotest.(check int)
271274 ""
272272- 11
275275+ 25
273276 (List.length @@ Option.get result)
274277275278let test_workspace_symbols () =