unknown module field lint works on definitions

This commit is contained in:
XeroOl 2024-07-07 23:53:54 -05:00
parent e493b0e21f
commit 6801d0d3d9
5 changed files with 23 additions and 13 deletions

View File

@ -2,7 +2,7 @@
(local dispatch (require :fennel-ls.dispatch)) (local dispatch (require :fennel-ls.dispatch))
(local json-rpc (require :fennel-ls.json-rpc)) (local json-rpc (require :fennel-ls.json-rpc))
check [filenames] lint [filenames]
"non-interactive mode that gets executed from CLI with --lint. "non-interactive mode that gets executed from CLI with --lint.
runs lints on each file, then formats and prints them" runs lints on each file, then formats and prints them"
(local files (require :fennel-ls.files)) (local files (require :fennel-ls.files))
@ -38,7 +38,7 @@
(λ main [] (λ main []
(case arg (case arg
["--lint" & filenames] (check filenames) ["--lint" & filenames] (lint filenames)
(where (or ["--server"] [nil])) (main-loop (io.input) (where (or ["--server"] [nil])) (main-loop (io.input)
(io.output)) (io.output))
_args (do (io.stderr:write "USAGE: fennel-ls [--lint file] [--server]\n") _args (do (io.stderr:write "USAGE: fennel-ls [--lint file] [--server]\n")

View File

@ -61,7 +61,7 @@ identifiers are declared / referenced in which places."
"Compile the file, and record all the useful information from the compiler into the file object" "Compile the file, and record all the useful information from the compiler into the file object"
;; The useful information being recorded: ;; The useful information being recorded:
(let [definitions-by-scope (doto {} (setmetatable has-tables-mt)) (let [definitions-by-scope (doto {} (setmetatable has-tables-mt))
definitions {} ; symbol -> definition definitions {} ; symbol -> binding
diagnostics {} ; [diagnostic] diagnostics {} ; [diagnostic]
references {} ; symbol -> references references {} ; symbol -> references
macro-refs {} ; symbol -> macro macro-refs {} ; symbol -> macro

View File

@ -273,7 +273,7 @@ Every time the client sends a message, it gets handled by a function in the corr
(send (message.diagnostics file)) (send (message.diagnostics file))
(set file.open? true)) (set file.open? true))
(λ notifications.textDocument/didSave [server send {: uri}] (λ notifications.textDocument/didSave [server _send {: uri}]
(when (utils.endswith uri "flsproject.fnl") (when (utils.endswith uri "flsproject.fnl")
(config.reload server)) (config.reload server))

View File

@ -42,18 +42,27 @@ the `file.diagnostics` field, filling it with diagnostics."
#[{:range (message.ast->range server file symbol) #[{:range (message.ast->range server file symbol)
:newText (.. "_" (tostring symbol))}]))) :newText (.. "_" (tostring 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) opts.searched-through-require-with-stack-size-1)
{:range (message.ast->range server file symbol)
:message (.. "unknown field: " (tostring symbol))
:severity message.severity.WARN
:code 302
:codeDescription "unknown-module-field"})))
(λ unknown-module-field [server file] (λ unknown-module-field [server file]
"any multisym whose definition can't be found through a (require) call" "any multisym whose definition can't be found through a (require) call"
(icollect [symbol (pairs file.references) &into file.diagnostics] (icollect [symbol (pairs file.references) &into file.diagnostics]
(if (. (utils.multi-sym-split symbol) 2) (if (. (utils.multi-sym-split symbol) 2)
(let [opts {} (module-field-helper server file symbol symbol [])))
item (analyzer.search-ast server file symbol [] opts)]
(if (and (not item) opts.searched-through-require-with-stack-size-1) (icollect [symbol binding (pairs file.definitions) &into file.diagnostics]
{:range (message.ast->range server file symbol) (if binding.keys
:message (.. "unknown field: " (tostring symbol)) (module-field-helper server file symbol binding.definition (fcollect [i (length binding.keys) 1 -1]
:severity message.severity.WARN (. binding.keys i))))))
:code 302
:codeDescription "unknown-module-field"})))))
(λ unnecessary-method [server file colon call] (λ unnecessary-method [server file colon call]
"a call to the : builtin that could just be a multisym" "a call to the : builtin that could just be a multisym"

View File

@ -92,7 +92,8 @@
:main.fnl :main.fnl
"(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 :message "unknown field: guy.d"}] [{:code 302 :message "unknown field: c"}
{:code 302 :message "unknown field: guy.d"}]
[{:code 302 :message "unknown field: a"} [{:code 302 :message "unknown field: a"}
{:code 302 :message "unknown field: b"}]) {:code 302 :message "unknown field: b"}])
(check "table.insert2 table.insert" (check "table.insert2 table.insert"