Add diagnostic warning for unnecessary : call.

When you have a call to the `:` special which could just be a multisym
method call, emit a warning for that.
This commit is contained in:
Phil Hagelberg 2023-11-15 11:30:44 -08:00 committed by XeroOl
parent 27d1df23eb
commit c8f9b71057
4 changed files with 37 additions and 7 deletions

View File

@ -2,6 +2,7 @@
Goes through a file and mutates the `file.diagnostics` field, filling it with diagnostics."
(local fennel (require :fennel))
(local language (require :fennel-ls.language))
(local message (require :fennel-ls.message))
(local utils (require :fennel-ls.utils))
@ -30,11 +31,26 @@ Goes through a file and mutates the `file.diagnostics` field, filling it with di
:code 302
:codeDescription "field checking I guess"})))))
(λ unnecessary-method [self file]
(icollect [[colon receiver method &as call] (pairs file.calls)
&into file.diagnostics]
(if (and (= (fennel.sym ":") colon)
(fennel.sym? receiver)
(= :string (type method)))
(case (message.ast->range self file call)
range {: range
:message "unnecessary : call; use multisym"
:severity message.severity.WARN
:code 302
:codeDescription "unnecessary colon"}))))
(λ check [self file]
"fill up the file.diagnostics table with linting things"
(if self.configuration.checks.unused-definition
(unused-definition self file))
(if self.configuration.checks.unknown-module-field
(unknown-module-field self file)))
(unknown-module-field self file))
(if self.configuration.checks.unnecessary-method
(unnecessary-method self file)))
{: check}

View File

@ -6,6 +6,7 @@ I have them all here because I have a feeling I am conflating
missing fields with null fields, and I want to have one location
to look to fix this in the future."
(local fennel (require :fennel))
(local utils (require :fennel-ls.utils))
(local json (require :json.json))
@ -59,11 +60,11 @@ to look to fix this in the future."
:result (nullify ?result)})
(λ ast->range [self file ?ast]
(case (values (utils.get-ast-info ?ast :bytestart)
(utils.get-ast-info ?ast :byteend))
(bytestart byteend)
{:start (utils.byte->position file.text bytestart self.position-encoding)
:end (utils.byte->position file.text (+ byteend 1) self.position-encoding)}))
(case (fennel.ast-source ?ast)
{: bytestart : byteend} {:start (utils.byte->position file.text bytestart
self.position-encoding)
:end (utils.byte->position file.text (+ byteend 1)
self.position-encoding)}))
(λ multisym->range [self file ast n]
(let [spl (utils.multi-sym-split ast)]

View File

@ -95,7 +95,8 @@ in the \"self\" object."
:macro-path (option "./?.fnl;./?/init-macros.fnl;./?/init.fnl;src/?.fnl;src/?/init-macros.fnl;src/?/init.fnl")
:version (option "lua54")
:checks {:unused-definition (option true)
:unknown-module-field (option true)}})
:unknown-module-field (option true)
:unnecessary-method (option true)}})
(λ make-configuration [?c]
(make-configuration-from-template default-configuration ?c))

View File

@ -100,6 +100,18 @@
responses (self:open-file! filename "(fn [abc] (set abc.xyz 10))")]
(assert (not (?. responses 1 :params :diagnostics 1)))))
(it "warns when using the : special when a multisym would do"
(let [self (create-client)]
(match (self:open-file! filename "(let [x :haha] (: x :find :a))")
[{:params {: diagnostics}}]
(is (find [i v (ipairs diagnostics)]
(match v
{:message "unnecessary : call; use multisym"
:range {:start {:character 15 :line 0}
:end {:character 29 :line 0}}}
v)))
_ (error "did not match"))))
(it "warns if a var is written but not read"
(let [self (create-client)
responses (self:open-file! filename "(var x 1) (set x 2) (set [x] [3])")]