completions no longer suggest invalid fields

This commit is contained in:
XeroOl 2025-07-26 19:10:41 -05:00
parent 251a7789a4
commit 0828820097
5 changed files with 27 additions and 31 deletions

View File

@ -346,15 +346,8 @@ identifiers are declared / referenced in which places."
&into allowed-globals] &into allowed-globals]
extra-global) extra-global)
(fn parse-ast [parser] (let [macro-file? (or (file.uri:match "%.fnlm$")
(icollect [ok ast parser &until (not ok)] ast)) (= (file.text:sub 1 24) ";; fennel-ls: macro-file"))
(fn macro-file? [file]
(or (file.uri:match "%.fnlm$")
(= (file.text:sub 1 24) ";; fennel-ls: macro-file")))
;; TODO clean up this code. It's awful now that there is error handling
(let [macro-file? (macro-file? file)
plugin plugin
{:name "fennel-ls" {:name "fennel-ls"
:versions ["1.4.1" "1.4.2" "1.5.0" "1.5.1" "1.5.3" "1.5.4"] :versions ["1.4.1" "1.4.2" "1.5.0" "1.5.1" "1.5.3" "1.5.4"]
@ -395,7 +388,7 @@ identifiers are declared / referenced in which places."
(fn _p1 [p2 p3] (fn _p1 [p2 p3]
(filter-errors :parser (xpcall #(p p2 p3) fennel.traceback)))) (filter-errors :parser (xpcall #(p p2 p3) fennel.traceback))))
ast (parse-ast parser)] ast (icollect [ok ast parser &until (not ok)] ast)]
(λ traverse [ast] (λ traverse [ast]
"runs on every ast tree that was parsed" "runs on every ast tree that was parsed"

View File

@ -71,18 +71,19 @@ is set to true and we report that we support completionItem/resolve."
(set (. seen definition) true) (set (. seen definition) true)
(add-completion! name definition) (add-completion! name definition)
(each [field def ?string-method (navigate.iter-fields server definition)] (each [field def ?string-method (navigate.iter-fields server definition)]
(if (or (= :self (tostring (?. def :metadata :fnl/arglist 1))) (when (utils.valid-sym-field? field)
?string-method (if (or (= :self (tostring (?. def :metadata :fnl/arglist 1)))
(and (fennel.list? def.definition) ?string-method
(or (fennel.sym? (. def.definition 1) "fn") (and (fennel.list? def.definition)
(fennel.sym? (. def.definition 1) "λ")) (or (fennel.sym? (. def.definition 1) "fn")
(or (and (fennel.table? (. def.definition 2)) (fennel.sym? (. def.definition 1) "λ"))
(fennel.sym? (. def.definition 2 1) "self")) (or (and (fennel.table? (. def.definition 2))
(and (fennel.sym? (. def.definition 2)) (fennel.sym? (. def.definition 2 1) "self"))
(fennel.table? (. def.definition 3)) (and (fennel.sym? (. def.definition 2))
(fennel.sym? (?. def.definition 3 1) "self"))))) (fennel.table? (. def.definition 3))
(add-completion-recursively! (.. name ":" field) def) (fennel.sym? (?. def.definition 3 1) "self")))))
(add-completion-recursively! (.. name "." field) def))) (add-completion-recursively! (.. name ":" field) def)
(add-completion-recursively! (.. name "." field) def))))
(set (. seen definition) false))) (set (. seen definition) false)))
(fn expression-completions [] (fn expression-completions []

View File

@ -34,11 +34,6 @@ You can read more about how to add lints in docs/linting.md"
(table.insert (assert (. lints t) (.. "unknown lint type " t)) lint)) (table.insert (assert (. lints t) (.. "unknown lint type " t)) lint))
(table.insert (assert (. lints lint.type) (.. "unknown lint type " lint.type)) lint))))) (table.insert (assert (. lints lint.type) (.. "unknown lint type " lint.type)) lint)))))
(fn could-be-rewritten-as-sym? [str]
(and (= :string (type str)) (not (str:find "^%d"))
(not (str:find "[^!$%*+/0-9<=>?A-Z\\^_a-z|\128-\255-]"))))
(add-lint :unused-definition (add-lint :unused-definition
{:what-it-does {:what-it-does
"Marks bindings that aren't read. Completely overwriting a value doesn't count "Marks bindings that aren't read. Completely overwriting a value doesn't count
@ -192,7 +187,7 @@ You can read more about how to add lints in docs/linting.md"
method (. ast 3)] method (. ast 3)]
(if (and (sym? (. ast 1) ":") (if (and (sym? (. ast 1) ":")
(sym? object) (sym? object)
(could-be-rewritten-as-sym? method)) (utils.valid-sym-field? method))
{:range (message.ast->range server file ast) {:range (message.ast->range server file ast)
:message (.. "unnecessary : call: use (" (tostring object) ":" method ")") :message (.. "unnecessary : call: use (" (tostring object) ":" method ")")
:severity message.severity.WARN})))}) :severity message.severity.WARN})))})
@ -218,7 +213,7 @@ You can read more about how to add lints in docs/linting.md"
(let [all-rewritable? (faccumulate [syms true (let [all-rewritable? (faccumulate [syms true
i 3 (- (length ast) 1) i 3 (- (length ast) 1)
&until (not syms)] &until (not syms)]
(could-be-rewritten-as-sym? (. ast i)))] (utils.valid-sym-field? (. ast i)))]
(if (and (sym? (. ast 1) "tset") (if (and (sym? (. ast 1) "tset")
(sym? (. ast 2)) (sym? (. ast 2))
all-rewritable?) all-rewritable?)

View File

@ -215,6 +215,10 @@ WARNING: this is only used in the test code, not in the real language server"
suffix)] suffix)]
(.. clean-path clean-suffix)))) (.. clean-path clean-suffix))))
(fn valid-sym-field? [str]
(and (= :string (type str))
(not (str:find "[^!#$%&*+/0-9<=>?A-Z\\^_a-z|\128-\255-]"))))
(fn find [t x ?k] (fn find [t x ?k]
(match (next t ?k) (k x) k (k y_) (find t x k))) (match (next t ?k) (k x) k (k y_) (find t x k)))
@ -235,4 +239,5 @@ WARNING: this is only used in the test code, not in the real language server"
: path-join : path-join
: path-sep : path-sep
: endswith : endswith
: find} : find
: valid-sym-field?}

View File

@ -191,7 +191,9 @@
;; Lint only triggers on keys that can be written as a sym ;; Lint only triggers on keys that can be written as a sym
(check "(local tbl {}) (tset tbl \"hello-world\" 249)" (check "(local tbl {}) (tset tbl \"hello-world\" 249)"
[{:code :unnecessary-tset}]) [{:code :unnecessary-tset}])
(assert-ok "(local tbl {}) (tset tbl \"01234567\" 249)") ;; symbols like tbl.01234567 *are* valid >:)
(check "(local tbl {}) (tset tbl \"01234567\" 249)"
[{:code :unnecessary-tset}])
(assert-ok "(local tbl {}) (tset tbl \"hello world\" 1)") (assert-ok "(local tbl {}) (tset tbl \"hello world\" 1)")
(assert-ok "(local tbl {}) (tset tbl \"0123.4567\" 1)") (assert-ok "(local tbl {}) (tset tbl \"0123.4567\" 1)")
nil) nil)