Update unnecessary tset lint to handle any key nesting depth.

The unnecessary tset lint was assuming a single key, but it was
triggering for calls with multiple nested keys, causing the quickfix
action to drop all elements after the fourth argument, which was assumed
to be the value.

Now it's been updated to handle nested calls of any depth.
This commit is contained in:
Michele Campeotto 2025-03-22 10:24:23 +01:00 committed by Phil Hagelberg
parent 8d74f0134a
commit e504013663
4 changed files with 39 additions and 15 deletions

View File

@ -87,9 +87,24 @@ the `file.diagnostics` field, filling it with diagnostics."
:codeDescription "unnecessary-method"}))))
(λ unnecessary-tset [server file head call]
(λ all-syms? [call start end]
(faccumulate [syms true
i start end]
(and syms
(could-be-rewritten-as-sym? (. call i)))))
(λ make-new-text [call]
(.. (faccumulate [text "(set "
i 2 (- (length call) 2)]
(.. text (tostring (. call i)) "."))
(tostring (. call (- (length call) 1)))
" "
(view (. call (length call)))
")"))
(if (and (sym? head :tset)
(sym? (. call 2))
(could-be-rewritten-as-sym? (. call 3))
(all-syms? call 3 (- (length call) 1))
(. file.lexical call))
(diagnostic {:range (message.ast->range server file call)
:message (.. "unnecessary " (tostring head))
@ -97,9 +112,7 @@ the `file.diagnostics` field, filling it with diagnostics."
:code 309
:codeDescription "unnecessary-tset"}
#[{:range (message.ast->range server file call)
:newText (string.format "(set %s.%s %s)"
(tostring (. call 2)) (. call 3)
(view (. call 4)))}])))
:newText (make-new-text call)}])))
(λ unnecessary-do-values [server file head call]
(if (and (or (sym? head :do) (sym? head :values))

View File

@ -42,14 +42,23 @@
"Prefix with _ to silence warning"
"(local _x 10)"))
; (fn test-fix-method-function []
; (check "(local x {})
; (fn x:y [a b c]
; (print client a b c))"
; "TO-BE-NAMED"
; "(local x {})
; (fn x.y [client a b c]
; (print client a b c))"))
(fn test-unnecessary-tset []
(check "==(tset state :mouse 496)=="
"Replace with set"
"(set state.mouse 496)")
(check "==(tset state :mouse :cursor 496)=="
"Replace with set"
"(set state.mouse.cursor 496)")
(check "==(tset state :mouse :cursor {:x 4 :y 7})=="
"Replace with set"
"(set state.mouse.cursor {:x 4 :y 7})")
(check "==(tset state :mouse :cursor :x 496)=="
"Replace with set"
"(set state.mouse.cursor.x 496)"))
{: test-fix-op-no-arguments
: test-fix-unused-definition}
: test-fix-unused-definition
: test-unnecessary-tset}

View File

@ -22,6 +22,7 @@
:test.completion
:test.references
:test.document-highlight
:test.signature-help
:test.lint
:test.code-action
:test.rename

View File

@ -185,6 +185,7 @@
:message "unnecessary tset"
:range {:start {:character 15 :line 0}
:end {:character 32 :line 0}}}])
(check "(local tbl {}) (tset tbl :key :nested 9)" [{:code 309}])
;; Lint only triggers on keys that can be written as a sym
(check "(local tbl {}) (tset tbl \"hello-world\" 249)" [{:code 309}])
(assert-ok "(local tbl {}) (tset tbl \"01234567\" 249)")
@ -274,5 +275,5 @@
: test-unset-var
: test-match-should-case
: test-unpack-into-op
: test-unpack-in-middle
}
: test-unpack-in-middle}