Select the types of activity you want to include in your feed.
Factor out Actions module
- track history in compiler state - fix issue in `Did_change` and `Did_open` handler that resulted in unparsed trees. This fixes the definitions handler. - Add some tests
···11+(*
22+ * SPDX-FileCopyrightText: 2024 The Forester Project Contributors
33+ *
44+ * SPDX-License-Identifier: GPL-3.0-or-later
55+ *)
66+77+open Forester_core
88+99+type exit =
1010+ Fail | Finished
1111+[@@deriving show]
1212+1313+type t =
1414+ | Quit of exit
1515+ | Build_import_graph
1616+ | Plant_assets
1717+ | Plant_foreign
1818+ | Done
1919+ | Load_all_configured_dirs
2020+ | Parse_all
2121+ | Expand_all
2222+ | Eval_all
2323+ | Load_tree of (Eio.Fs.dir_ty Eio.Path.t [@printer Eio.Path.pp])
2424+ | Parse of (Lsp.Uri.t [@printer fun fmt uri -> fprintf fmt "%s" (Lsp.Uri.to_string uri)])
2525+ | Expand of URI.t
2626+ | Eval of URI.t
2727+ | Query of (string, Vertex.t) Datalog_expr.query
2828+ | Query_results of (Vertex_set.t [@opaque])
2929+ | Report_errors of ((Reporter.Message.t Asai.Diagnostic.t [@opaque]) list * t)
3030+ | Run_jobs of Job.job Range.located list
3131+[@@deriving show]
3232+3333+let report ~next_action ~errors =
3434+ if List.length errors > 0 then
3535+ Report_errors (errors, next_action)
3636+ else next_action
+4-41
lib/compiler/Driver.ml
···10101111module T = Types
12121313-module Action = struct
1414- type exit =
1515- Fail | Finished
1616- [@@deriving show]
1717-1818- type t =
1919- | Quit of exit
2020- | Build_import_graph
2121- | Plant_assets
2222- | Plant_foreign
2323- | Done
2424- | Load_all_configured_dirs
2525- | Parse_all
2626- | Expand_all
2727- | Eval_all
2828- | Load_tree of (Eio.Fs.dir_ty Eio.Path.t [@printer Eio.Path.pp])
2929- | Parse of (Lsp.Uri.t [@printer fun fmt uri -> fprintf fmt "%s" (Lsp.Uri.to_string uri)])
3030- | Expand of URI.t
3131- | Eval of URI.t
3232- | Query of (string, Vertex.t) Datalog_expr.query
3333- | Query_results of (Vertex_set.t [@opaque])
3434- | Report_errors of ((Reporter.Message.t Asai.Diagnostic.t [@opaque]) list * t)
3535- | Run_jobs of Job.job Range.located list
3636- [@@deriving show]
3737-3838- let report ~next_action ~errors =
3939- if List.length errors > 0 then
4040- Report_errors (errors, next_action)
4141- else next_action
4242-end
4343-4444-let update
4545- : Action.t -> State.t -> Action.t * State.t
4646-= fun action forest ->
1313+let update (action : Action.t) (forest : State.t) =
4714 let open Action in
4815 let host = forest.config.host in
1616+ let forest = State.update_history forest action in
4917 match action with
5018 | Quit e ->
5119 begin
···224192let implant_foreign = run_until_done Plant_foreign
225193let plant_assets = run_until_done Plant_assets
226194227227-let batch_run_with_history ~env ~(config : Config.t) ~dev =
228228- let history = ref [] in
195195+let batch_run ~env ~(config : Config.t) ~dev =
229196 let init =
230197 State.make ~env ~config ~dev ()
231198 |> plant_assets
232199 |> implant_foreign
233200 in
234201 let rec go action state =
235235- history := action :: !history;
236202 let new_action, new_state = update action state in
237203 match action with
238204 | Quit Fail -> exit 1
···246212 | _ ->
247213 go new_action new_state
248214 in
249249- let history = !history in
250250- go Load_all_configured_dirs init, history
251251-252252-let batch_run ~env ~config ~dev = fst @@ batch_run_with_history ~env ~config ~dev
215215+ go Load_all_configured_dirs init
253216254217let language_server ~env ~config =
255218 let init = State.make ~env ~config ~dev: true () in
+1
lib/compiler/Forester_compiler.ml
···4343module Forest = Forest
4444(** Augmented hash table used throughout compilation phases.*)
45454646+module Action = Action
4647module State = State
4748module Phases = Phases
4849module Driver = Driver
+13-18
lib/compiler/Phases.ml
···1717 Dir_scanner.scan_directories tree_dirs
1818 |> Seq.map Imports.load_tree
19192020-let parse
2121- (forest : State.t)
2222- : Reporter.Message.t Asai.Diagnostic.t list * Tree.code list
2323- =
2020+let parse (forest : State.t) =
2421 let host = forest.config.host in
2522 let trees = forest.index |> URI.Tbl.to_seq_values |> List.of_seq in
2626- let f tree =
2727- if Tree.is_unparsed tree then
2828- tree
2929- |> Tree.to_doc
3030- |> Option.map (Parse.parse_document ~host)
3131- else None
2323+ let results =
2424+ let@ tree = List.filter_map @~ trees in
2525+ match tree with
2626+ | Document doc -> Some (Parse.parse_document ~host doc)
2727+ | Parsed _
2828+ | Expanded _
2929+ | Resource _ ->
3030+ None
3231 in
3333- let results = List.filter_map f trees in
3434- results
3535- |> List.partition_map
3636- (function
3737- | Ok t -> Right t
3838- | Error d ->
3939- Left d
4040- )
3232+ let@ result = List.partition_map @~ results in
3333+ match result with
3434+ | Ok t -> Right t
3535+ | Error d -> Left d
41364237let reparse (doc : Lsp.Text_document.t) (forest : State.t) =
4338 Logs.debug (fun m -> m "reparsing");
+5-2
lib/compiler/State.ml
···2323 dependency_cache: Cache.t;
2424 resolver: string URI.Tbl.t;
2525 search_index: Forester_search.Index.t;
2626- usages: (Tree.exports, URI.t Asai.Range.located) Hashtbl.t
2626+ usages: (Tree.exports, URI.t Asai.Range.located) Hashtbl.t;
2727+ history: Action.t list;
2728}
28292930let make
···3940 ?(search_index = Forester_search.Index.create [])
4041 ?(dependency_cache = Cache.empty)
4142 ()
4242-= {env; dev; config; index; diagnostics; resolver; import_graph; graphs; search_index; dependency_cache; usages;}
4343+= {env; dev; config; index; diagnostics; resolver; import_graph; graphs; search_index; dependency_cache; usages; history = []}
43444445module Syntax = struct
4546 let (.={}) state uri =
···8788end
88898990open Syntax
9191+9292+let update_history forest action = {forest with history = action :: forest.history}
90939194let find_opt state uri = URI.Tbl.find_opt state.index uri
9295let to_seq state = URI.Tbl.to_seq state.index
+2-5
lib/compiler/test/Test_errors.ml
···5454 Sys.chdir (Eio.Path.native_exn tmp_dir);
5555 let@ () = check_diagnostic (Resource_not_found (URI.of_string_exn "asdf")) in
5656 let@ () = Reporter.easy_run in
5757- let forest, history =
5858- (* State.make ~env ~config ~dev: false () |> *)
5959- Driver.batch_run_with_history ~env ~config ~dev: false
6060- in
5757+ let forest = Driver.batch_run ~env ~config ~dev: false in
6158 Alcotest.(check @@ list action)
6259 ""
6360 [
···6966 (Run_jobs []);
7067 Done
7168 ]
7272- history;
6969+ (List.rev forest.history);
7370 Alcotest.(check int) "" 1 (URI.Tbl.length forest.diagnostics);
7471 in
7572 let open Alcotest in
+1
lib/core/Code.mli
···4646 | Dx_const_uri of t
4747 | Comment of string
4848 | Error of string
4949+[@@deriving show]
49505051and t = node Range.located list
5152
···161161 | None -> false
162162163163let rec node_at ~(position : Lsp.Types.Position.t) (code : _ list) : Code.node Range.located option =
164164- let flattened = flatten code in
165165- match List.find_opt (contains ~position) flattened with
164164+ match List.find_opt (contains ~position) code with
166165 | None -> None
167166 | Some n ->
168167 match (node_at ~position) (nodes_within n) with
+14-12
lib/language_server/Definitions.ml
···1919 let Lsp_state.{forest; _} = Lsp_state.get () in
2020 let host = forest.config.host in
2121 let uri = URI_scheme.lsp_uri_to_uri ~host textDocument.uri in
2222- match Option.bind forest.={uri} Tree.to_code with
2323- | None -> None
2424- | Some {nodes; _} ->
2525- match Analysis.addr_at ~position nodes with
2222+ match forest.={uri} with
2323+ | None -> assert false
2424+ | Some tree ->
2525+ match Tree.to_code tree with
2626 | None -> None
2727- | Some {value = str; _} ->
2828- let uri = URI_scheme.user_uri ~host str in
2929- let path = URI.Tbl.find forest.resolver uri in
3030- let uri = Lsp.Uri.of_path path in
3131- Logs.debug (fun m -> m "Definitions: %s" path);
3232- let range = L.Range.create ~start: {character = 1; line = 0} ~end_: {character = 1; line = 0} in
3333- Some
3434- (`Location [L.Location.{uri; range}])
2727+ | Some {nodes; _} ->
2828+ match Analysis.addr_at ~position nodes with
2929+ | None -> assert false
3030+ | Some {value = str; _} ->
3131+ let uri = URI_scheme.user_uri ~host str in
3232+ let path = URI.Tbl.find forest.resolver uri in
3333+ let uri = Lsp.Uri.of_path path in
3434+ let range = L.Range.create ~start: {character = 1; line = 0} ~end_: {character = 1; line = 0} in
3535+ Some
3636+ (`Location [L.Location.{uri; range}])
+6-2
lib/language_server/Did_change.ml
···1414let compute (params : L.DidChangeTextDocumentParams.t) =
1515 let Lsp_state.{forest; _} = Lsp_state.get () in
1616 match params with
1717- | {textDocument = {uri; _}; contentChanges} ->
1818- let uri = URI_scheme.lsp_uri_to_uri ~host: forest.config.host uri in
1717+ | {textDocument = {uri = lsp_uri; _}; contentChanges} ->
1818+ let uri = URI_scheme.lsp_uri_to_uri ~host: forest.config.host lsp_uri in
1919 match forest.={uri} with
2020 | None -> ()
2121 | Some tree ->
···2525 let new_doc = Lsp.Text_document.apply_content_changes doc contentChanges in
2626 Eio.traceln "After change, doc has content %s" (Lsp.Text_document.text new_doc);
2727 forest.={uri} <- Document new_doc;
2828+ Lsp_state.modify (fun ({forest; _} as lsp_state) ->
2929+ let new_forest = Driver.run_until_done (Action.Parse lsp_uri) forest in
3030+ {lsp_state with forest = new_forest}
3131+ );
2832 Diagnostics.compute new_doc
+8-4
lib/language_server/Did_open.ml
···66 *)
7788open Forester_core
99-open Forester_compiler.State.Syntax
99+open Forester_compiler
1010+open State.Syntax
1011module L = Lsp.Types
11121213let compute
1313- ({textDocument = {uri; _}} as params: L.DidOpenTextDocumentParams.t)
1414+ ({textDocument = {uri = lsp_uri; _}} as params: L.DidOpenTextDocumentParams.t)
1415 =
1516 let Lsp_state.{forest; _} = Lsp_state.get () in
1617 let document =
···1819 ~position_encoding: `UTF16
1920 params
2021 in
2121- (* Hashtbl.replace forest.documents uri document; *)
2222- let uri = URI_scheme.lsp_uri_to_uri ~host: forest.config.host uri in
2222+ let uri = URI_scheme.lsp_uri_to_uri ~host: forest.config.host lsp_uri in
2323 forest.={uri} <- Document document;
2424+ Lsp_state.modify (fun ({forest; _} as lsp_state) ->
2525+ let new_forest = Driver.run_until_done (Action.Parse lsp_uri) forest in
2626+ {lsp_state with forest = new_forest}
2727+ );
2428 Diagnostics.compute document