make the completion tests run faster
performance is starting to bother me, but I've made completions faster (in tests).
This commit is contained in:
parent
8811454456
commit
1c3d7fbe21
@ -38,18 +38,6 @@ is set to true and we report that we support completionItem/resolve."
|
||||
(local compiler (require :fennel-ls.compiler))
|
||||
(local {:metadata METADATA} (require :fennel.compiler))
|
||||
|
||||
(local hardcoded-completions
|
||||
{:nil {:metadata {:fnl/docstring "Represents the absence of a useful value."
|
||||
:fls/itemKind "Keyword"}}
|
||||
:true {:metadata {:fnl/docstring "A boolean value representing truth."
|
||||
:fls/itemKind "Keyword"}}
|
||||
:false {:metadata {:fnl/docstring "A boolean value representing falsehood."
|
||||
:fls/itemKind "Keyword"}}
|
||||
:.nan {:metadata {:fnl/docstring "NaN"
|
||||
:fls/itemKind "Constant"}}
|
||||
:.inf {:metadata {:fnl/docstring "inf"
|
||||
:fls/itemKind "Constant"}}})
|
||||
|
||||
(λ textDocument/completion [server _send {: position :textDocument {: uri}}]
|
||||
;; get the file
|
||||
(let [file (files.get-by-uri server uri)
|
||||
@ -80,7 +68,7 @@ is set to true and we report that we support completionItem/resolve."
|
||||
"add the completion. also recursively adds the fields' completions"
|
||||
(when (not (. seen definition))
|
||||
(set (. seen definition) true)
|
||||
(add-completion! name definition "Value")
|
||||
(add-completion! name definition)
|
||||
(each [field def ?string-method (navigate.iter-fields server definition)]
|
||||
(if (or (= :self (tostring (?. def :metadata :fnl/arglist 1)))
|
||||
?string-method
|
||||
@ -97,11 +85,7 @@ is set to true and we report that we support completionItem/resolve."
|
||||
(set (. seen definition) false)))
|
||||
|
||||
(fn expression-completions []
|
||||
(each [name documentation (pairs hardcoded-completions)]
|
||||
(add-completion! name documentation))
|
||||
|
||||
(local seen-manglings {})
|
||||
|
||||
(each [_ global* (ipairs file.allowed-globals)]
|
||||
(when (not (. seen-manglings global*))
|
||||
(set (. seen-manglings global*) true)
|
||||
@ -156,14 +140,13 @@ is set to true and we report that we support completionItem/resolve."
|
||||
|
||||
(fn completionItem/resolve [server _send completion-item]
|
||||
(let [result
|
||||
(or (. hardcoded-completions completion-item.name)
|
||||
(let [{: uri : byte} completion-item.data
|
||||
file (files.get-by-uri server uri)
|
||||
(_symbol parents) (analyzer.find-symbol file.ast byte)
|
||||
scope (or (accumulate [?find nil _ parent (ipairs parents) &until ?find]
|
||||
(. file.scopes parent))
|
||||
file.scope)]
|
||||
(analyzer.search-name-and-scope server file completion-item.label scope)))]
|
||||
(let [{: uri : byte} completion-item.data
|
||||
file (files.get-by-uri server uri)
|
||||
(_symbol parents) (analyzer.find-symbol file.ast byte)
|
||||
scope (or (accumulate [?find nil _ parent (ipairs parents) &until ?find]
|
||||
(. file.scopes parent))
|
||||
file.scope)]
|
||||
(analyzer.search-name-and-scope server file completion-item.label scope))]
|
||||
(when result
|
||||
(set completion-item.documentation (format.hover-format server completion-item.label result)))
|
||||
completion-item))
|
||||
|
||||
@ -97,9 +97,22 @@ Handles grabbing the documentation from sources other than fennel code;
|
||||
(or (get-library-global server global-name)
|
||||
(. (get-lua-version server.configuration.lua-version) global-name)))
|
||||
|
||||
(local hardcoded-special-items
|
||||
{:nil {:metadata {:fnl/docstring "Represents the absence of a useful value."
|
||||
:fls/itemKind "Keyword"}}
|
||||
:true {:metadata {:fnl/docstring "A boolean value representing truth."
|
||||
:fls/itemKind "Keyword"}}
|
||||
:false {:metadata {:fnl/docstring "A boolean value representing falsehood."
|
||||
:fls/itemKind "Keyword"}}
|
||||
:.nan {:metadata {:fnl/docstring "NaN"
|
||||
:fls/itemKind "Constant"}}
|
||||
:.inf {:metadata {:fnl/docstring "inf"
|
||||
:fls/itemKind "Constant"}}})
|
||||
|
||||
(fn get-builtin [_server builtin-name]
|
||||
(or (. specials builtin-name)
|
||||
(. macros* builtin-name)))
|
||||
(. macros* builtin-name)
|
||||
(. hardcoded-special-items builtin-name)))
|
||||
|
||||
(λ validate-lua-version [lua-version invalid]
|
||||
(case (. lua-versions lua-version)
|
||||
|
||||
@ -193,14 +193,11 @@ fntype is one of fn or λ or lambda"
|
||||
{:label name
|
||||
:documentation (when (not server.can-do-good-completions?) (hover-format server name definition))
|
||||
:textEdit (when (not server.can-do-good-completions?) {:newText name : range})
|
||||
:kind (or (if (not= ?kind :Value) (?. kinds ?kind))
|
||||
:kind (or (?. kinds ?kind)
|
||||
(if (name:find ".:") kinds.Method)
|
||||
(case (navigate.getmetadata server definition)
|
||||
metadata
|
||||
(or (?. kinds metadata.fls/itemKind)
|
||||
(when metadata.fnl/arglist
|
||||
(if (name:find ":") kinds.Method kinds.Function))))
|
||||
(?. kinds ?kind)
|
||||
kinds.Text)})
|
||||
metadata (?. kinds metadata.fls/itemKind))
|
||||
kinds.Value)})
|
||||
|
||||
{: signature-help-format
|
||||
: hover-format
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
: encoding
|
||||
:locations [{:range {: start : end}}]
|
||||
: initialize-response} (create-client "(let [==𐐀𐐀== 100] 𐐀𐐀|)"
|
||||
{:position-encodings [:utf-16]
|
||||
{:capabilities {:general {:positionEncodings [:utf-16]}}
|
||||
:markup-encoding :utf-16})
|
||||
[response] (client:definition uri cursor)]
|
||||
(faith.= :utf-16 encoding)
|
||||
@ -23,8 +23,8 @@
|
||||
: encoding
|
||||
:locations [{:range {: start : end}}]
|
||||
: initialize-response} (create-client "(let [==𐐀𐐀== 100] 𐐀𐐀|)"
|
||||
{:position-encodings [:utf-8]
|
||||
:markup-encoding :utf-8})
|
||||
{:capabilities {:general {:positionEncodings [:utf-8]}}
|
||||
:markup-encoding :utf-8})
|
||||
[response] (client:definition uri cursor)]
|
||||
(faith.= :utf-8 encoding)
|
||||
(faith.= :utf-8 (. initialize-response 1 :result :capabilities :positionEncoding))
|
||||
@ -33,13 +33,13 @@
|
||||
(faith.= end response.result.range.end))
|
||||
|
||||
;; utf-16 is the fallback
|
||||
(let [{: initialize-response} (create-client "" {:position-encodings NIL})]
|
||||
(let [{: initialize-response} (create-client "" {:capabilities {:general {}}})]
|
||||
(faith.= :utf-16 (. initialize-response 1 :result :capabilities :positionEncoding)))
|
||||
|
||||
(let [{: initialize-response} (create-client "" {:position-encodings [:some-unknown-encoding]})]
|
||||
(let [{: initialize-response} (create-client "" {:capabilities {:general {:positionEncodings [:some-unknown-encoding]}}})]
|
||||
(faith.= :utf-16 (. initialize-response 1 :result :capabilities :positionEncoding)))
|
||||
|
||||
(let [{: initialize-response} (create-client "" {:position-encodings [:utf-8 :utf-16]})]
|
||||
(let [{: initialize-response} (create-client "" {:capabilities {:general {:positionEncodings [:utf-8 :utf-16]}}})]
|
||||
(faith.= :utf-8 (. initialize-response 1 :result :capabilities :positionEncoding)))
|
||||
|
||||
nil)
|
||||
|
||||
@ -9,62 +9,77 @@
|
||||
:Snippet 15 :Color 16 :File 17 :Reference 18 :Folder 19 :EnumMember 20
|
||||
:Constant 21 :Struct 22 :Event 23 :Operator 24 :TypeParameter 25})
|
||||
|
||||
(fn find [completions e]
|
||||
(accumulate [result nil
|
||||
i c (ipairs completions)
|
||||
&until result]
|
||||
(if (or (and (= (type e) :string)
|
||||
(= c.label e))
|
||||
(and (= (type e) :table)
|
||||
(or (= e.label nil)
|
||||
(and (= (type e.label) :string) (= e.label c.label))
|
||||
(and (= (type e.label) :function) (e.label c.label)))
|
||||
(or (= e.kind nil)
|
||||
(and (= (type e.kind) :number) (= e.kind c.kind))
|
||||
(and (= (type e.kind) :function) (e.kind c.kind)))
|
||||
(or (= e.filterText nil)
|
||||
(and (= (type e.filterText) :string) (= e.filterText c.filterText))
|
||||
(and (= (type e.filterText) :function) (e.filterText c.filterText)))
|
||||
(or (= e.insertText nil)
|
||||
(and (= (type e.insertText) :string) (= e.insertText c.insertText))
|
||||
(and (= (type e.insertText) :function) (e.insertText c.insertText)))
|
||||
(or (= e.documentation nil)
|
||||
(and (= (type e.documentation) :string) (= e.documentation c.documentation))
|
||||
(and (= (type e.documentation) :function) (e.documentation c.documentation))
|
||||
(and (= e.documentation true) (not= nil c.documentation)))
|
||||
(or (= e.textEdit nil)
|
||||
(and (= (type e.textEdit) :table)
|
||||
(= e.textEdit.range.start.line c.textEdit.range.start.line)
|
||||
(= e.textEdit.range.start.character c.textEdit.range.start.character)
|
||||
(= e.textEdit.range.end.line c.textEdit.range.end.line)
|
||||
(= e.textEdit.range.end.character c.textEdit.range.end.character)
|
||||
(= e.textEdit.newText c.textEdit.newText))
|
||||
(and (= (type e.textEdit) :function) (e.textEdit c.textEdit)))))
|
||||
i)))
|
||||
(fn find [client params e]
|
||||
(let [completions (or params.items params)]
|
||||
(accumulate [result nil
|
||||
i c (ipairs completions)
|
||||
&until result]
|
||||
(let [c (if params.itemDefaults
|
||||
(collect [k v (pairs params.itemDefaults) &into (collect [k v (pairs c)] k v)] k v)
|
||||
c)]
|
||||
(if (or (and (= (type e) :string)
|
||||
(= c.label e))
|
||||
(and (= (type e) :table)
|
||||
(or (= e.label nil)
|
||||
(and (= (type e.label) :string) (= e.label c.label))
|
||||
(and (= (type e.label) :function) (e.label c.label)))
|
||||
(or (= e.kind nil)
|
||||
(and (= (type e.kind) :number) (= e.kind c.kind))
|
||||
(and (= (type e.kind) :function) (e.kind c.kind)))
|
||||
(or (= e.filterText nil)
|
||||
(and (= (type e.filterText) :string) (= e.filterText c.filterText))
|
||||
(and (= (type e.filterText) :function) (e.filterText c.filterText)))
|
||||
(or (= e.insertText nil)
|
||||
(and (= (type e.insertText) :string) (= e.insertText c.insertText))
|
||||
(and (= (type e.insertText) :function) (e.insertText c.insertText)))
|
||||
(or (= e.documentation nil)
|
||||
(let [c (if params.items (-> (client:completion-item-resolve c)
|
||||
(. 1 :result))
|
||||
c)]
|
||||
(or
|
||||
(and (= (type e.documentation) :string) (= e.documentation c.documentation))
|
||||
(and (= (type e.documentation) :function) (e.documentation c.documentation))
|
||||
(and (= e.documentation true) (not= nil c.documentation)))))
|
||||
(or (= e.textEdit nil)
|
||||
(let [c-textEdit (or c.textEdit {:range c.editRange :newText (or c.insertText c.label)})]
|
||||
(and (= (type e.textEdit) :table)
|
||||
(= e.textEdit.range.start.line c-textEdit.range.start.line)
|
||||
(= e.textEdit.range.start.character c-textEdit.range.start.character)
|
||||
(= e.textEdit.range.end.line c-textEdit.range.end.line)
|
||||
(= e.textEdit.range.end.character c-textEdit.range.end.character)
|
||||
(= e.textEdit.newText c-textEdit.newText)))
|
||||
(and (= (type e.textEdit) :function) (e.textEdit c.textEdit)))))
|
||||
i)))))
|
||||
|
||||
(fn check [file-contents expected unexpected ?client-opts]
|
||||
(let [{: client : uri : cursor : text} (create-client file-contents ?client-opts)
|
||||
(fn check [file-contents expected unexpected ?bad-completions?]
|
||||
(let [{: client : uri : cursor : text} (create-client file-contents (if (not ?bad-completions?)
|
||||
{:capabilities
|
||||
{:textDocument
|
||||
{:completion
|
||||
{:completionList
|
||||
{:itemDefaults
|
||||
[:editRange :data]}}}}}))
|
||||
[{:result ?result}] (client:completion uri
|
||||
(or cursor
|
||||
(position-past-end-of-text text)))
|
||||
completions (or ?result [])]
|
||||
|
||||
(each [_ e (ipairs unexpected)]
|
||||
(let [i (find completions e)]
|
||||
(let [i (find client completions e)]
|
||||
(faith.= nil i (.. "Got unexpected completion: " (view e) "\n"
|
||||
"from: " (view file-contents) "\n"
|
||||
(view (. completions i) {:escape-newlines? true})))))
|
||||
(view (. (or completions.items completions) i) {:escape-newlines? true})))))
|
||||
|
||||
(if (= (type expected) :table)
|
||||
(each [_ e (ipairs expected)]
|
||||
(let [i (find completions e)]
|
||||
(let [i (find client completions e)]
|
||||
(faith.is i (.. "Didn't get completion: " (view e) "\n"
|
||||
"from: " (view file-contents) "\n"
|
||||
(if (= (type e) :table)
|
||||
(let [candidate (find completions {:label e.label})]
|
||||
(let [candidate (find client completions {:label e.label})]
|
||||
(if candidate
|
||||
(.. "Candidate that didn't match:\n"
|
||||
(view (. completions candidate)
|
||||
(view (. (or completions.items completions) candidate)
|
||||
{:escape-newlines? true}))
|
||||
""))
|
||||
"")))))
|
||||
@ -111,7 +126,7 @@
|
||||
(check "(local x {:field 100})\n(if x.fi" [:x.field] [])
|
||||
(check "(let [x 10] (let [x 10] x"
|
||||
(fn [completions]
|
||||
(faith.= 1 (accumulate [number-of-x 0 _ completion (ipairs completions)]
|
||||
(faith.= 1 (accumulate [number-of-x 0 _ completion (ipairs completions.items)]
|
||||
(if (= completion.label :x)
|
||||
(+ number-of-x 1)
|
||||
number-of-x))))
|
||||
@ -185,37 +200,10 @@
|
||||
nil)
|
||||
|
||||
(fn test-docs []
|
||||
(check "(fn xyzzy [x y z] \"docstring\" nil)\n(xyzz"
|
||||
[{:label :xyzzy :kind kinds.Function :documentation true}]
|
||||
[])
|
||||
|
||||
;; things that aren't present in lua5.4 but are in other versions, I guess??
|
||||
(local things-that-are-allowed-to-have-missing-docs
|
||||
{:lua 1 :set-forcibly! 1}) ;:unpack 1 :setfenv 1 :getfenv 1 :module 1 :newproxy 1 :gcinfo 1 :loadstring 1 :bit 1 :jit 1 :bit32 1})
|
||||
|
||||
(check "("
|
||||
[;; builtin specials
|
||||
{:label :local
|
||||
:kind kinds.Operator
|
||||
:documentation true
|
||||
:textEdit {:range {:start {:line 0 :character 1}
|
||||
:end {:line 0 :character 1}}
|
||||
:newText :local}}
|
||||
;; builtin macros
|
||||
{:label :-?>
|
||||
:kind kinds.Keyword
|
||||
:documentation true}
|
||||
;; builtin globals
|
||||
{:label :table
|
||||
:kind kinds.Module
|
||||
:documentation true}
|
||||
{:label :_G
|
||||
:kind kinds.Variable
|
||||
:documentation true}]
|
||||
[{:documentation #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))}
|
||||
{:kind #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))}
|
||||
{:label #(= nil $)}])
|
||||
|
||||
(check "(let [x (fn x [a b c]
|
||||
\"docstring\"
|
||||
nil)
|
||||
@ -226,16 +214,40 @@
|
||||
{:kind #(= nil $)}
|
||||
{:label #(= nil $)}])
|
||||
|
||||
(check "(let [x :hi]
|
||||
(x:|))"
|
||||
[:x:gsub
|
||||
:x:match
|
||||
:x:match
|
||||
:x:sub
|
||||
:x:len
|
||||
:x:find]
|
||||
[{:documentation #(= nil $)}])
|
||||
|
||||
(each [_ mode (ipairs [true false])]
|
||||
(check "(fn x [a b c]
|
||||
\"docstring\"
|
||||
nil)
|
||||
(let [str :hi]
|
||||
(|))"
|
||||
[;; builtin specials
|
||||
{:label :local
|
||||
:kind kinds.Operator
|
||||
:documentation true}
|
||||
;; builtin macros
|
||||
{:label :-?>
|
||||
:kind kinds.Keyword
|
||||
:documentation true}
|
||||
;; builtin globals
|
||||
{:label :table
|
||||
:kind kinds.Module
|
||||
:documentation true}
|
||||
{:label :_G
|
||||
:kind kinds.Variable
|
||||
:documentation true}
|
||||
;; method fields
|
||||
{:label :str:gsub :kind kinds.Method :documentation true}
|
||||
{:label :str:match :kind kinds.Method :documentation true}
|
||||
{:label :str:match :kind kinds.Method :documentation true}
|
||||
{:label :str:sub :kind kinds.Method :documentation true}
|
||||
{:label :str:len :kind kinds.Method :documentation true}
|
||||
{:label :str:find :kind kinds.Method :documentation true}
|
||||
;; things in scope
|
||||
{:label :x :kind kinds.Function :documentation true}]
|
||||
[{:documentation #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))}
|
||||
{:kind #(= nil $) :label #(not (. things-that-are-allowed-to-have-missing-docs $))}
|
||||
{:label #(= nil $)}]
|
||||
mode))
|
||||
nil)
|
||||
|
||||
(fn test-module []
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
(icollect [_ range (ipairs ranges) &into highlights]
|
||||
{: range :kind 1}))
|
||||
|
||||
params {:capabilities {:general {:positionEncodings (un-nil (or opts.position-encodings [default-encoding]))}}
|
||||
params {:capabilities (or opts.capabilities {:general {:positionEncodings [default-encoding]}})
|
||||
:clientInfo (un-nil (or opts.client-info {:name "Neovim" :version "0.7.2"}))
|
||||
:initializationOptions opts.initialization-options
|
||||
:processId 16245
|
||||
|
||||
Loading…
Reference in New Issue
Block a user