unknown module field lint works on definitions
This commit is contained in:
parent
e493b0e21f
commit
6801d0d3d9
@ -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")
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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))
|
||||||
|
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user