clean up quickfix lint title system
This commit is contained in:
parent
623700e1a2
commit
fc57612fea
@ -108,7 +108,7 @@ Every time the client sends a message, it gets handled by a function in the corr
|
||||
symbol
|
||||
(analyzer.find-nearest-definition server this-file symbol byte)
|
||||
{: referenced-by :file {:uri this-file.uri &as file} : binding}
|
||||
(let [result (icollect [_ {:symbol reference} (ipairs referenced-by)]
|
||||
(let [result (icollect [_ {:symbol reference} (ipairs referenced-by) &into (message.array)]
|
||||
{:range (message.ast->range server file reference)
|
||||
:kind documentHighlightKind.Read})]
|
||||
(table.insert result {:range (message.ast->range server file binding)
|
||||
@ -142,12 +142,12 @@ Every time the client sends a message, it gets handled by a function in the corr
|
||||
(let [file (files.get-by-uri server uri)
|
||||
byte (utils.position->byte file.text position server.position-encoding)]
|
||||
(case-try (analyzer.find-nearest-call server file byte)
|
||||
(symbol active-parameter)
|
||||
(analyzer.find-definition server file symbol)
|
||||
(call active-parameter)
|
||||
(analyzer.find-definition server file call)
|
||||
{:indeterminate nil &as definition}
|
||||
(formatter.signature-help-format definition)
|
||||
signature
|
||||
(message.symbol->signature-help server file symbol
|
||||
(message.call->signature-help server file call
|
||||
signature
|
||||
active-parameter)
|
||||
(catch _ nil))))
|
||||
@ -207,9 +207,8 @@ Every time the client sends a message, it gets handled by a function in the corr
|
||||
|
||||
(λ requests.textDocument/codeAction [server _send {: range :textDocument {: uri}}]
|
||||
(let [file (files.get-by-uri server uri)]
|
||||
(icollect [_ diagnostic (ipairs file.diagnostics)]
|
||||
(if (and (overlap? diagnostic.range range)
|
||||
diagnostic.quickfix)
|
||||
(icollect [_ diagnostic (ipairs file.diagnostics) &into (message.array)]
|
||||
(if (overlap? diagnostic.range range)
|
||||
(message.diagnostic->code-action server file diagnostic :quickfix)))))
|
||||
|
||||
(λ notifications.textDocument/didChange [server send {: contentChanges :textDocument {: uri}}]
|
||||
|
||||
@ -13,8 +13,10 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
(local diagnostic-mt {:__tojson (fn [{: self} state] (dkjson.encode self state))
|
||||
:__index #(. $1 :self $2)})
|
||||
|
||||
(fn diagnostic [self quickfix]
|
||||
(setmetatable {: self : quickfix} diagnostic-mt))
|
||||
(fn diagnostic [self]
|
||||
(let [fix self.fix]
|
||||
(set self.fix nil)
|
||||
(setmetatable {: self : fix} diagnostic-mt)))
|
||||
|
||||
(fn could-be-rewritten-as-sym? [str]
|
||||
(and (= :string (type str)) (not (str:find "^%d"))
|
||||
@ -33,9 +35,10 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
{:range (message.ast->range server file symbol)
|
||||
:message (.. "unused definition: " (tostring symbol))
|
||||
:severity message.severity.WARN
|
||||
:code :unused-definition}
|
||||
#[{:range (message.ast->range server file symbol)
|
||||
:newText (.. "_" (tostring symbol))}])))
|
||||
:code :unused-definition
|
||||
:fix #{:title (.. "Replace " (tostring symbol) " with _" (tostring symbol))
|
||||
:changes [{:range (message.ast->range server file symbol)
|
||||
:newText (.. "_" (tostring symbol))}]}})))
|
||||
|
||||
;; this is way too specific; it's also safe to do this inside an `if` or `case`
|
||||
(fn in-or? [calls symbol]
|
||||
@ -107,9 +110,10 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
(diagnostic {:range (message.ast->range server file call)
|
||||
:message (.. "unnecessary " (tostring head))
|
||||
:severity message.severity.WARN
|
||||
:code :unnecessary-tset}
|
||||
#[{:range (message.ast->range server file call)
|
||||
:newText (make-new-text call)}])))
|
||||
:code :unnecessary-tset
|
||||
:fix #{:title "Replace tset with set"
|
||||
:changes [{:range (message.ast->range server file call)
|
||||
:newText (make-new-text call)}]}})))
|
||||
|
||||
(λ unnecessary-do-values [server file head call]
|
||||
(if (and (or (sym? head :do) (sym? head :values))
|
||||
@ -117,26 +121,31 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
(diagnostic {:range (message.ast->range server file call)
|
||||
:message (.. "unnecessary " (tostring head))
|
||||
:severity message.severity.WARN
|
||||
:code :unnecessary-do-values}
|
||||
#[{:range (message.ast->range server file call)
|
||||
:newText (view (. call 2))}])))
|
||||
:code :unnecessary-do-values
|
||||
:fix #{:title "Unwrap the expression"
|
||||
:changes [{:range (message.ast->range server file call)
|
||||
:newText (view (. call 2))}]}})))
|
||||
|
||||
(local implicit-do-forms (collect [form {: body-form?} (pairs (fennel.syntax))]
|
||||
(values form body-form?)))
|
||||
|
||||
(λ redundant-do [server file head call]
|
||||
(let [last-body (. call (length call))]
|
||||
(if (and (. implicit-do-forms (tostring head)) (. file.lexical call)
|
||||
(list? last-body) (sym? (. last-body 1) :do))
|
||||
(if (and (. implicit-do-forms (tostring head))
|
||||
(. file.lexical call)
|
||||
(list? last-body)
|
||||
(sym? (. last-body 1) :do)
|
||||
(not (unnecessary-do-values server file head call))) ;; we don't want two lints to trigger for same call
|
||||
(diagnostic {:range (message.ast->range server file last-body)
|
||||
:message "redundant do"
|
||||
:severity message.severity.WARN
|
||||
:code :redundant-do}
|
||||
#[{:range (message.ast->range server file last-body)
|
||||
:newText (table.concat
|
||||
(fcollect [i 2 (length last-body)]
|
||||
(view (. last-body i)))
|
||||
" ")}]))))
|
||||
:code :redundant-do
|
||||
:fix #{:title "Unwrap the expression"
|
||||
:changes [{:range (message.ast->range server file last-body)
|
||||
:newText (table.concat
|
||||
(fcollect [i 2 (length last-body)]
|
||||
(view (. last-body i)))
|
||||
" ")}]}}))))
|
||||
|
||||
(λ bad-unpack [server file op call]
|
||||
"an unpack call leading into an operator"
|
||||
@ -160,12 +169,12 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
(.. " Use a loop when you have a dynamic number of "
|
||||
"arguments to (" (tostring op) ")")))
|
||||
:severity message.severity.WARN
|
||||
:code :bad-unpack}
|
||||
(if (and (= (length call) 2)
|
||||
(= (length (. call 2)) 2)
|
||||
(sym? op ".."))
|
||||
#[{:range (message.ast->range server file call)
|
||||
:newText (.. "(table.concat " (view (. call 2 2)) ")")}])))))
|
||||
:code :bad-unpack
|
||||
:fix (if (and (= (length last-item) 2)
|
||||
(sym? op ".."))
|
||||
#{:title "Replace with a call to table.concat"
|
||||
:changes [{:range (message.ast->range server file (if (= 2 (length call)) call last-item))
|
||||
:newText (.. "(table.concat " (view (. last-item 2)) ")")}]})}))))
|
||||
|
||||
(λ var-never-set [server file symbol definition]
|
||||
(if (and definition.var? (not definition.var-set) (. file.lexical symbol))
|
||||
@ -189,9 +198,10 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
{:range (message.ast->range server file call)
|
||||
:message (.. "write " (view identity) " instead of (" (tostring op) ")")
|
||||
:severity message.severity.WARN
|
||||
:code :op-with-no-arguments}
|
||||
#[{:range (message.ast->range server file call)
|
||||
:newText (view identity)}]))))
|
||||
:code :op-with-no-arguments
|
||||
:fix #{:title (.. "Replace (" (tostring op) ") with " (view identity))
|
||||
:changes [{:range (message.ast->range server file call)
|
||||
:newText (view identity)}]}}))))
|
||||
|
||||
(λ no-decreasing-comparison [server file op call]
|
||||
(if (or (sym? op :>) (sym? op :>=))
|
||||
@ -199,13 +209,14 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
{:range (message.ast->range server file call)
|
||||
:message "Use increasing operator instead of decreasing"
|
||||
:severity message.severity.WARN
|
||||
:code :no-decreasing-comparison}
|
||||
#[{:range (message.ast->range server file call)
|
||||
:newText (let [new (if (sym? op :>=) (fennel.sym :<=) (fennel.sym :<))
|
||||
reversed (fcollect [i (length call) 2 -1
|
||||
&into (list (sym new))]
|
||||
(. call i))]
|
||||
(view reversed))}])))
|
||||
:code :no-decreasing-comparison
|
||||
:fix #{:title "Reverse the comparison"
|
||||
:changes [{:range (message.ast->range server file call)
|
||||
:newText (let [new (if (sym? op :>=) (fennel.sym :<=) (fennel.sym :<))
|
||||
reversed (fcollect [i (length call) 2 -1
|
||||
&into (list (sym new))]
|
||||
(. call i))]
|
||||
(view reversed))}]}})))
|
||||
|
||||
(λ match-reference? [ast references]
|
||||
(if (sym? ast) (?. references ast :target)
|
||||
@ -221,9 +232,10 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
(diagnostic {:range (message.ast->range server file (. ast 1))
|
||||
:message "no pinned patterns; use case instead of match"
|
||||
:severity message.severity.WARN
|
||||
:code :match-should-case}
|
||||
#[{:range (message.ast->range server file (. ast 1))
|
||||
:newText "case"}])))
|
||||
:code :match-should-case
|
||||
:fix #{:title "Replace match with case"
|
||||
:changes [{:range (message.ast->range server file (. ast 1))
|
||||
:newText "case"}]}})))
|
||||
|
||||
(λ multival-in-middle-of-call [server file fun call arg index]
|
||||
"generally, values and unpack are signs that the user is trying to do
|
||||
@ -252,11 +264,12 @@ the `file.diagnostics` field, filling it with diagnostics."
|
||||
(diagnostic {:range (message.ast->range server file binding)
|
||||
:message "use do instead of let with no bindings"
|
||||
:severity message.severity.WARN
|
||||
:code :empty-let}
|
||||
#[(let [{: start} (message.ast->range server file let*)
|
||||
{: end} (message.ast->range server file binding)]
|
||||
{:range {: start : end}
|
||||
:newText "do"})])))
|
||||
:code :empty-let
|
||||
:fix #{:title "Replace (let [] ...) with (do ...)"
|
||||
:changes [(let [{: start} (message.ast->range server file let*)
|
||||
{: end} (message.ast->range server file binding)]
|
||||
{:range {: start : end}
|
||||
:newText "do"})]}})))
|
||||
|
||||
(λ add-lint-diagnostics [server file]
|
||||
"fill up the file.diagnostics table with linting things"
|
||||
|
||||
@ -9,6 +9,8 @@ LSP json objects."
|
||||
(local utils (require :fennel-ls.utils))
|
||||
(local json (require :dkjson))
|
||||
|
||||
(local json-array-mt {:__jsontype :array})
|
||||
|
||||
(λ nullify [?value]
|
||||
(case ?value
|
||||
nil json.null
|
||||
@ -73,25 +75,18 @@ LSP json objects."
|
||||
:end (utils.byte->position file.text (+ byteend 1)
|
||||
server.position-encoding)}))
|
||||
|
||||
(λ code-action-title [diag]
|
||||
(let [titles {:match-should-case "Replace match with case"
|
||||
:unused-definition "Prefix with _ to silence warning"
|
||||
:op-with-no-arguments "Replace with the corresponding literal"
|
||||
:no-decreasing-comparison "Reverse comparison"
|
||||
:unnecessary-tset "Replace with set"
|
||||
:unnecessary-do-values "Remove unnecessary do or values"
|
||||
:redundant-do "Remove redundant do"
|
||||
:bad-unpack "Replace with table.concat call"}]
|
||||
(or (. titles diag.code)
|
||||
(.. "Action title missing - " diag.code))))
|
||||
(λ array [?t]
|
||||
(setmetatable (or ?t []) json-array-mt))
|
||||
|
||||
(λ diagnostic->code-action [_server file diagnostic ?kind]
|
||||
(let [{: uri} file]
|
||||
{:title (code-action-title diagnostic)
|
||||
:kind ?kind
|
||||
:edit {:changes {uri (diagnostic.quickfix)}}}))
|
||||
(λ diagnostic->code-action [_server {: uri} diagnostic ?kind]
|
||||
(case-try diagnostic.fix
|
||||
fix (fix)
|
||||
{: title : changes} {: title
|
||||
:kind ?kind
|
||||
:diagnostics [diagnostic]
|
||||
:edit {:changes {uri (array changes)}}}))
|
||||
|
||||
(λ symbol->signature-help [_server _file _call signature active-parameter]
|
||||
(λ call->signature-help [_server _file _call signature active-parameter]
|
||||
(let [params-count (length signature.parameters)]
|
||||
{:signatures [signature]
|
||||
:activeSignature 0 ; we only ever have one signature
|
||||
@ -101,8 +96,7 @@ LSP json objects."
|
||||
active-parameter)}))
|
||||
|
||||
(λ multisym->range [server file ast n]
|
||||
(let [spl (utils.multi-sym-split ast)
|
||||
n (if (< n 0) (+ n 1 (length spl)) n)]
|
||||
(let [spl (utils.multi-sym-split ast)]
|
||||
(case (values (utils.get-ast-info ast :bytestart)
|
||||
(utils.get-ast-info ast :byteend))
|
||||
(bytestart byteend)
|
||||
@ -138,10 +132,11 @@ LSP json objects."
|
||||
: create-error
|
||||
: ast->range
|
||||
: diagnostic->code-action
|
||||
: symbol->signature-help
|
||||
: call->signature-help
|
||||
: multisym->range
|
||||
: range-and-uri
|
||||
: diagnostics
|
||||
: severity
|
||||
: severity->string
|
||||
: show-message}
|
||||
: show-message
|
||||
: array}
|
||||
|
||||
@ -33,32 +33,47 @@
|
||||
(fn test-fix-op-no-arguments []
|
||||
(check "(let [x (+====)]
|
||||
(print x))"
|
||||
"Replace with the corresponding literal"
|
||||
"Replace (+) with 0"
|
||||
"(let [x 0]
|
||||
(print x))"))
|
||||
(print x))")
|
||||
nil)
|
||||
|
||||
(fn test-fix-unused-definition []
|
||||
(check "(local x==== 10)"
|
||||
"Prefix with _ to silence warning"
|
||||
"(local _x 10)"))
|
||||
"Replace x with _x"
|
||||
"(local _x 10)")
|
||||
nil)
|
||||
|
||||
(fn test-unnecessary-tset []
|
||||
(check "==(tset state :mouse 496)=="
|
||||
"Replace with set"
|
||||
"Replace tset with set"
|
||||
"(set state.mouse 496)")
|
||||
|
||||
(check "==(tset state :mouse :cursor 496)=="
|
||||
"Replace with set"
|
||||
"Replace tset with set"
|
||||
"(set state.mouse.cursor 496)")
|
||||
|
||||
(check "==(tset state :mouse :cursor {:x 4 :y 7})=="
|
||||
"Replace with set"
|
||||
"Replace tset 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)"))
|
||||
"Replace tset with set"
|
||||
"(set state.mouse.cursor.x 496)")
|
||||
nil)
|
||||
|
||||
(fn test-fix-unpack []
|
||||
(check "(.. (table.unpack my-ta====ble))"
|
||||
"Replace with a call to table.concat"
|
||||
"(table.concat my-table)")
|
||||
(check "(.. 1 2 3 (table.unpa====ck my-table))"
|
||||
"Replace with a call to table.concat"
|
||||
"(.. 1 2 3 (table.concat my-table))")
|
||||
(check-negative "(+ 1 2 3 (table.unpa====ck my-table))"
|
||||
"Replace with a call to table.concat")
|
||||
nil)
|
||||
|
||||
{: test-fix-op-no-arguments
|
||||
: test-fix-unused-definition
|
||||
: test-unnecessary-tset}
|
||||
: test-unnecessary-tset
|
||||
: test-fix-unpack}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user