Lints for doc fields, doc hovers on strings

This commit is contained in:
XeroOl 2024-05-04 15:36:03 -05:00
parent 926dff9267
commit 2d7c8b1ad7
4 changed files with 32 additions and 14 deletions

View File

@ -6,9 +6,10 @@ compiler's plugin hook callbacks. It stores lexical info about which
identifiers are declared / referenced in which places." identifiers are declared / referenced in which places."
(local {: sym? : list? : sequence? : table? : sym : view &as fennel} (require :fennel)) (local {: sym? : list? : sequence? : table? : sym : view &as fennel} (require :fennel))
(local docs (require :fennel-ls.docs))
(local message (require :fennel-ls.message)) (local message (require :fennel-ls.message))
(local utils (require :fennel-ls.utils))
(local searcher (require :fennel-ls.searcher)) (local searcher (require :fennel-ls.searcher))
(local utils (require :fennel-ls.utils))
(fn scope? [candidate] (fn scope? [candidate]
;; just checking a couple of the fields ;; just checking a couple of the fields
@ -86,10 +87,12 @@ identifiers are declared / referenced in which places."
(assert (scope? scope) :not-a-scope) (assert (scope? scope) :not-a-scope)
;; find reference ;; find reference
(let [name (string.match (tostring symbol) "[^%.:]+")] (let [name (string.match (tostring symbol) "[^%.:]+")]
(case (find-definition (tostring name) scope) (case (or (find-definition (tostring name) scope)
(docs.get-global-metadata name))
target (let [ref {: symbol : target : ref-type}] target (let [ref {: symbol : target : ref-type}]
(tset references symbol ref) (tset references symbol ref)
(table.insert target.referenced-by ref))))) (when target.referenced-by
(table.insert target.referenced-by ref))))))
(λ symbol-to-expression [ast scope ?reference?] (λ symbol-to-expression [ast scope ?reference?]
(assert (sym? ast) "symbols only") (assert (sym? ast) "symbols only")

View File

@ -65,6 +65,7 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
(stack-add-split! stack (utils.multi-sym-split symbol))) (stack-add-split! stack (utils.multi-sym-split symbol)))
(λ search-document [self document stack opts] (λ search-document [self document stack opts]
(doto opts (tset :searched-through-require true))
(if (= 0 (length stack)) (if (= 0 (length stack))
document document
(. document.fields (. stack (length stack))) (. document.fields (. stack (length stack)))
@ -90,23 +91,23 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
(search-assignment self file {:target (. ?fields (table.remove stack))} stack opts) (search-assignment self file {:target (. ?fields (table.remove stack))} stack opts)
(search-multival self file ?definition (stack-add-keys! stack ?keys) (or ?multival 1) opts)))) (search-multival self file ?definition (stack-add-keys! stack ?keys) (or ?multival 1) opts))))
(λ search-reference [self file ref stack opts]
(if ref.target.metadata
(search-document self ref.target stack opts)
ref.target.binding
(search-assignment self file ref stack opts)))
(λ search-symbol [self file symbol stack opts] (λ search-symbol [self file symbol stack opts]
(if (= (tostring symbol) :nil) (if (= (tostring symbol) :nil)
(if (= 0 (length stack)) (if (= 0 (length stack))
{:definition symbol : file} {:definition symbol : file}
nil) nil)
(if (. file.references symbol) (if (. file.references symbol)
(search-assignment self file (. file.references symbol) (stack-add-multisym! stack symbol) opts) (search-reference self file (. file.references symbol) (stack-add-multisym! stack symbol) opts))))
(let [parts (utils.multi-sym-split symbol)]
(case (docs.get-global-metadata (. parts 1))
document (search-document self document (stack-add-split! stack parts) opts)
_ nil)))))
(λ search-table [self file tbl stack opts] (λ search-table [self file tbl stack opts]
(if (. tbl (. stack (length stack))) (if (. tbl (. stack (length stack)))
(search-val self file (. tbl (table.remove stack)) stack opts) (search-val self file (. tbl (table.remove stack)) stack opts)
(= 0 (length stack))
{:definition tbl : file} ;; BASE CASE !!
nil)) ;; BASE CASE Give up nil)) ;; BASE CASE Give up
(λ search-list [self file call stack multival opts] (λ search-list [self file call stack multival opts]
@ -151,8 +152,9 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
(varg? ast) nil ;; TODO function-args (varg? ast) nil ;; TODO function-args
(= 1 multival) (= 1 multival)
(if (sym? ast) (search-symbol self file ast stack opts) (if (sym? ast) (search-symbol self file ast stack opts)
(= 0 (length stack)) {:definition ast : file} ;; BASE CASE !!
(= :table (type ast)) (search-table self file ast stack opts) (= :table (type ast)) (search-table self file ast stack opts)
(= 0 (length stack)) {:definition ast : file}) ;; BASE CASE !! (= :string (type ast)) (search-document self (docs.get-global-metadata :string) stack opts))
nil))) nil)))
@ -175,7 +177,7 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
(case (docs.get-global-metadata (utils.multi-sym-base symbol)) (case (docs.get-global-metadata (utils.multi-sym-base symbol))
document (search-document self document stack opts) document (search-document self document stack opts)
_ (case (. file.references symbol) _ (case (. file.references symbol)
ref (search-assignment self file ref stack opts) ref (search-reference self file ref stack opts)
_ (case (. file.definitions symbol) _ (case (. file.definitions symbol)
def (search-multival self file def.definition (stack-add-keys! stack def.keys) (or def.multival 1) opts))))))) def (search-multival self file def.definition (stack-add-keys! stack def.keys) (or def.multival 1) opts)))))))
@ -260,6 +262,5 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
{: find-symbol {: find-symbol
: find-nearest-definition : find-nearest-definition
: search-main : search-main
: search-assignment
: search-name-and-scope : search-name-and-scope
:search-ast search-val} :search-ast search-val}

