goto-definition with injected fields (fn a.b [])

This commit is contained in:
XeroOl 2022-09-03 12:52:34 -05:00
parent b2540e53cb
commit 0d8b927929
No known key found for this signature in database
GPG Key ID: 9DD4B4B4DAED0322
5 changed files with 35 additions and 16 deletions

View File

@ -24,7 +24,7 @@ Features / To Do List / Things I would enjoy patches for:
- [X] `require` and cross-module definition lookups
- [ ] goes to a.method on `(: a :method)` when triggered at `:method`
- [X] expanded macros (a little bit)
- [ ] table mutation via `fn` special: `(fn obj.new-field [])`
- [X] table mutation via `fn` special: `(fn obj.new-field [])`
- [ ] macro calls / which macros are in scope
- [ ] setmetatable
- [ ] function arguments / function calls
@ -36,7 +36,7 @@ Features / To Do List / Things I would enjoy patches for:
- [X] from current scope
- [ ] from macros (only on first form in a list)
- [ ] from specials (only on first form in a list)
- [ ] "dot completion" for table fields
- [X] "dot completion" for table fields
- [ ] dot completion is aware of a string's fields
- [ ] from anywhere else that I'm forgetting right now
- [ ] actually compliant rules about lexical scope (only see things declared before, not after)

View File

@ -5,6 +5,7 @@ later by fennel-ls.language to answer requests from the client."
(local {: sym? : list? : sequence? : sym : view &as fennel} (require :fennel))
(local message (require :fennel-ls.message))
(local utils (require :fennel-ls.utils))
;; words surrounded by - are symbols,
;; because fennel doesn't allow 'require in a runtime file
@ -85,12 +86,18 @@ later by fennel-ls.language to answer requests from the client."
(match ast
(where [_fn name args]
(and (sym? name)
(not (multisym? name)) ;; not dealing with multisym for now
(sequence? args)))
(tset (. definitions-by-scope scope) ;; !!! TODO somehow insert into child scope
(tostring name)
{:binding name
:definition ast})))
(let [def {:binding name :definition ast}]
(if (multisym? name)
(match (utils.multi-sym-split name)
[ref field nil]
(let [target (find-definition ref scope)]
(set target.fields (or target.fields {}))
(tset target.fields field def))) ;; TODO more complicated function name metadata
(tset (. definitions-by-scope scope)
(tostring name)
def)))))
(λ define-function-args [ast scope]
;; add the definitions of function arguments to the definitions

View File

@ -19,14 +19,21 @@ the data provided by compiler.fnl."
(var search nil) ;; all of the search functions are mutually recursive
(λ search-assignment [self file assignment stack opts]
(let [{: binding :definition ?definition :keys ?keys} assignment]
(let [{: binding
:definition ?definition
:keys ?keys
:fields ?fields} assignment]
(if (and (= 0 (length stack)) opts.stop-early?)
(values assignment file) ;; BASE CASE!!
(do
(if ?keys
(fcollect [i (length ?keys) 1 -1 &into stack]
(. ?keys i)))
(search self file ?definition stack opts)))))
(values assignment file) ;; BASE CASE!!
(and (not= 0 (length stack)) (?. ?fields (. stack (length stack))))
(search-assignment self file (. ?fields (table.remove stack)) stack opts)
(do
(if ?keys
(fcollect [i (length ?keys) 1 -1 &into stack]
(. ?keys i)))
(search self file ?definition stack opts)))))
(λ search-symbol [self file symbol stack opts]
(if (= symbol -nil-)

View File

@ -70,7 +70,7 @@
(check :goto-definition.fnl 1 5 :bar.fnl 0 0 0 2))
(it "goes to the last form of `do` and `let`"
(check :goto-definition.fnl 47 13 :goto-definition.fnl 47 30 47 52)))
(check :goto-definition.fnl 47 13 :goto-definition.fnl 47 30 47 52))
;; TODO
;; (it "doesn't leak function arguments to the surrounding scope")
@ -82,7 +82,8 @@
;; (it "can follow import-macros (namespaced)")
;; (it "can go to the definition even in a lua file")
;; (it "finds (set a.b) definitions")
;; (it "finds (fn a.b [] ...) declarations")
(it "finds (fn a.b [] ...) declarations"
(check :goto-definition.fnl 51 12 :goto-definition.fnl 50 4 50 22)))
;; (it "finds (tset a :b) definitions")
;; (it "finds (setmetatable a {__index {:b def}) definitions")
;; (it "finds definitions into a function (fn foo [] (local x 10) {: x}) (let [result (foo)] (print result.x)) finds result.x")

View File

@ -46,3 +46,7 @@
(print funny.field)
(local object (do (let [a 10] {:my-definition :here})))
(local module {})
(fn module.my-function [a b c] "docstring" (let [body (+ a b c)] body))
(module.my-function 1 2 3)