From e0067880d1cfcde89f124b0bb82c97929dd1ebe4 Mon Sep 17 00:00:00 2001 From: XeroOl Date: Wed, 29 May 2024 22:38:55 -0500 Subject: [PATCH] Unknown field lint only triggers at stack size 1 This is probably not a good commit message, but basically, if you require a module foo, and then look for foo.bar.baz, it won't trigger, but foo.bar will trigger it. --- src/fennel-ls/language.fnl | 32 ++++++++++++++++++-------------- src/fennel-ls/lint.fnl | 2 +- test/lint.fnl | 6 ++++++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/fennel-ls/language.fnl b/src/fennel-ls/language.fnl index de644cc..7c76b55 100644 --- a/src/fennel-ls/language.fnl +++ b/src/fennel-ls/language.fnl @@ -65,17 +65,18 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find (stack-add-split! stack (utils.multi-sym-split symbol))) (λ search-document [self document stack opts] - (when (not= (tostring (?. document :binding)) :_G) - (set opts.searched-through-require true)) + (when (and (not= (tostring (?. document :binding)) :_G) + (= (length stack) 1)) + (set opts.searched-through-require-with-stack-size-1 true)) (if (= 0 (length stack)) document (and document.fields (. document.fields (. stack (length stack)))) (search-document self (. document.fields (table.remove stack)) stack opts))) -(λ search-val [self file ast stack opts] +(λ search-val [self file ?ast stack opts] "searches for the definition of the ast, adjusted to 1 value" - (search-multival self file ast stack 1 opts)) + (search-multival self file ?ast stack 1 opts)) (λ search-assignment [self file assignment stack opts] (let [{:target {:binding _ @@ -130,7 +131,9 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find (let [newfile (state.get-by-module self mod)] (when newfile (let [newitem (. newfile.ast (length newfile.ast))] - (search-val self newfile newitem stack (doto opts (tset :searched-through-require true))))))))) + (when (= (length stack) 1) + (set opts.searched-through-require-with-stack-size-1 true)) + (search-val self newfile newitem stack opts))))))) "." (if (= multival 1) (let [[_ & rest] call] @@ -149,15 +152,16 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find {:definition call : file}))))) ;; BASE CASE!! (set search-multival - (λ [self file ast stack multival opts] - (if (list? ast) (search-list self file ast stack multival opts) - (varg? ast) nil ;; TODO function-args - (= 1 multival) - (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) - (= :string (type ast)) (search-document self (docs.get-global self :string) stack opts)) - nil))) + (λ [self file ?ast stack multival opts] + (let [ast ?ast] ;; it was a bad idea to use λ because ast may be nil + (if (list? ast) (search-list self file ast stack multival opts) + (varg? ast) nil ;; TODO function-args + (= 1 multival) + (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) + (= :string (type ast)) (search-document self (docs.get-global self :string) stack opts)) + nil)))) ;; the options thing is getting out of hand diff --git a/src/fennel-ls/lint.fnl b/src/fennel-ls/lint.fnl index 3ebbc83..800bcc9 100644 --- a/src/fennel-ls/lint.fnl +++ b/src/fennel-ls/lint.fnl @@ -47,7 +47,7 @@ the `file.diagnostics` field, filling it with diagnostics." (if (. (utils.multi-sym-split symbol) 2) (let [opts {} item (language.search-ast self file symbol [] opts)] - (if (and (not item) opts.searched-through-require) + (if (and (not item) opts.searched-through-require-with-stack-size-1) {:range (message.ast->range self file symbol) :message (.. "unknown field: " (tostring symbol)) :severity message.severity.WARN diff --git a/test/lint.fnl b/test/lint.fnl index 9c64cf6..8899160 100644 --- a/test/lint.fnl +++ b/test/lint.fnl @@ -98,6 +98,12 @@ (check "_G.insert2" [] [{:code 302}]) + ;; we don't care about nested + (check {:requireme.fnl "{:field []}" + :main.fnl "(local {: field} (require :requireme)) + field.unknown"} + [] + [{:code 302}]) nil) (fn test-unnecessary-colon []