duplicate-table-keys lint

This commit is contained in:
XeroOl 2025-07-12 16:11:36 -05:00
parent d219cfffcb
commit d4c24b00f4
2 changed files with 41 additions and 3 deletions

View File

@ -16,7 +16,8 @@ the `file.diagnostics` field, filling it with diagnostics."
:reference []
:macro-call []
:function-call []
:special-call []})
:special-call []
:other []})
(local all-lints [])
@ -331,6 +332,25 @@ the `file.diagnostics` field, filling it with diagnostics."
:message (.. "too many args. my analysis of the signature says we ignore any arguments past " min-params " arguments but you've provided " number-of-args)
:severity message.severity.WARN})))))})
(add-lint :duplicate-table-keys
{:type :other
:impl (fn [server file]
(let [seen []]
(each [ast (pairs file.lexical)]
(when (table? ast)
(case (getmetatable ast)
{: keys} (let [dkey (accumulate [_ 1 i v (ipairs keys) &until (. seen v)]
(do (set (. seen v) i)
(+ i 1)))]
(when (. keys dkey)
(coroutine.yield
{:code :duplicate-table-keys
:range (message.ast->range server file ast)
:message (.. "key " (tostring (. keys dkey)) " appears more than once")
:severity message.severity.WARN}))
(each [k (pairs seen)]
(set (. seen k) nil))))))))})
(local lint-mt {:__tojson (fn [{: self} state] (dkjson.encode self state))
:__index #(. $1 :self $2)})
@ -349,7 +369,9 @@ the `file.diagnostics` field, filling it with diagnostics."
(table.insert file.diagnostics
(wrap (doto diagnostic
(tset :code lint.name))))))))
(each [diagnostic (coroutine.wrap #(run lints.other server file))]
(table.insert file.diagnostics
(wrap diagnostic)))
(each [symbol definition (pairs file.definitions)]
(when (. file.lexical symbol)
(run lints.definition server file symbol definition)))

View File

@ -315,6 +315,21 @@
:flsproject.fnl "{:lints {:mismatched-argument-count true}}"})
nil)
(fn test-duplicate-keys []
(assert-ok "{:a 1 :b 2}")
(assert-ok "(local _ {:a 1}) {:a 2}")
(check "{:a 1 :a 2}" [{:code :duplicate-table-keys :message "key a appears more than once"}])
(check "{:there :are
:lots :of
:choices :for
:which :key
:to :include
:in :the
:message :.
:which :one?}" [{:code :duplicate-table-keys :message "key which appears more than once"}])
(check "(local a 1) {:a 2 : a}" [{:code :duplicate-table-keys}])
nil)
;; TODO lints:
;; duplicate keys in kv table
;; (tset <sym> <any>) --> (set (. <sym> <any>)) (might be wanted for compat?)
@ -341,4 +356,5 @@
: test-op-with-no-arguments
: test-empty-let
: test-decreasing-comparison
: test-arg-count}
: test-arg-count
: test-duplicate-keys}