treat lambda and λ as function definitions

This commit is contained in:
XeroOl 2023-06-29 12:23:42 -05:00
parent 2c61b5401a
commit 21bd635123
5 changed files with 28 additions and 4 deletions

View File

@ -58,6 +58,12 @@ Here is my feature wishlist. I don't expect to ever get all of this done, but th
- [ ] `do`/`values` with only one inner form
- [ ] redundant `do` as the last/only item in a form that accepts a "body"
- [ ] `var` forms that could be `local`
- [ ] Arity checking
- [ ] Too many args (assuming there is no ... argument)
- [ ] Too few args (assuming the last argument is statically countable, and also account for ?optional arguments)
- [ ] I need to also make it work for built-in functions
- [ ] warn if an optional arg is present, but no call ever passes the arg
- [ ] Code that matches the shape of `accumulate` or `icollect` or `collect`?? or other macros??
- [ ] Dead code (I'm not sure what sort of things cause dead code)
- [ ] Unused fields (difficult)
- [ ] unification in a `match` pattern (difficult)

View File

@ -12,6 +12,8 @@ later by fennel-ls.language to answer requests from the client."
;; because fennel doesn't allow 'require in a runtime file
(local -require- (sym :require))
(local -fn- (sym :fn))
(local -lambda- (sym :lambda))
(local -λ- (sym :λ))
(λ ast->macro-ast [ast]
[(fennel.list (sym :eval-compiler)
@ -49,7 +51,8 @@ later by fennel-ls.language to answer requests from the client."
diagnostics {} ; [diagnostic]
references {} ; symbol -> references
scopes {} ; ast -> scope
require-calls {}]; ast -> boolean (does this ast start with the symbol `require)
require-calls {} ; ast -> boolean (does this ast start with the symbol `require)
calls {}]; array of all lists
(λ find-definition [name ?scope]
(when ?scope
@ -183,13 +186,14 @@ later by fennel-ls.language to answer requests from the client."
(tset scopes ast scope))
(λ call [ast scope]
(tset calls ast (. ast 1))
(tset scopes ast scope)
;; Most calls aren't interesting, but here's the list of the ones that are:
(case ast
;; This cannot be done through the :fn feature of the compiler plugin system
;; because it needs to be called *before* the body of the function is processed.
;; TODO check if hashfn needs to be here
(where [(= -fn-)])
(where (or [(= -fn-)] [(= -lambda-)] [(= -λ-)] false)) ;; TODO, this false pattern should not ever match, and should be removed once I update fennel
(define-function ast scope)
(where [(= -require-) _modname])
(tset require-calls ast true)
@ -291,6 +295,7 @@ later by fennel-ls.language to answer requests from the client."
; ;; base case???
(set file.ast ast)
(set file.calls calls)
(set file.scope scope)
(set file.scopes scopes)
(set file.definitions definitions)

View File

@ -5,7 +5,6 @@ Every time the client sends a message, it gets handled by a function in the corr
(ie, a textDocument/didChange notification will call notifications.textDocument/didChange
and a textDocument/defintion request will call requests.textDocument/definition)"
(local {: pos->byte : apply-changes} (require :fennel-ls.utils))
(local diagnostics (require :fennel-ls.diagnostics))
(local message (require :fennel-ls.message))
(local state (require :fennel-ls.state))

View File

@ -22,7 +22,7 @@ in the \"self\" object."
file)))
(λ get-by-path [self path]
(get-by-uri (utils.path->uri path)))
(get-by-uri self (utils.path->uri path)))
(λ get-by-module [self module]
;; check the cache

View File

@ -81,6 +81,20 @@
"not found")
_ (error "did not match"))))
; (it "warns about unused functions"
; (let [self (create-client)
; responses (self:open-file! filename "(fn x [])")]
; (match responses
; [{:params {: diagnostics}}]
; (is (find [i v (ipairs diagnostics)]
; (match v
; {:message "unused definition: x"
; :range {:start {:character 7 :line 0}
; :end {:character 8 :line 0}}}
; v))
; "not found")
; _ (error "did not match"))))
(it "does not warn if a field is used"
(let [self (create-client)
responses (self:open-file! filename "(fn [abc] (set abc.xyz 10))")]