fix: completion for aliases

closes #863
This commit is contained in:
Leonardo de Moura 2021-12-10 12:12:30 -08:00
parent 84f374702d
commit 47c2d335d4
4 changed files with 60 additions and 7 deletions

View file

@ -11,7 +11,8 @@ import Lean.Exception
namespace Lean
/-!
We use aliases to implement the `export <id> (<id>+)` command.
An `export A (x)` in the namespace `B` produces an alias `B.x ~> A.x`. -/
An `export A (x)` in the namespace `B` produces an alias `B.x ~> A.x`.
-/
abbrev AliasState := SMap Name (List Name)
abbrev AliasEntry := Name × Name

View file

@ -92,7 +92,7 @@ private def runM (ctx : ContextInfo) (lctx : LocalContext) (x : M Unit) : IO (Op
| (some _, s) =>
return some { items := sortCompletionItems s.itemsMain ++ sortCompletionItems s.itemsOther, isIncomplete := true }
private def matchAtomic (id: Name) (declName : Name) : Bool :=
private def matchAtomic (id : Name) (declName : Name) : Bool :=
match id, declName with
| Name.str Name.anonymous s₁ _, Name.str Name.anonymous s₂ _ => s₁.isPrefixOf s₂
| _, _ => false
@ -172,6 +172,14 @@ private def idCompletionCore (ctx : ContextInfo) (id : Name) (danglingDot : Bool
if (← matchUsingNamespace ns) then
return ()
| _ => pure ()
-- Recall that aliases may not be atomic and include the namespace where they were created.
let matchAlias (ns : Name) (alias : Name) : Bool :=
ns.isPrefixOf alias && matchAtomic id (alias.replacePrefix ns Name.anonymous)
-- Auxiliary function for `alias`
let addAlias (alias : Name) (declNames : List Name) : M Unit := do
declNames.forM fun declName => do
unless (← isBlackListed declName) do
addCompletionItemForDecl alias declName expectedType?
-- search explicitily open `ids`
for openDecl in ctx.openDecls do
match openDecl with
@ -179,13 +187,21 @@ private def idCompletionCore (ctx : ContextInfo) (id : Name) (danglingDot : Bool
unless (← isBlackListed resolvedId) do
if matchAtomic id openedId then
addCompletionItemForDecl openedId resolvedId expectedType?
| _ => pure ()
| OpenDecl.simple ns except =>
getAliasState env |>.forM fun alias declNames => do
if matchAlias ns alias then
addAlias alias declNames
-- search for aliases
getAliasState env |>.forM fun alias declNames => do
if matchAtomic id alias then
declNames.forM fun declName => do
unless (← isBlackListed declName) do
addCompletionItemForDecl alias declName expectedType?
-- use current namespace
let rec searchAlias (ns : Name) : M Unit := do
if matchAlias ns alias then
addAlias alias declNames
else
match ns with
| Name.str p .. => searchAlias p
| _ => return ()
searchAlias ctx.currNamespace
-- TODO search macros
-- TODO search namespaces

View file

@ -0,0 +1,10 @@
import Lean
open Lean in
#check getRe
--^ textDocument/completion
namespace Lean
#check getRe
--^ textDocument/completion
end Lean

View file

@ -0,0 +1,26 @@
{"textDocument": {"uri": "file://863.lean"},
"position": {"line": 3, "character": 12}}
{"items":
[{"label": "getReducibilityStatus",
"detail":
"[inst : Monad m] → [inst : MonadEnv m] → Name → m ReducibilityStatus"},
{"label": "getReducibilityStatusImp",
"detail": "Environment → Name → ReducibilityStatus"},
{"label": "getRef", "detail": "[self : MonadRef m] → m Syntax"},
{"label": "getRegularInitFnNameFor?",
"detail": "Environment → Name → Option Name"},
{"label": "getRevAliases", "detail": "Environment → Name → List Name"}],
"isIncomplete": true}
{"textDocument": {"uri": "file://863.lean"},
"position": {"line": 7, "character": 12}}
{"items":
[{"label": "getReducibilityStatus",
"detail":
"[inst : Monad m] → [inst : MonadEnv m] → Name → m ReducibilityStatus"},
{"label": "getReducibilityStatusImp",
"detail": "Environment → Name → ReducibilityStatus"},
{"label": "getRef", "detail": "[self : MonadRef m] → m Syntax"},
{"label": "getRegularInitFnNameFor?",
"detail": "Environment → Name → Option Name"},
{"label": "getRevAliases", "detail": "Environment → Name → List Name"}],
"isIncomplete": true}