Diagnostics with similar iterators are fused together
This commit is contained in:
parent
814ebb4dfa
commit
ea89ecad9f
@ -2,14 +2,13 @@
|
|||||||
Provides the function (check self file), which goes through a file and mutates
|
Provides the function (check self file), which goes through a file and mutates
|
||||||
the `file.diagnostics` field, filling it with diagnostics."
|
the `file.diagnostics` field, filling it with diagnostics."
|
||||||
|
|
||||||
(local fennel (require :fennel))
|
(local {: sym? : list? : view} (require :fennel))
|
||||||
(local language (require :fennel-ls.language))
|
(local language (require :fennel-ls.language))
|
||||||
(local message (require :fennel-ls.message))
|
(local message (require :fennel-ls.message))
|
||||||
(local utils (require :fennel-ls.utils))
|
(local utils (require :fennel-ls.utils))
|
||||||
|
|
||||||
(λ unused-definition [self file]
|
(λ unused-definition [self file symbol definition]
|
||||||
"local variable that is defined but not used"
|
"local variable that is defined but not used"
|
||||||
(icollect [symbol definition (pairs file.definitions) &into file.diagnostics]
|
|
||||||
(if (and (not= "_" (: (tostring symbol) :sub 1 1))
|
(if (and (not= "_" (: (tostring symbol) :sub 1 1))
|
||||||
(not (accumulate [reference false
|
(not (accumulate [reference false
|
||||||
_ ref (ipairs definition.referenced-by)
|
_ ref (ipairs definition.referenced-by)
|
||||||
@ -20,7 +19,7 @@ the `file.diagnostics` field, filling it with diagnostics."
|
|||||||
:message (.. "unused definition: " (tostring symbol))
|
:message (.. "unused definition: " (tostring symbol))
|
||||||
:severity message.severity.WARN
|
:severity message.severity.WARN
|
||||||
:code 301
|
:code 301
|
||||||
:codeDescription "unused-definition"})))
|
:codeDescription "unused-definition"}))
|
||||||
|
|
||||||
(λ unknown-module-field [self file]
|
(λ unknown-module-field [self 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"
|
||||||
@ -35,12 +34,12 @@ the `file.diagnostics` field, filling it with diagnostics."
|
|||||||
:code 302
|
:code 302
|
||||||
:codeDescription "unknown-module-field"})))))
|
:codeDescription "unknown-module-field"})))))
|
||||||
|
|
||||||
(λ unnecessary-method [self file]
|
(λ unnecessary-method [self 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"
|
||||||
(icollect [[colon receiver method &as call] (pairs file.calls)
|
(if (sym? colon ":")
|
||||||
&into file.diagnostics]
|
(let [receiver (. call 2)
|
||||||
(if (and (fennel.sym? colon ":")
|
method (. call 3)]
|
||||||
(fennel.sym? receiver)
|
(if (and (sym? receiver)
|
||||||
(. file.lexical call)
|
(. file.lexical call)
|
||||||
(= :string (type method))
|
(= :string (type method))
|
||||||
(not (method:find "^[0-9]"))
|
(not (method:find "^[0-9]"))
|
||||||
@ -50,53 +49,65 @@ the `file.diagnostics` field, filling it with diagnostics."
|
|||||||
:message (.. "unnecessary : call: use (" (tostring receiver) ":" method ")")
|
:message (.. "unnecessary : call: use (" (tostring receiver) ":" method ")")
|
||||||
:severity message.severity.WARN
|
:severity message.severity.WARN
|
||||||
:code 303
|
:code 303
|
||||||
:codeDescription "unnecessary-method"}))))
|
:codeDescription "unnecessary-method"})))))
|
||||||
|
|
||||||
(local ops {"+" 1 "-" 1 "*" 1 "/" 1 "//" 1 "%" 1 ".." 1 "and" 1 "or" 1})
|
(local ops {"+" 1 "-" 1 "*" 1 "/" 1 "//" 1 "%" 1 ".." 1 "and" 1 "or" 1})
|
||||||
(λ bad-unpack [self file]
|
(λ bad-unpack [self file op call]
|
||||||
"an unpack call leading into an operator"
|
"an unpack call leading into an operator"
|
||||||
(icollect [[op &as call] (pairs file.calls)
|
(if (and (sym? op)
|
||||||
&into file.diagnostics]
|
|
||||||
(if (and (fennel.sym? op)
|
|
||||||
(. ops (tostring op))
|
(. ops (tostring op))
|
||||||
;; last item is an unpack call
|
;; last item is an unpack call
|
||||||
(fennel.list? (. call (length call)))
|
(list? (. call (length call)))
|
||||||
(or (fennel.sym? (. call (length call) 1) :unpack)
|
(or (sym? (. call (length call) 1) :unpack)
|
||||||
(fennel.sym? (. call (length call) 1) :_G.unpack)
|
(sym? (. call (length call) 1) :_G.unpack)
|
||||||
(fennel.sym? (. call (length call) 1) :table.unpack))
|
(sym? (. call (length call) 1) :table.unpack))
|
||||||
;; Only the unpack call needs to be present in the original file.
|
;; Only the unpack call needs to be present in the original file.
|
||||||
(. file.lexical (. call (length call))))
|
(. file.lexical (. call (length call))))
|
||||||
(case (message.ast->range self file (. call (length call)))
|
(case (message.ast->range self file (. call (length call)))
|
||||||
range {: range
|
range {: range
|
||||||
:message (.. "faulty unpack call: " (tostring op) " isn't variadic at runtime."
|
:message (.. "faulty unpack call: " (tostring op) " isn't variadic at runtime."
|
||||||
(if (fennel.sym? op "..")
|
(if (sym? op "..")
|
||||||
(let [unpackme (fennel.view (. call (length call) 2))]
|
(let [unpackme (view (. call (length call) 2))]
|
||||||
(.. " Use (table.concat " unpackme ") instead of (.. (unpack " unpackme "))"))
|
(.. " Use (table.concat " unpackme ") instead of (.. (unpack " unpackme "))"))
|
||||||
(.. " Use a loop when you have a dynamic number of arguments to (" (tostring op) ")")))
|
(.. " Use a loop when you have a dynamic number of arguments to (" (tostring op) ")")))
|
||||||
:severity message.severity.WARN
|
:severity message.severity.WARN
|
||||||
:code 304
|
:code 304
|
||||||
:codeDescription "bad-unpack"}))))
|
:codeDescription "bad-unpack"})))
|
||||||
|
|
||||||
(λ var-never-set [self file]
|
(λ var-never-set [self file symbol definition]
|
||||||
(icollect [symbol definition (pairs file.definitions) &into file.diagnostics]
|
|
||||||
(if (and definition.var? (not definition.var-set))
|
(if (and definition.var? (not definition.var-set))
|
||||||
{:range (message.ast->range self file symbol)
|
{:range (message.ast->range self file symbol)
|
||||||
:message (.. "var is never set: " (tostring symbol) " Consider using (local) instead of (var)")
|
:message (.. "var is never set: " (tostring symbol) " Consider using (local) instead of (var)")
|
||||||
:severity message.severity.WARN
|
:severity message.severity.WARN
|
||||||
:code 305
|
:code 305
|
||||||
:codeDescription "var-never-set"})))
|
:codeDescription "var-never-set"}))
|
||||||
|
|
||||||
(λ check [self file]
|
(λ check [self file]
|
||||||
"fill up the file.diagnostics table with linting things"
|
"fill up the file.diagnostics table with linting things"
|
||||||
(if self.configuration.checks.unused-definition
|
(let [checks self.configuration.checks
|
||||||
(unused-definition self file))
|
d file.diagnostics]
|
||||||
(if self.configuration.checks.unknown-module-field
|
;; definition diagnostics
|
||||||
(unknown-module-field self file))
|
(each [symbol definition (pairs file.definitions)]
|
||||||
(if self.configuration.checks.unnecessary-method
|
(if checks.unused-definition
|
||||||
(unnecessary-method self file))
|
(tset d (+ 1 (length d)) (unused-definition self file symbol definition)))
|
||||||
(if self.configuration.checks.bad-unpack
|
(if checks.var-never-set
|
||||||
(bad-unpack self file))
|
(tset d (+ 1 (length d)) (var-never-set self file symbol definition))))
|
||||||
(if self.configuration.checks.var-never-set
|
|
||||||
(var-never-set self file)))
|
;; call diagnostics
|
||||||
|
(each [[head &as call] (pairs file.calls)]
|
||||||
|
(when head
|
||||||
|
(if checks.bad-unpack
|
||||||
|
(tset d (+ 1 (length d)) (bad-unpack self file head call)))
|
||||||
|
(if checks.unnecessary-method
|
||||||
|
(tset d (+ 1 (length d)) (unnecessary-method self file head call)))))
|
||||||
|
|
||||||
|
(if checks.unknown-module-field
|
||||||
|
(unknown-module-field self file))))
|
||||||
|
;; (if checks.unnecessary-values
|
||||||
|
;; (unnecessary-values file)))
|
||||||
|
;; (if checks.unnecessary-do)
|
||||||
|
;; (unnecessary-do file)))
|
||||||
|
;; (if checks.unnecessary-unary-op))
|
||||||
|
;; (unnecessary-values file)))
|
||||||
|
|
||||||
{: check}
|
{: check}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user