diff --git a/src/fennel-ls/analyzer.fnl b/src/fennel-ls/analyzer.fnl index b62c4d1..eadeb60 100644 --- a/src/fennel-ls/analyzer.fnl +++ b/src/fennel-ls/analyzer.fnl @@ -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} diff --git a/src/fennel-ls/completion.fnl b/src/fennel-ls/completion.fnl index c6d3544..e9005fb 100644 --- a/src/fennel-ls/completion.fnl +++ b/src/fennel-ls/completion.fnl @@ -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") diff --git a/src/fennel-ls/handlers.fnl b/src/fennel-ls/handlers.fnl index 35513cc..342b89f 100644 --- a/src/fennel-ls/handlers.fnl +++ b/src/fennel-ls/handlers.fnl @@ -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)} diff --git a/src/fennel-ls/lint.fnl b/src/fennel-ls/lint.fnl index 71ea540..1301b67 100644 --- a/src/fennel-ls/lint.fnl +++ b/src/fennel-ls/lint.fnl @@ -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