-
Notifications
You must be signed in to change notification settings - Fork 437
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: add call hierarchy support #3082
Conversation
|
The previous version of this PR adjusted The core issue is that we want to save some kind of context while elaborating a term, but cannot meaningfully do so until we are fully done with elaborating the term, lest parts of the saved context may be missing. We already work around this limitation in several other places, e.g. using To solve this issue, the previous commit introduces a notion of The old Another adjustment made in the previous commit is to remove the incorrect unused variable linter tests checking for unused |
(CI is red because LeanInk manually traverses the InfoTree, but the tests are green. PRs for fixing downstream repos tbd) |
59f4035
to
0aba0a0
Compare
df4a8b7
to
8a8acfc
Compare
This PR facilitates augmenting the context of an `InfoTree` with *partial* contexts while elaborating a command. Using partial contexts, this PR also adds support for tracking the parent declaration name of a term in the `InfoTree`. The parent declaration name is needed to compute the call hierarchy in #3082. Specifically, the `Lean.Elab.InfoTree.context` constructor is refactored to take a value of the new type `Lean.Elab.PartialContextInfo` instead of a `Lean.Elab.ContextInfo`, which now refers to a full `InfoTree` context. The `PartialContextInfo` is then merged into a `ContextInfo` while traversing the tree using `Lean.Elab.PartialContextInfo.mergeIntoOuter?`. The partial context after executing `liftTermElabM` is stored in values of a new type `Lean.Elab.CommandContextInfo`. As a result of this, `Lean.Elab.ContextInfo.save` moves to `Lean.Elab.CommandContextInfo.save`. For obtaining the parent declaration for a term, a new typeclass `MonadParentDecl` is introduced to save the parent declaration in `Lean.Elab.withSaveParentDeclInfoContext`. `Lean.Elab.Term.withDeclName x` now calls `withSaveParentDeclInfoContext x` to save the declaration name. ### Migration **The changes to the `InfoTree.context` constructor break backwards compatibility with all downstream users that traverse the `InfoTree` manually instead of going through the functions in `InfoUtils.lean`.** To fix this, you can merge the outer `ContextInfo` in a traversal with the `PartialContextInfo` of an `InfoTree.context` node using `PartialContextInfo.mergeIntoOuter?`. See e.g. `Lean.Elab.InfoTree.foldInfo` for an example: ```lean partial def InfoTree.foldInfo (f : ContextInfo → Info → α → α) (init : α) : InfoTree → α := go none init where go ctx? a | context ctx t => go (ctx.mergeIntoOuter? ctx?) a t | node i ts => let a := match ctx? with | none => a | some ctx => f ctx i a ts.foldl (init := a) (go <| i.updateContext? ctx?) | _ => a ``` Downstream users that manually save `InfoTree`s may need to adjust calls to `ContextInfo.save` to use `CommandContextInfo.save` instead and potentially wrap their `CommandContextInfo` in a `PartialContextInfo.commandCtx` constructor when storing it in an `InfoTree` or `ContextInfo.mk` when creating a full context. ### Motivation As of now, `ContextInfo`s are always *full* contexts, constructed as if they were always created in `liftTermElabM` after running the `TermElabM` action. This is not strictly true; we already create `ContextInfo`s in several places other than `liftTermElabM` and work around the limitation that `ContextInfo`s are always full contexts in certain places (e.g. `Info.updateContext?` is a crux that we need because we can't always create partial contexts at the term-level), but it has mostly worked out so far. Note that one must be very careful when saving a `ContextInfo` in places other than `liftTermElabM` because the context may not be as complete as we would like (e.g. it may lack meta-variable assignments, potentially leading to a language server panic). Unfortunately, the parent declaration of a term is another example of a context that cannot be provided in `liftTermElabM`: The parent declaration is usually set via `withDeclName`, which itself lives in `TermElabM`. So by the time we are trying to save the full `ContextInfo`, the declaration name is already gone. There is no easy fix for this like in the other cases where we would really just like to augment the context with an extra field. The refactor that we decided on to resolve the issue is to refactor the `InfoTree` to take a `PartialContextInfo` instead of a `ContextInfo` and have code that traverses the `InfoTree` merge inner contexts with outer contexts to produce a full `ContextInfo` value. ### Bumps for downstream projects - `lean-pr-testing-3159` branch at Std, not yet opened as a PR - `lean-pr-testing-3159` branch at Mathlib, not yet opened as a PR - leanprover/LeanInk#57 - hargoniX/LeanInk#1 - tydeu/lean4-alloy#7 - leanprover-community/repl#29 --------- Co-authored-by: Sebastian Ullrich <[email protected]>
97994ca
to
6cd7dcd
Compare
7d59981
to
9d8564f
Compare
In v4.6.0, there was a significant regression in initial server startup performance because the .ilean files got bigger in #3082 and we load the information stored in all .ilean files synchronously when the server starts up. This PR makes this loading asynchronous. The trade-off is that requests that are issued right after the initial server start when the references are not fully loaded yet may yield incomplete results. Benchmark for this in a separate PR soon after this one. --------- Co-authored-by: Sebastian Ullrich <[email protected]>
In v4.6.0, there was a significant regression in initial server startup performance because the .ilean files got bigger in #3082 and we load the information stored in all .ilean files synchronously when the server starts up. This PR makes this loading asynchronous. The trade-off is that requests that are issued right after the initial server start when the references are not fully loaded yet may yield incomplete results. Benchmark for this in a separate PR soon after this one. --------- Co-authored-by: Sebastian Ullrich <[email protected]>
This PR adds support for the "call hierarchy" feature of LSP that allows quickly navigating both inbound and outbound call sites of functions. In this PR, "call" is taken to mean "usage", so inbound and outbound references of all kinds of identifiers (e.g. functions or types) can be navigated. To implement the call hierarchy feature, this PR implements the LSP requests
textDocument/prepareCallHierarchy
,callHierarchy/incomingCalls
andcallHierarchy/outgoingCalls
.Showing the call hierarchy (click to show image)
Incoming calls (click to show image)
Outgoing calls (click to show image)
It is based on #3159, which should be merged before this PR.
To route the parent declaration name through to the language server, the
.ilean
format is adjusted, breaking backwards compatibility with version 1 of the ILean format and yielding version 2.This PR also makes the following more minor adjustments:
Lean.Server.findModuleRefs
now also combines the identifiers of constants and FVars and prefers constant over FVars for the combined identifier. This is necessary because e.g. declarations declared usingwhere
yield both a constant (for usage outside of the function) and an FVar (for usage inside of the function) with the same range, whereas we would typically like all references to refer to the former. This also fixes a bug introduced in feat: rename request handler #2462 where renaming a declaration declared usingwhere
would not rename usages outside of the function, as well as a bug in the unused variable linter wherewhere
declarations would be reported as unused even if they were being used outside of the function.Lean.Server.RefInfo
toLean.Lsp.RefInfo
now also computes theLean.DeclarationRanges
for parent declaration names viaMetaM
and must hence be inIO
now.Array.groupByKey
toHashMap.lean
.Watchdog.lean
andLanguageFeatures.lean
.