Skip to content

Commit

Permalink
WIP: invalidating overview with ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
rtetley committed Nov 12, 2024
1 parent 2a68ecb commit 4d7bc58
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 11 deletions.
20 changes: 11 additions & 9 deletions language-server/dm/document.ml
Original file line number Diff line number Diff line change
Expand Up @@ -521,26 +521,28 @@ let rec unchanged_id id = function
| (Added _ | Deleted _) :: _ -> id

let invalidate top_edit top_id parsed_doc new_sentences =
let rec invalidate_diff parsed_doc scheduler_state invalid_ids = function
| [] -> invalid_ids, parsed_doc
let rec invalidate_diff parsed_doc scheduler_state invalid_ids invalid_ranges = function
| [] -> invalid_ids, invalid_ranges, parsed_doc
| Equal s :: diffs ->
let patch_sentence (parsed_doc,scheduler_state) (id,new_s) =
patch_sentence parsed_doc scheduler_state id new_s
in
let parsed_doc, scheduler_state = List.fold_left patch_sentence (parsed_doc, scheduler_state) s in
invalidate_diff parsed_doc scheduler_state invalid_ids diffs
invalidate_diff parsed_doc scheduler_state invalid_ids invalid_ranges diffs
| Deleted ids :: diffs ->
let invalid_ids = List.fold_left (fun ids id -> Stateid.Set.add id ids) invalid_ids ids in
let unique_invalid_ids = Stateid.Set.elements invalid_ids in
let invalid_ranges = List.fold_right RangeList.insert_or_merge_range invalid_ranges (List.map (range_of_id parsed_doc) unique_invalid_ids) in
let parsed_doc = List.fold_left remove_sentence parsed_doc ids in
(* FIXME update scheduler state, maybe invalidate after diff zone *)
invalidate_diff parsed_doc scheduler_state invalid_ids diffs
invalidate_diff parsed_doc scheduler_state invalid_ids invalid_ranges diffs
| Added new_sentences :: diffs ->
(* FIXME could have side effect on the following, unchanged sentences *)
let add_sentence (parsed_doc,scheduler_state) ({ parsing_start; start; stop; ast; synterp_state } : pre_sentence) =
add_sentence parsed_doc parsing_start start stop ast synterp_state scheduler_state
in
let parsed_doc, scheduler_state = List.fold_left add_sentence (parsed_doc,scheduler_state) new_sentences in
invalidate_diff parsed_doc scheduler_state invalid_ids diffs
invalidate_diff parsed_doc scheduler_state invalid_ids invalid_ranges diffs
in
let (_,_synterp_state,scheduler_state) = state_at_pos parsed_doc top_edit in
let sentence_strings = LM.bindings @@ LM.map (fun s -> string_of_parsed_ast s.ast) parsed_doc.sentences_by_end in
Expand All @@ -554,8 +556,8 @@ let invalidate top_edit top_id parsed_doc new_sentences =
let diff = diff old_sentences new_sentences in
let unchanged_id = unchanged_id top_id diff in
log @@ "diff:\n" ^ string_of_diff parsed_doc diff;
let invalid_ids, doc = invalidate_diff parsed_doc scheduler_state Stateid.Set.empty diff in
unchanged_id, invalid_ids, doc
let invalid_ids, invalid_ranges, doc = invalidate_diff parsed_doc scheduler_state Stateid.Set.empty [] diff in
unchanged_id, invalid_ids, invalid_ranges, doc

(** Validate document when raw text has changed *)
let validate_document ({ parsed_loc; raw_doc; } as document) =
Expand Down Expand Up @@ -585,15 +587,15 @@ let handle_invalidate {parsed; errors; parsed_comments; stop; top_id; started} d
log @@ Format.sprintf "%i new comments" (List.length new_comments);
let errors = parsing_errors_before document stop in
let comments = comments_before document stop in
let unchanged_id, invalid_ids, document = invalidate (stop+1) top_id document new_sentences in
let unchanged_id, invalid_ids, invalid_ranges, document = invalidate (stop+1) top_id document new_sentences in
let parsing_errors_by_end =
List.fold_left (fun acc (error : parsing_error) -> LM.add error.stop error acc) errors new_errors
in
let comments_by_end =
List.fold_left (fun acc (comment : comment) -> LM.add comment.stop comment acc) comments new_comments
in
let parsed_loc = pos_at_end document in
Some (unchanged_id, invalid_ids, { document with parsed_loc; parsing_errors_by_end; comments_by_end})
Some (unchanged_id, invalid_ids, invalid_ranges, { document with parsed_loc; parsing_errors_by_end; comments_by_end})

let handle_event document = function
| ParseEvent state -> handle_parse_more state, None
Expand Down
2 changes: 1 addition & 1 deletion language-server/dm/document.mli
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ val validate_document : document -> events
(** [validate_document doc] triggers the parsing of the document line by line without
launching any execution. *)

val handle_event : document -> event -> events * (sentence_id option * sentence_id_set * document) option
val handle_event : document -> event -> events * (sentence_id option * sentence_id_set * RangeList.t * document) option
(** [handle_event dpc ev] handles a parsing event for the document. One parsing event parses one line
and prepares the next parsing event. Finally once the full parsing is done, the final event returs
the id of the bottomost sentence of the prefix which has not changed since the previous validation
Expand Down
4 changes: 3 additions & 1 deletion language-server/dm/documentManager.ml
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,9 @@ let handle_event ev st block background =
let cancel_handles = List.map Sel.Event.get_cancellation_handle events in
let update_view = false in
Some {st with cancel_handles}, inject_doc_events events, None, update_view
| Some (unchanged_id, invalid_roots, document) ->
| Some (unchanged_id, invalid_roots, invalid_ranges, document) ->
let execution_state = ExecutionManager.invalidate_overview st.execution_state invalid_ranges in
let st = {st with execution_state} in
let st = validate_document st unchanged_id invalid_roots document in
let update_view = true in
if background then
Expand Down
9 changes: 9 additions & 0 deletions language-server/dm/executionManager.ml
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,15 @@ let invalidate_prepared_or_processing task state document =
| PDelegate task -> invalidate_prepared_or_processing_delegate task state document
| PSkip { id } | PExec { id } | PQuery { id } -> invalidate_prepared_or_processing_sentence id state document


let invalidate_overview state invalid_ranges =
let {prepared; processing; processed} = state.overview in
let prepared = List.fold_right RangeList.remove_or_truncate_range invalid_ranges prepared in
let processing = List.fold_right RangeList.remove_or_truncate_range invalid_ranges processing in
let processed = List.fold_right RangeList.remove_or_truncate_range invalid_ranges processed in
let overview = {prepared; processing; processed} in
{state with overview}

let update_processing task state document =
let {processing; prepared} = state.overview in
match task with
Expand Down
1 change: 1 addition & 0 deletions language-server/dm/executionManager.mli
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ val get_options : unit -> options
val set_options : options -> unit
val set_default_options : unit -> unit
val invalidate : Document.document -> Scheduler.schedule -> sentence_id -> state -> state
val invalidate_overview : state -> RangeList.t -> state

val error : state -> sentence_id -> (Loc.t option * Pp.t) option
val feedback : state -> sentence_id -> feedback_message list
Expand Down

0 comments on commit 4d7bc58

Please sign in to comment.