diff --git a/src/fennel-ls/diagnostics.fnl b/src/fennel-ls/diagnostics.fnl index 7c6995b..2e75857 100644 --- a/src/fennel-ls/diagnostics.fnl +++ b/src/fennel-ls/diagnostics.fnl @@ -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} diff --git a/src/fennel-ls/message.fnl b/src/fennel-ls/message.fnl index 7471a56..90564fe 100644 --- a/src/fennel-ls/message.fnl +++ b/src/fennel-ls/message.fnl @@ -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)] diff --git a/src/fennel-ls/state.fnl b/src/fennel-ls/state.fnl index e4b158b..c6dcdd8 100644 --- a/src/fennel-ls/state.fnl +++ b/src/fennel-ls/state.fnl @@ -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)) diff --git a/test/diagnostic-test.fnl b/test/diagnostic-test.fnl index 48de5c3..1f75a54 100644 --- a/test/diagnostic-test.fnl +++ b/test/diagnostic-test.fnl @@ -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])")]