Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: snapshot trees and language processors #3014

Merged
merged 69 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
ceeaff7
feat: start integrating new snapshot types into cmdline driver
Kha Oct 12, 2023
d0fd3d7
feat: switch `Language` to bundled, integrate into cmdline driver in …
Kha Oct 13, 2023
152d594
fix: do not duplicate output
Kha Oct 13, 2023
a68d1c6
fix: more output fixes
Kha Oct 19, 2023
f2f6016
foo
Kha Nov 3, 2023
986d1c1
fix: `run_task`/`deactivate_task` race condition on `m_imp->m_closure`
Kha Nov 9, 2023
d2bf996
fix: re-read HTTP header when skipping notification in `Ipc.readRespo…
Kha Nov 10, 2023
23da22e
fix: debounce server status reporting
Kha Nov 10, 2023
7932c0d
fix: create snapshot for header in legacy adapter
Kha Nov 11, 2023
00e976c
fix: memoize `cmdSnaps` legacy adapter so `getFinishedPrefix` works a…
Kha Nov 11, 2023
7c0ad9c
fix: `waitForDiagnostics` must wait on reporter task
Kha Nov 11, 2023
89383cf
doc: Language
Kha Nov 13, 2023
58c19d7
chore: rely on auto cancellation of reporter
Kha Nov 25, 2023
22aa0dc
doc: more
Kha Nov 27, 2023
1d547d3
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Nov 29, 2023
0ce8fee
import at most once per worker process
Kha Nov 29, 2023
4c9b70b
fix test outputs
Kha Nov 29, 2023
0282d1c
File worker: synchronize output messages
Kha Nov 30, 2023
8fff2e2
fix: incremental parsing
Kha Dec 1, 2023
ca75ce2
polish Lean.Language.Lean
Kha Dec 1, 2023
44cb1cc
better naming
Kha Dec 2, 2023
057184b
feat: synchronous execution of task continuations
Kha Dec 2, 2023
0688e22
synchronous fast forwarding in Lean processor
Kha Dec 2, 2023
d0e9409
Bring back trust level
Kha Dec 2, 2023
85a151b
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Dec 2, 2023
3930e40
Try a shortcut
Kha Dec 2, 2023
3b14598
Remove redundant fields
Kha Dec 2, 2023
daf6fde
doc
Kha Dec 2, 2023
c6dd2b1
code owner
Kha Dec 2, 2023
f89de7f
doc
Kha Dec 2, 2023
edefad1
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Dec 8, 2023
5550623
Fix explicit cancellation
Kha Dec 12, 2023
91e7e28
Adjust comments
Kha Dec 13, 2023
33a9647
Cache interactive diagnostics properly
Kha Dec 13, 2023
63a853e
fix: clear progress notifications from `lake` in the end
Kha Dec 13, 2023
9c49e49
fix: header errors should be fatal
Kha Dec 14, 2023
67c0599
Header diagnostics should cover the full file
Kha Dec 14, 2023
e0e7faf
server reporting delay
Kha Dec 14, 2023
cef0d59
fix: header errors should be fatal
Kha Dec 14, 2023
5122ee7
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Dec 14, 2023
dc97d75
fix nondeterministic test output from new debouncing
Kha Dec 14, 2023
893ea99
trigger CI
Kha Dec 14, 2023
078cef0
trigger CI again
Kha Dec 15, 2023
561f260
remove unused Option.forM, already in std4
Kha Dec 15, 2023
6ec85ec
perf: keep alive old single-threaded cmdline driver for a little longer
Kha Dec 18, 2023
b50c9e2
fix: don't report the same info tree twice
Kha Dec 21, 2023
0480045
refactor: previous commit
Kha Dec 21, 2023
29b6612
fix: report all info trees at `ileanInfoFinal`
Kha Dec 21, 2023
5de7e2c
refactor: move interactive diagnostics caching from `Snapshot` to fil…
Kha Dec 23, 2023
8b96499
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Jan 25, 2024
8bd6612
clean up Lean.Server changes
Kha Feb 1, 2024
a0a65b6
refactor: remove unique ID indirection for interactive diagnostics ca…
Kha Feb 13, 2024
25886d2
Merge branch 'master' of https://github.com/leanprover/lean4 into het…
Kha Feb 20, 2024
58d5b58
Remove `Language` interface for now, to be refined in `hash-lang`
Kha Feb 20, 2024
4665f41
Move `setup-file` logic back from language processor into file worker
Kha Feb 21, 2024
8830667
Run `lake setup-file` at most once per worker process, like before
Kha Feb 22, 2024
91a0fee
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Feb 29, 2024
2c99cf5
Fix cancellation in reportSnapshots
Kha Feb 29, 2024
44e5163
refactor: lazy initialization of request caches
Kha Mar 1, 2024
ad6b225
fix: traces on partial syntax
Kha Mar 1, 2024
2745d55
address some comments
Kha Mar 6, 2024
491b125
remove ElabTaskError.aborted
Kha Mar 7, 2024
c64fe35
address more comments
Kha Mar 7, 2024
34ff994
address more comments
Kha Mar 7, 2024
27c90ba
address even more comments
Kha Mar 7, 2024
959fa55
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Mar 7, 2024
f7db589
Replace silly critical section code with `modifyGet`
Kha Mar 8, 2024
c26033c
Address review comments
Kha Mar 8, 2024
723910a
Merge remote-tracking branch 'upstream/master' into het-snaps
Kha Mar 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 34 additions & 19 deletions src/Lean/Server/Completion.lean
Original file line number Diff line number Diff line change
Expand Up @@ -81,39 +81,53 @@ open Elab
open Meta
open FuzzyMatching

abbrev EligibleHeaderDecls := HashMap Name ConstantInfo

/-- Cached header declarations for which `allowCompletion headerEnv decl` is true. -/
builtin_initialize eligibleHeaderDeclsRef : IO.Ref (HashMap Name ConstantInfo) ← IO.mkRef {}
builtin_initialize eligibleHeaderDeclsRef : IO.Ref (Option EligibleHeaderDecls) ←
IO.mkRef none

/-- Caches the declarations in the header for which `allowCompletion headerEnv decl` is true. -/
def fillEligibleHeaderDecls (headerEnv : Environment) : IO Unit := do
eligibleHeaderDeclsRef.modify fun startEligibleHeaderDecls =>
(·.2) <| StateT.run (m := Id) (s := startEligibleHeaderDecls) do
headerEnv.constants.forM fun declName c => do
/--
Returns the declarations in the header for which `allowCompletion env decl` is true, caching them
if not already cached.
-/
def getEligibleHeaderDecls (env : Environment) : IO EligibleHeaderDecls := do
if let some eligibleHeaderDecls ← eligibleHeaderDeclsRef.get then
return eligibleHeaderDecls

-- enter critical section to avoid running the computation multiple times
-- `take` safety: we call `set` in all branches, without a chance for exceptions in between
if let some eligibleHeaderDecls ← unsafe eligibleHeaderDeclsRef.take then
-- someone else was quicker!
eligibleHeaderDeclsRef.set eligibleHeaderDecls
return eligibleHeaderDecls
let (_, eligibleHeaderDecls) :=
StateT.run (m := Id) (s := {}) do
-- `map₁` are the header decls
env.constants.map₁.forM fun declName c => do
modify fun eligibleHeaderDecls =>
if allowCompletion headerEnv declName then
if allowCompletion env declName then
eligibleHeaderDecls.insert declName c
else
eligibleHeaderDecls
eligibleHeaderDeclsRef.set (some eligibleHeaderDecls)
return eligibleHeaderDecls

/-- Iterate over all declarations that are allowed in completion results. -/
private def forEligibleDeclsM [Monad m] [MonadEnv m] [MonadLiftT (ST IO.RealWorld) m]
(f : Name → ConstantInfo → m PUnit) : m PUnit := do
[MonadLiftT IO m] (f : Name → ConstantInfo → m PUnit) : m PUnit := do
let env ← getEnv
(← eligibleHeaderDeclsRef.get).forM f
(← getEligibleHeaderDecls (← getEnv)).forM f
Kha marked this conversation as resolved.
Show resolved Hide resolved
-- map₂ are exactly the local decls
env.constants.map₂.forM fun name c => do
if allowCompletion env name then
f name c

/-- Checks whether this declaration can appear in completion results. -/
private def allowCompletion [Monad m] [MonadEnv m] [MonadLiftT (ST IO.RealWorld) m]
(declName : Name) : m Bool := do
let env ← getEnv
if (← eligibleHeaderDeclsRef.get).contains declName then
return true
if env.constants.map₂.contains declName && Lean.Meta.allowCompletion env declName then
return true
return false
private def allowCompletion (env : Environment) (eligibleHeaderDecls : EligibleHeaderDecls)
Kha marked this conversation as resolved.
Show resolved Hide resolved
(declName : Name) : Bool :=
eligibleHeaderDecls.contains declName ||
env.constants.map₂.contains declName && Lean.Meta.allowCompletion env declName

/--
Sorts `items` descendingly according to their score and ascendingly according to their label
Expand Down Expand Up @@ -371,16 +385,17 @@ private def idCompletionCore
matchAtomic id (alias.replacePrefix ns Name.anonymous)
else
none
let eligibleHeaderDecls ← getEligibleHeaderDecls env
-- Auxiliary function for `alias`
let addAlias (alias : Name) (declNames : List Name) (score : Float) : M Unit := do
declNames.forM fun declName => do
if allowCompletion declName then
if allowCompletion env eligibleHeaderDecls declName then
addUnresolvedCompletionItemForDecl alias.getString! declName score
-- search explicitly open `ids`
for openDecl in ctx.openDecls do
match openDecl with
| OpenDecl.explicit openedId resolvedId =>
if allowCompletion resolvedId then
if allowCompletion env eligibleHeaderDecls resolvedId then
if let some score := matchAtomic id openedId then
addUnresolvedCompletionItemForDecl openedId.getString! resolvedId score
| OpenDecl.simple ns _ =>
Expand Down
2 changes: 0 additions & 2 deletions src/Lean/Server/FileWorker.lean
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,6 @@ def setupImports (meta : DocumentMeta) (chanOut : Channel JsonRpc.Message)
return .error { diagnostics := .empty, success? := none }

let imports := Elab.headerToImports stx
-- Prepare header-based caches that requests may use
--runHeaderCachingHandlers headerEnv
let fileSetupResult ← setupFile meta imports fun stderrLine => do
let progressDiagnostic := {
range := ⟨⟨0, 0⟩, ⟨0, 0⟩⟩
Expand Down
1 change: 0 additions & 1 deletion src/Lean/Server/FileWorker/RequestHandling.lean
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,6 @@ builtin_initialize
CompletionParams
CompletionList
handleCompletion
Completion.fillEligibleHeaderDecls
registerLspRequestHandler
"completionItem/resolve"
CompletionItem
Expand Down
25 changes: 5 additions & 20 deletions src/Lean/Server/Requests.lean
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,8 @@ section HandlerTable
open Lsp

structure RequestHandler where
fileSource : Json → Except RequestError Lsp.DocumentUri
handle : Json → RequestM (RequestTask Json)
/--
Handler that is called by the file worker after processing the header with the header environment.
Enables request handlers to cache data related to imports.
-/
handleHeaderCaching : Environment → IO Unit
fileSource : Json → Except RequestError Lsp.DocumentUri
handle : Json → RequestM (RequestTask Json)

builtin_initialize requestHandlers : IO.Ref (PersistentHashMap String RequestHandler) ←
IO.mkRef {}
Expand All @@ -207,9 +202,7 @@ as LSP error responses. -/
def registerLspRequestHandler (method : String)
paramType [FromJson paramType] [FileSource paramType]
respType [ToJson respType]
(handler : paramType → RequestM (RequestTask respType))
(headerCachingHandler : Environment → IO Unit := fun _ => pure ())
: IO Unit := do
(handler : paramType → RequestM (RequestTask respType)) : IO Unit := do
if !(← Lean.initializing) then
throw <| IO.userError s!"Failed to register LSP request handler for '{method}': only possible during initialization"
if (← requestHandlers.get).contains method then
Expand All @@ -220,8 +213,8 @@ def registerLspRequestHandler (method : String)
let params ← liftExcept <| parseRequestParams paramType j
let t ← handler params
pure <| t.map <| Except.map ToJson.toJson
let handleHeaderCaching := headerCachingHandler
requestHandlers.modify fun rhs => rhs.insert method { fileSource, handle, handleHeaderCaching }

requestHandlers.modify fun rhs => rhs.insert method { fileSource, handle }

def lookupLspRequestHandler (method : String) : IO (Option RequestHandler) :=
return (← requestHandlers.get).find? method
Expand Down Expand Up @@ -252,14 +245,6 @@ def chainLspRequestHandler (method : String)
else
throw <| IO.userError s!"Failed to chain LSP request handler for '{method}': no initial handler registered"

/--
Runs the header caching handler for every single registered request handler using the given
`headerEnv`.
-/
def runHeaderCachingHandlers (headerEnv : Environment) : IO Unit := do
(← requestHandlers.get).forM fun _ handler =>
handler.handleHeaderCaching headerEnv

def routeLspRequest (method : String) (params : Json) : IO (Except RequestError DocumentUri) := do
match (← lookupLspRequestHandler method) with
| none => return Except.error <| RequestError.methodNotFound method
Expand Down
Loading