From 3a30fc83edfb9eec6c6348837c083bd59d8cc5ce Mon Sep 17 00:00:00 2001 From: Phil Hagelberg Date: Sun, 2 Mar 2025 22:05:33 -0800 Subject: [PATCH] Support (or table.unpack _G.unpack) pattern without unknown field lint. Now we are selflint clean! We can enable it in the ci target now. --- Makefile | 2 +- src/fennel-ls/lint.fnl | 8 ++++++++ src/fennel-ls/utils.fnl | 6 +++++- test/diagnostic.fnl | 5 +++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fc3026e..0adf563 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ check-luarocks: eval "$$(luarocks path)"; \ fennel-ls --lint -ci: testall check-deps check-luarocks +ci: selflint testall check-deps check-luarocks clean: rm -fr $(EXE) old-deps old-fennel build/ diff --git a/src/fennel-ls/lint.fnl b/src/fennel-ls/lint.fnl index a4269f3..7f04af4 100644 --- a/src/fennel-ls/lint.fnl +++ b/src/fennel-ls/lint.fnl @@ -52,11 +52,19 @@ the `file.diagnostics` field, filling it with diagnostics." #[{:range (message.ast->range server file symbol) :newText (.. "_" (tostring symbol))}]))) +;; this is way too specific; it's also safe to do this inside an `if` or `case` +(fn in-or? [calls symbol] + (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] "if ?ast is a module field that isn't known, return a diagnostic" (let [opts {} item (analyzer.search-ast server file ?ast stack opts)] (if (and (not item) + (not (in-or? file.calls symbol)) + ;; this doesn't necessarily have to come thru require; it works + ;; for built-in modules too opts.searched-through-require-with-stack-size-1) (diagnostic {:range (message.ast->range server file symbol) diff --git a/src/fennel-ls/utils.fnl b/src/fennel-ls/utils.fnl index 1f8e310..c99c288 100644 --- a/src/fennel-ls/utils.fnl +++ b/src/fennel-ls/utils.fnl @@ -206,6 +206,9 @@ WARNING: this is only used in the test code, not in the real language server" (: :gsub "/+" "/") (->> (pick-values 1)))) +(fn find [t x ?k] + (match (next t ?k) (k x) k (k y_) (find t x k))) + {: uri->path : path->uri : pos->position @@ -220,4 +223,5 @@ WARNING: this is only used in the test code, not in the real language server" : absolute-path? : path-join : path-sep - : endswith} + : endswith + : find} diff --git a/test/diagnostic.fnl b/test/diagnostic.fnl index 3d953e1..77cfe8d 100644 --- a/test/diagnostic.fnl +++ b/test/diagnostic.fnl @@ -156,6 +156,11 @@ [{:message "unknown identifier: unpack"} {:message "unknown identifier: warn"}] {:lua-version "union"}) + ;; can reference table.unpack in an or + (check "(print (or table.unpack _G.unpack))" + [] + [{:message "unknown field: table.unpack"}] + {:lua-version "intersection"}) ;; deprecated functions still work (check "(print (math.atan2 (tonumber (io.read))))" []