Add diagnostic for var-never-set.
This uses the isvar field from the opts map of the destructure hook.
This commit is contained in:
parent
f25fd9fd60
commit
5055fd31ef
@ -83,7 +83,7 @@ later by fennel-ls.language to answer requests from the client."
|
||||
(when (or ?reference? (fennel.multi-sym? ast))
|
||||
(reference ast scope)))
|
||||
|
||||
(λ define [?definition binding scope]
|
||||
(λ define [?definition binding scope ?opts]
|
||||
;; Add a definition to the definitions
|
||||
;; recursively explore the binding (which, in the general case, is a destructuring assignment)
|
||||
;; right now I'm not keeping track of *how* the symbol was destructured: just finding all the symbols for now.
|
||||
@ -96,7 +96,8 @@ later by fennel-ls.language to answer requests from the client."
|
||||
:referenced-by (or (?. definitions binding :referenced-by) [])
|
||||
:keys (if (< 0 (length keys))
|
||||
(fcollect [i 1 (length keys)]
|
||||
(. keys i)))}]
|
||||
(. keys i)))
|
||||
:var? (?. ?opts :isvar)}]
|
||||
(tset (. definitions-by-scope scope) (tostring binding) definition)
|
||||
(tset definitions binding definition))
|
||||
(list? binding)
|
||||
@ -104,7 +105,7 @@ later by fennel-ls.language to answer requests from the client."
|
||||
(= (length binding)
|
||||
(- (length ?definition) 1)))
|
||||
(for [i 1 (length binding)]
|
||||
(define (. ?definition (+ i 1)) (. binding i) scope))
|
||||
(define (. ?definition (+ i 1)) (. binding i) scope ?opts))
|
||||
(recurse (. binding 1) keys))
|
||||
(table? binding)
|
||||
(accumulate [prev nil
|
||||
@ -135,10 +136,10 @@ later by fennel-ls.language to answer requests from the client."
|
||||
;; (fcollect [i 1 (length keys)]
|
||||
;; (. keys i)))}
|
||||
name (string.match (tostring binding) "[^%.:]+")]
|
||||
(when (multisym? binding)
|
||||
(case (find-definition (tostring name) scope)
|
||||
target
|
||||
(table.insert target.referenced-by binding))))
|
||||
(case (find-definition (tostring name) scope)
|
||||
target (if (multisym? binding)
|
||||
(table.insert target.referenced-by binding)
|
||||
(set target.var-set true))))
|
||||
(= :table (type binding))
|
||||
(each [k v (iter binding)]
|
||||
(table.insert keys k)
|
||||
@ -146,11 +147,11 @@ later by fennel-ls.language to answer requests from the client."
|
||||
(table.remove keys))))
|
||||
(recurse binding []))
|
||||
|
||||
(λ destructure [to from scope {:declaration ?declaration?}]
|
||||
(λ destructure [to from scope {:declaration ?declaration? &as opts}]
|
||||
;; I really don't understand symtype
|
||||
;; I think I need an explanation
|
||||
(if ?declaration?
|
||||
(define to from scope)
|
||||
(define to from scope opts)
|
||||
(mutate to from scope)))
|
||||
|
||||
(λ add-field [ast multisym scope]
|
||||
|
||||
@ -73,6 +73,15 @@ Goes through a file and mutates the `file.diagnostics` field, filling it with di
|
||||
:code 304
|
||||
:codeDescription "bad-unpack"}))))
|
||||
|
||||
(λ var-never-set [self file]
|
||||
(icollect [symbol definition (pairs file.definitions) &into file.diagnostics]
|
||||
(if (and definition.var? (not definition.var-set))
|
||||
{:range (message.ast->range self file symbol)
|
||||
:message (.. "var is never set: " (tostring symbol))
|
||||
:severity message.severity.WARN
|
||||
:code 301
|
||||
:codeDescription "var-never-set"})))
|
||||
|
||||
(λ check [self file]
|
||||
"fill up the file.diagnostics table with linting things"
|
||||
(if self.configuration.checks.unused-definition
|
||||
@ -82,6 +91,8 @@ Goes through a file and mutates the `file.diagnostics` field, filling it with di
|
||||
(if self.configuration.checks.unnecessary-method
|
||||
(unnecessary-method self file))
|
||||
(if self.configuration.checks.bad-unpack
|
||||
(bad-unpack self file)))
|
||||
(bad-unpack self file))
|
||||
(if self.configuration.checks.var-never-set
|
||||
(var-never-set self file)))
|
||||
|
||||
{: check}
|
||||
|
||||
@ -96,7 +96,8 @@ in the \"self\" object."
|
||||
:checks {:unused-definition (option true)
|
||||
:unknown-module-field (option true)
|
||||
:unnecessary-method (option true)
|
||||
:bad-unpack (option true)}
|
||||
:bad-unpack (option true)
|
||||
:var-never-set (option true)}
|
||||
:extra-globals (option "")})
|
||||
|
||||
(λ make-configuration [?c]
|
||||
|
||||
@ -81,6 +81,20 @@
|
||||
"not found")
|
||||
_ (error "did not match"))))
|
||||
|
||||
(it "warns about vars that are never set"
|
||||
(let [self (create-client)
|
||||
responses (self:open-file! filename "(var x nil) (print x)")]
|
||||
(match responses
|
||||
[{:params {: diagnostics}}]
|
||||
(is (find [_ v (ipairs diagnostics)]
|
||||
(match v
|
||||
{:message "var is never set: x"
|
||||
:range {:start {:character 5 :line 0}
|
||||
:end {:character 6 :line 0}}}
|
||||
v))
|
||||
"not found")
|
||||
_ (error "did not match"))))
|
||||
|
||||
(it "warns about unused functions"
|
||||
(let [self (create-client)
|
||||
responses (self:open-file! filename "(fn x [])")]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user