Skip to content

Commit 6ad206d

Browse files
committed
Merge branch 'v9.1' into v9.0
2 parents 3c6f87c + e668c1e commit 6ad206d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+6678
-222
lines changed

CHANGES.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
#1050)
2626
- [layout-engine] Add background color for each box kind (@ejgallego,
2727
#1050)
28-
- [compiler] Fix handling of literate files (@ejgallego, #, reported
29-
by @jim-portegies)
28+
- [compiler] Fix handling of literate files (@ejgallego, #1056,
29+
reported by @jim-portegies)
3030
- [rocq] Create output directory on .vo file save if it doesn't
3131
exists. This is very useful in the web context where we don't yet
3232
have a proper virtual FS setup, thus making the "Save .vo file"
@@ -40,6 +40,54 @@
4040
checking of Rocq's `Require`s when needed. The algorithm is not
4141
smart at all yet, as it invalidates all the requires for all open
4242
files. (@ejgallego, @helguo, #1059)
43+
- [goals] New option (LSP, petanque, API) to display and retrieve
44+
goals without the compacted context. See protocol docs for more
45+
information. (@ejgallego, alexJ, #1065, cc #1043)
46+
- [fleche] [rocq] New options and data fields to expose document
47+
comments. This is experimental, pass the `--record_comments` flags
48+
to `rocq-lsp`, `fcc`, or `pet-server` to enable it. Once this flag
49+
is passed, comments for a document will be stored in the new
50+
`doc.comments` field. (@ejgallego, alexJ, #1069, fixes #353)
51+
- [hover] New debug option `show_pr_vernac_on_hover`, that will
52+
re-print the sentence under point using the Rocq printer
53+
(@ejgallego, alexJ, #1070)
54+
- [petanque] New methods `proof_info` and `proof_info_at_pos` that
55+
return information about the current proof. As of today they return
56+
the proof name, text, range, ... (@DikieDick, @ejgallego, #1051)
57+
- [petanque] New method `list_notations_in_statement` which returns
58+
an analysis of notations appearing inside a Rocq statement
59+
(@JulesViennotFranca, @ejgallego, #1017)
60+
- [tools] New tool `rocq-checkdecls` for Rocq blueprints, inspired by
61+
the Lean version (#785, @ejgallego, Andrej Bauer)
62+
- [plugins] New demo plugin "baseline", that tries to proof existing
63+
lemmas using a set of pre-fixed tactics (@ejgallego, Shachar
64+
Itzhaky, Eytan Singher, #799)
65+
- [tools] New tool `checkdecls` for Coq blueprint, inspired by the
66+
Lean version (#785, @ejgallego, Andrej Bauer)
67+
- [lsp] [rocq] Example of Ltac2 AST analysis using serlib's Analzyer
68+
infra (@ejgallego, @jim-portegies, @DikieDick, #1058)
69+
- [lsp controller] Log internal errors to user-facing log
70+
(@ejgallego, #1074)
71+
- [doc] Example typescript client connecting to the WASM-based lsp
72+
server (@ejgallego, #626)
73+
- [hover] When the `show_doc_on_hover` option is enabled, hover will
74+
show coqdoc documentation when hovering on identifiers, using some
75+
heuristics to infer it from the comment just before
76+
it. Documentation is treated as Markdown. This feature is
77+
experimental and limited to documentation comments on the same file.
78+
(@ejgallego, #590)
79+
- [plugins] New plugin to dump document data (@ejgallego, Stefania
80+
Dumbrava, #1075)
81+
- [fcc] New option `--trace-file` that will generate trace data for
82+
visualizing with perfetto.dev (@ejgallego, AlexJ, Gaëtan Gilbert,
83+
#1076)
84+
- [fcc] New options `--save_vof` and `--load_vof` that can save a
85+
Fleche version of a document to a `.vof` file, thus avoiding `.vo`
86+
recompilation for example when calling `fcc --plugin=...` for a
87+
given file (@ejgallego, Alexj, #1077)
88+
- [vscode] Add config manager for handling client configuration
89+
changes in the infoview. Add configuration option for number of
90+
messages displayed (@Durbatuluk1701, #1067)
4391

4492
# coq-lsp 0.2.4: (W)Activation
4593
------------------------------

compiler/args.ml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
(************************************************************************)
2+
(* Copyright 2019 MINES ParisTech -- Dual License LGPL 2.1+ / GPL3+ *)
3+
(* Copyright 2019-2024 Inria -- Dual License LGPL 2.1+ / GPL3+ *)
4+
(* Copyright 2024-2025 Emilio J. Gallego Arias -- LGPL 2.1+ / GPL3+ *)
5+
(* Copyright 2025 CNRS -- LGPL 2.1+ / GPL3+ *)
6+
(* Written by: Emilio J. Gallego Arias & coq-lsp contributors *)
7+
(************************************************************************)
8+
(* Flèche => command-line compiler *)
9+
(************************************************************************)
10+
111
module Display = struct
212
type t =
313
| Verbose
@@ -12,10 +22,14 @@ type t =
1222
; debug : bool (** run in debug mode *)
1323
; display : Display.t (** display level *)
1424
; plugins : string list (** Flèche plugins to load *)
25+
; trace_file : string option (** Save flame profile to file *)
1526
; max_errors : int option
1627
(** Maximum erros before aborting the compilation *)
1728
; coq_diags_level : int
1829
(** Whether to include feedback messages in the diagnostics *)
30+
; record_comments : bool (** Record comments (experimental) *)
31+
; save_vof : bool (** Save a vof file *)
32+
; load_vof : bool (** Load a vof file instead of compiling *)
1933
}
2034

2135
let compute_default_plugins ~no_vo ~plugins =

compiler/cc.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ type t =
55
; default : Coq.Workspace.t
66
; io : Fleche.Io.CallBack.t
77
; token : Coq.Limits.Token.t
8+
; save_vof : bool
89
}

compiler/compile.ml

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
(************************************************************************)
2+
(* Copyright 2019 MINES ParisTech -- Dual License LGPL 2.1+ / GPL3+ *)
3+
(* Copyright 2019-2024 Inria -- Dual License LGPL 2.1+ / GPL3+ *)
4+
(* Copyright 2024-2025 Emilio J. Gallego Arias -- LGPL 2.1+ / GPL3+ *)
5+
(* Copyright 2025 CNRS -- LGPL 2.1+ / GPL3+ *)
6+
(* Written by: Emilio J. Gallego Arias & coq-lsp contributors *)
7+
(************************************************************************)
8+
(* Flèche => command-line compiler *)
9+
(************************************************************************)
10+
111
open Fleche
212

313
let is_in_dir ~dir ~file = CString.is_prefix dir file
@@ -39,8 +49,22 @@ let guess_languageId file =
3949
| ".v.tex" -> "latex"
4050
| _ -> "rocq"
4151

52+
let do_save_vof ~io ~token ~doc =
53+
match Doc.save_vof ~token ~doc with
54+
| Coq.Protect.E.{ r = Coq.Protect.R.Completed (Ok ()); feedback } ->
55+
Io.Log.feedback "vof safe" feedback;
56+
Io.Report.msg ~io ~lvl:Info "vof file saved"
57+
| Coq.Protect.E.{ r = Completed (Error (User msg)); feedback }
58+
| Coq.Protect.E.{ r = Completed (Error (Anomaly msg)); feedback } ->
59+
Io.Log.feedback "vof safe" feedback;
60+
Io.Report.msg ~io ~lvl:Error "error saving vof file %a" Coq.Pp_t.pp_with
61+
msg.msg
62+
| Coq.Protect.E.{ r = Interrupted; feedback } ->
63+
Io.Log.feedback "vof safe" feedback;
64+
Io.Report.msg ~io ~lvl:Error "saving vof file interrupted"
65+
4266
let compile_file ~cc file : int =
43-
let { Cc.io; root_state; workspaces; default; token } = cc in
67+
let { Cc.io; root_state; workspaces; default; token; save_vof } = cc in
4468
Io.Report.msg ~io ~lvl:Info "compiling file %s" file;
4569
match Lang.LUri.(File.of_uri (of_string file)) with
4670
| Error _ -> 222
@@ -57,9 +81,38 @@ let compile_file ~cc file : int =
5781
save_diags_file ~doc;
5882
(* Vo file saving is now done by a plugin *)
5983
Theory.close ~uri;
84+
if save_vof then do_save_vof ~io ~token ~doc;
6085
status_of_doc doc)
6186

62-
let compile ~cc =
63-
List.fold_left
64-
(fun status file -> if status = 0 then compile_file ~cc file else status)
65-
0
87+
let compile_file ~cc file : int =
88+
let args () = [ ("file", `String file) ] in
89+
NewProfile.profile "compile" ~args (fun () -> compile_file ~cc file) ()
90+
91+
let oprofile = ref None
92+
93+
let init_profile trace_file =
94+
match trace_file with
95+
| None -> ()
96+
| Some file ->
97+
let oc = Stdlib.open_out file in
98+
let fmt = Format.formatter_of_out_channel oc in
99+
oprofile := Some (oc, fmt);
100+
NewProfile.init { output = fmt; fname = "fcc" }
101+
102+
let finish_profile () =
103+
match !oprofile with
104+
| None -> ()
105+
| Some (oc, fmt) ->
106+
NewProfile.finish ();
107+
Format.pp_print_flush fmt ();
108+
Stdlib.close_out oc
109+
110+
let compile ~cc ~trace_file files =
111+
init_profile trace_file;
112+
let finally = finish_profile in
113+
let compile () =
114+
List.fold_left
115+
(fun status file -> if status = 0 then compile_file ~cc file else status)
116+
0 files
117+
in
118+
Fun.protect ~finally compile

compiler/driver.ml

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
(* Duplicated with coq_lsp *)
2-
let coq_init ~debug =
2+
let coq_init ~debug ~record_comments =
33
let load_module = Dynlink.loadfile in
44
let load_plugin = Coq.Loader.plugin_handler None in
55
let vm, warnings = (true, None) in
6-
Coq.Init.(coq_init { debug; load_module; load_plugin; vm; warnings })
6+
Coq.Init.(
7+
coq_init { debug; record_comments; load_module; load_plugin; vm; warnings })
78

89
let replace_test_path exp message =
910
let home_re = Str.regexp (exp ^ ".*$") in
@@ -42,8 +43,12 @@ let go ~int_backend args =
4243
; debug
4344
; files
4445
; plugins
46+
; trace_file
4547
; max_errors
4648
; coq_diags_level
49+
; record_comments
50+
; save_vof
51+
; load_vof = _
4752
} =
4853
args
4954
in
@@ -52,7 +57,7 @@ let go ~int_backend args =
5257
let io = Output.init ~display ~perfData ~coq_diags_level in
5358
(* Initialize Coq *)
5459
let debug = debug || Fleche.Debug.backtraces || !Fleche.Config.v.debug in
55-
let root_state = coq_init ~debug in
60+
let root_state = coq_init ~debug ~record_comments in
5661
let roots = if List.length roots < 1 then [ Sys.getcwd () ] else roots in
5762
let default = Coq.Workspace.default ~debug ~cmdline in
5863
let () = Coq.Limits.select_best int_backend in
@@ -62,7 +67,44 @@ let go ~int_backend args =
6267
let workspaces = List.map make_ws roots in
6368
List.iter (log_workspace ~io) workspaces;
6469
let () = apply_config ~max_errors in
65-
let cc = Cc.{ root_state; workspaces; default; io; token } in
70+
let cc = Cc.{ root_state; workspaces; default; io; token; save_vof } in
6671
(* Initialize plugins *)
6772
plugin_init plugins;
68-
Compile.compile ~cc files
73+
Compile.compile ~cc ~trace_file files
74+
75+
let go_vof args =
76+
let { Args.cmdline = _
77+
; roots = _
78+
; display
79+
; debug = _
80+
; files
81+
; plugins
82+
; trace_file = _
83+
; max_errors = _
84+
; coq_diags_level
85+
; record_comments = _
86+
; save_vof = _
87+
; load_vof = _
88+
} =
89+
args
90+
in
91+
let open Fleche in
92+
(* Initialize logging; we skip Rocq's init *)
93+
let fb_handler = Coq.Init.mk_fb_handler Coq.Protect.fb_queue in
94+
ignore (Feedback.add_feeder fb_handler);
95+
plugin_init plugins;
96+
let perfData = Option.is_empty fcc_test in
97+
let io = Output.init ~display ~perfData ~coq_diags_level in
98+
let in_file = List.nth files 0 in
99+
let in_vof = Filename.(remove_extension in_file) ^ ".vof" in
100+
let doc = Doc.doc_of_disk ~in_file:in_vof in
101+
Io.Report.msg ~io ~lvl:Info "vof file loaded";
102+
Io.Report.msg ~io ~lvl:Info "document has %d nodes" (List.length doc.nodes);
103+
Io.Report.msg ~io ~lvl:Info "calling plugins for [Theory.Register.Completed]";
104+
(* Call plugins for the .vof file *)
105+
let token = Coq.Limits.Token.create () in
106+
Theory.Register.Completed.fire ~io ~token ~doc;
107+
0
108+
109+
let go ~int_backend (args : Args.t) =
110+
if args.load_vof then go_vof args else go ~int_backend args

compiler/fcc.ml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
open Cmdliner
33
open Fcc_lib
44

5-
let fcc_main int_backend roots display debug plugins files coqlib findlib_config
6-
ocamlpath rload_path load_path require_libraries no_vo max_errors
7-
coq_diags_level =
5+
let fcc_main int_backend roots display debug plugins trace_file files coqlib
6+
findlib_config ocamlpath rload_path load_path require_libraries no_vo
7+
max_errors coq_diags_level record_comments save_vof load_vof =
88
let vo_load_path = rload_path @ load_path in
99
let args = [] in
1010
let cmdline =
@@ -25,8 +25,12 @@ let fcc_main int_backend roots display debug plugins files coqlib findlib_config
2525
; files
2626
; debug
2727
; plugins
28+
; trace_file
2829
; max_errors
2930
; coq_diags_level
31+
; record_comments
32+
; save_vof
33+
; load_vof
3034
}
3135
in
3236
Driver.go ~int_backend args
@@ -51,10 +55,22 @@ let plugins : string list Term.t =
5155
let doc = "Compiler plugins to load" in
5256
Arg.(value & opt_all string [] & info [ "plugin" ] ~docv:"PLUGINS" ~doc)
5357

58+
let trace_file : string option Term.t =
59+
let doc = "Activate profiling and output a Rocq flame graph in FILE" in
60+
Arg.(value & opt (some string) None & info [ "trace_file" ] ~docv:"FILE" ~doc)
61+
5462
let no_vo : bool Term.t =
5563
let doc = "Don't generate .vo files at the end of compilation" in
5664
Arg.(value & flag & info [ "no_vo" ] ~doc)
5765

66+
let save_vof : bool Term.t =
67+
let doc = "Save a .vof file with Fleche-specific metadata" in
68+
Arg.(value & flag & info [ "vof" ] ~doc)
69+
70+
let load_vof : bool Term.t =
71+
let doc = "Save a .vof file with Fleche-specific metadata" in
72+
Arg.(value & flag & info [ "load_vof" ] ~doc)
73+
5874
let max_errors : int option Term.t =
5975
let doc = "Maximum errors in files before aborting" in
6076
Arg.(
@@ -97,9 +113,10 @@ let fcc_cmd : int Cmd.t =
97113
let fcc_term =
98114
let open Coq.Args in
99115
Term.(
100-
const fcc_main $ int_backend $ roots $ display $ debug $ plugins $ file
101-
$ coqlib $ findlib_config $ ocamlpath $ rload_paths $ qload_paths
102-
$ ri_from $ no_vo $ max_errors $ coq_diags_level)
116+
const fcc_main $ int_backend $ roots $ display $ debug $ plugins
117+
$ trace_file $ file $ coqlib $ findlib_config $ ocamlpath $ rload_paths
118+
$ qload_paths $ ri_from $ no_vo $ max_errors $ coq_diags_level
119+
$ record_comments $ save_vof $ load_vof)
103120
in
104121
let exits = Exit_codes.[ fatal; stopped; scheduled; uri_failed ] in
105122
Cmd.(v (Cmd.info "fcc" ~exits ~version ~doc ~man) fcc_term)

controller/lsp_core.ml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ end = struct
221221
Hashtbl.remove _rtable id;
222222
f pr |> answer ~ofn_rq ~id
223223
| None ->
224-
L.trace "consuem" "can't consume cancelled request: %d" id;
224+
L.trace "consume" "can't consume cancelled request: %d" id;
225225
()
226226

227227
let cancel ~ofn_rq ~code ~message id : unit =
@@ -381,6 +381,8 @@ let get_pp_format params =
381381
get_pp_format_from_config ()
382382
| None -> get_pp_format_from_config ()
383383

384+
let get_compact params = Option.default true (obool_field "compact" params)
385+
384386
let get_pretac params =
385387
Option.append (ostring_field "command" params) (ostring_field "pretac" params)
386388

@@ -399,9 +401,10 @@ let get_goals_mode params =
399401

400402
let do_goals ~params =
401403
let pp_format = get_pp_format params in
404+
let compact = get_compact params in
402405
let mode = get_goals_mode params in
403406
let pretac = get_pretac params in
404-
let handler = Rq_goals.goals ~pp_format ~mode ~pretac () in
407+
let handler = Rq_goals.goals ~pp_format ~compact ~mode ~pretac () in
405408
do_position_request ~postpone:true ~handler ~params
406409

407410
let do_definition =
@@ -614,7 +617,7 @@ let dispatch_notification ~io ~ofn ~token ~state ~method_ ~params : unit =
614617
(* NOOPs *)
615618
| "initialized" -> ()
616619
(* Generic handler *)
617-
| msg -> L.trace "no_handler" "%s" msg
620+
| msg -> L.trace "no_handler for notification" "%s" msg
618621

619622
let dispatch_state_notification ~io ~ofn ~token ~state ~method_ ~params :
620623
State.t =
@@ -781,6 +784,9 @@ let dispatch_or_resume_check ~io ~ofn ~state =
781784
let dispatch_or_resume_check ~io ~ofn ~state =
782785
try Some (dispatch_or_resume_check ~io ~ofn ~state) with
783786
| U.Type_error (msg, obj) ->
787+
Fleche.Io.(Report.msg ~io ~lvl:Error)
788+
"JSON Parsing Error when handling protocol input: %s\n\
789+
see log for more details" msg;
784790
L.trace_object msg obj;
785791
Some (Yield state)
786792
| Lsp_exit ->
@@ -793,12 +799,17 @@ let dispatch_or_resume_check ~io ~ofn ~state =
793799
coq-lsp internal error and should be fixed *)
794800
let bt = Printexc.get_backtrace () in
795801
let iexn = Exninfo.capture exn in
796-
L.trace "process_queue" "%s"
802+
let pp_msg = CErrors.(iprint iexn) in
803+
Fleche.Io.(Report.msg ~io ~lvl:Error)
804+
"Internal Error when handling command: %a\n\
805+
See log for more details, please report to rocq-lsp developers"
806+
Coq.Pp_t.pp pp_msg;
807+
L.trace "dispatch_or_resume_check" "%s"
797808
(if Printexc.backtrace_status () then "bt=true" else "bt=false");
798809
(* let method_name = Lsp.Base.Message.method_ com in *)
799810
(* L.trace "process_queue" "exn in method: %s" method_name; *)
800811
L.trace "print_exn [OCaml]" "%s" (Printexc.to_string exn);
801-
L.trace "print_exn [Coq ]" "%a" Coq.Pp_t.pp_with CErrors.(iprint iexn);
812+
L.trace "print_exn [Coq ]" "%a" Coq.Pp_t.pp pp_msg;
802813
L.trace "print_bt [OCaml]" "%s" bt;
803814
Some (Yield state)
804815

0 commit comments

Comments
 (0)