View File

@ -65,6 +65,16 @@ new message handler `msgh`.")
(check "(table.inser|t [] :message" #($:find "```fnl\n(insert list ?pos value)\n```" 1 true)) (check "(table.inser|t [] :message" #($:find "```fnl\n(insert list ?pos value)\n```" 1 true))
nil) nil)
(fn test-module []
(check "coroutine.yie|ld"
"```fnl\n(yield ...)\n```\nSuspends the execution of the calling coroutine.\nAny arguments to `yield` are passed as extra results to `resume`.")
(check "string.cha|r"
"```fnl\n(char ...)\n```\nReceives zero or more integers.\nReturns a string with length equal to the number of arguments,\nin which each character has the internal numeric code equal\nto its corresponding argument.\n\nNumeric codes are not necessarily portable across platforms.")
(check "(local x :hello)
x.cha|r"
"```fnl\n(char ...)\n```\nReceives zero or more integers.\nReturns a string with length equal to the number of arguments,\nin which each character has the internal numeric code equal\nto its corresponding argument.\n\nNumeric codes are not necessarily portable across platforms."))
(fn test-functions [] (fn test-functions []
(check "(fn my-function| [arg1 arg2 arg3] (check "(fn my-function| [arg1 arg2 arg3]
(print arg1 arg2 arg3))" (print arg1 arg2 arg3))"
@ -124,6 +134,7 @@ new message handler `msgh`.")
{: test-literals {: test-literals
: test-builtins : test-builtins
: test-globals : test-globals
: test-module
: test-functions : test-functions
: test-multisym : test-multisym
: test-crash : test-crash

View File

@ -88,7 +88,10 @@
"(local {: a : c &as guy} (require :the-guy-they-tell-you-not-to-worry-about)) "(local {: a : c &as guy} (require :the-guy-they-tell-you-not-to-worry-about))
(print guy.b guy.d)"} (print guy.b guy.d)"}
[{:code 302}] [{:code 302 :message "unknown module field: a"} [{:code 302}] [{:code 302 :message "unknown module field: a"}
{:code 302 :message "unknown module field: b"}])) {:code 302 :message "unknown module field: b"}])
(check "table.insert2"
[{:code 302}]
[]))
(fn test-unnecessary-colon [] (fn test-unnecessary-colon []
(check "(let [x :haha] (: x :find :a))" (check "(let [x :haha] (: x :find :a))"