simplify search api

This commit is contained in:
XeroOl 2025-06-28 17:47:51 -05:00
parent 6826c7584d
commit 67663d8271
4 changed files with 23 additions and 21 deletions

View File

@ -187,28 +187,31 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
(local {:metadata METADATA} (require :fennel.compiler))
;; the options thing is getting out of hand
(λ search-main [server file symbol opts initialization-opts]
"Find the definition of a symbol"
(λ search [server file ast opts initialization-opts]
"Find the definition of an ast"
(assert (= (type initialization-opts) :table))
;; The stack is the multi-sym parts still to search
;; for example, if I'm searching for "foo.bar.baz", my immediate priority is to find foo,
;; and the stack has ["baz" "bar"]. "bar" is at the "top"/"end" of the stack as the next key to search.
(if (sym? symbol)
(if (sym? ast)
;; when your search starts as a symbol, there's lots of special interesting things to consider
(let [stack
(if initialization-opts.stack
initialization-opts.stack
(let [?byte initialization-opts.byte
split (utils.multi-sym-split symbol (if ?byte (- ?byte symbol.bytestart)))]
split (utils.multi-sym-split ast (if ?byte (- ?byte ast.bytestart)))]
(stack-add-split! [] split)))]
(case (docs.get-builtin server (utils.multi-sym-base symbol))
(case (docs.get-builtin server (utils.multi-sym-base ast))
document (search-document server document stack opts)
_ (case (. file.references symbol)
_ (case (. file.references ast)
;; we want to search at least once, assuming opts.stop-early?
ref (search-reference server file ref stack opts)
_ (case (. file.definitions symbol)
_ (case (. file.definitions ast)
def (search-multival server file def.definition (stack-add-keys! stack def.keys) (or def.multival 1) opts)
_ (case (. file.macro-refs symbol)
ref {:binding symbol :metadata (. METADATA ref)})))))))
_ (case (. file.macro-refs ast)
ref {:binding ast :metadata (. METADATA ref)})))))
(search-val server file ast (or initialization-opts.stack []) opts)))
(λ find-local-definition [file name ?scope]
(when ?scope
@ -319,17 +322,16 @@ returns the called symbol and the number of the argument closest to byte"
(λ find-definition [server file symbol ?byte]
(if (. file.definitions symbol)
(. file.definitions symbol)
(search-main server file symbol {:stop-early? false} {:byte ?byte})))
(search server file symbol {:stop-early? false} {:byte ?byte})))
(λ find-nearest-definition [server file symbol ?byte]
(if (. file.definitions symbol)
(. file.definitions symbol)
(search-main server file symbol {:stop-early? true} {:byte ?byte})))
(search server file symbol {:stop-early? true} {:byte ?byte})))
{: find-symbol
: find-nearest-call
: find-nearest-definition
: find-definition
: search-main
: search-name-and-scope
:search-ast search-val}
: search
: search-name-and-scope}

View File

@ -51,7 +51,7 @@
(when (fennel.table? definition.definition)
(each [field value (pairs definition.definition)]
(when (= (type field) :string)
(case (analyzer.search-ast server definition.file value [] {})
(case (analyzer.search server definition.file value {} {})
def (add-field-recursively! field def)
_ (do
(io.stderr:write "BAD!!!! undocumented field: " (tostring field) "\n")

View File

@ -89,9 +89,9 @@ Every time the client sends a message, it gets handled by a function in the corr
(if
;; require call
(. file.require-calls parent)
(analyzer.search-ast server file parent [] {:stop-early? true})
(analyzer.search server file parent {:stop-early? true} {})
;; regular symbol
(analyzer.search-main server file symbol {:stop-early? true} {: byte}))
(analyzer.search server file symbol {:stop-early? true} {: byte}))
result
(if result.file
(message.range-and-uri server result.file (or result.binding result.definition)))
@ -156,7 +156,7 @@ Every time the client sends a message, it gets handled by a function in the corr
(let [file (files.get-by-uri server uri)
byte (utils.position->byte file.text position server.position-encoding)]
(case-try (analyzer.find-symbol file.ast byte)
symbol (analyzer.search-main server file symbol {} {: byte})
symbol (analyzer.search server file symbol {} {: byte})
{:indeterminate nil &as result} {:contents (formatter.hover-format result)
:range (message.ast->range server file
symbol)}

View File

@ -46,10 +46,10 @@ the `file.diagnostics` field, filling it with diagnostics."
(accumulate [in? false call (pairs calls) &until in?]
(and (sym? (. call 1) :or) (utils.find call symbol))))
(fn module-field-helper [server file symbol ?ast stack]
(fn module-field-helper [server file symbol ?ast ?stack]
"if ?ast is a module field that isn't known, return a diagnostic"
(let [opts {}
item (analyzer.search-ast server file ?ast stack opts)]
item (analyzer.search server file ?ast opts {:stack ?stack})]
(if (and (not item)
(. file.lexical symbol)
(not (in-or? file.calls symbol))
@ -66,7 +66,7 @@ the `file.diagnostics` field, filling it with diagnostics."
"any multisym whose definition can't be found through a (require) call"
(icollect [symbol (pairs file.references) &into file.diagnostics]
(if (. (utils.multi-sym-split symbol) 2)
(module-field-helper server file symbol symbol [])))
(module-field-helper server file symbol symbol)))
(icollect [symbol binding (pairs file.definitions) &into file.diagnostics]
(if binding.keys