analyzer can search into macro expansions and functions
shoutouts to rudy for working with me on these changes.
This commit is contained in:
parent
bfc6d64237
commit
ae66e6d002
@ -42,6 +42,7 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
|
|||||||
(local utils (require :fennel-ls.utils))
|
(local utils (require :fennel-ls.utils))
|
||||||
(local files (require :fennel-ls.files))
|
(local files (require :fennel-ls.files))
|
||||||
(local docs (require :fennel-ls.docs))
|
(local docs (require :fennel-ls.docs))
|
||||||
|
(local {: view} (require :fennel))
|
||||||
|
|
||||||
(local get-ast-info utils.get-ast-info)
|
(local get-ast-info utils.get-ast-info)
|
||||||
|
|
||||||
@ -146,11 +147,19 @@ find the definition `10`, but if `opts.stop-early?` is set, it would find
|
|||||||
(where (or :fn :lambda :λ))
|
(where (or :fn :lambda :λ))
|
||||||
(if (and (= multival 1) (= 0 (length stack)))
|
(if (and (= multival 1) (= 0 (length stack)))
|
||||||
{:definition call : file}) ;; BASE CASE !!
|
{:definition call : file}) ;; BASE CASE !!
|
||||||
;; TODO expand-macros
|
|
||||||
|
|
||||||
_
|
_
|
||||||
(if (and (= multival 1) (= 0 (length stack)))
|
(case (. file.macro-calls call)
|
||||||
{:definition call : file}))))) ;; BASE CASE!!
|
macroexpanded (search-multival server file macroexpanded stack multival opts)
|
||||||
|
_ (case (search-val server file (. call 1) [] {})
|
||||||
|
(where {: definition : file}
|
||||||
|
(list? definition)
|
||||||
|
(let [head (. definition 1)]
|
||||||
|
(or (sym? head :fn)
|
||||||
|
(sym? head :lambda)
|
||||||
|
(sym? head :λ))))
|
||||||
|
|
||||||
|
(search-multival server file (. definition (length definition)) stack multival opts)))))))
|
||||||
|
|
||||||
(set search-multival
|
(set search-multival
|
||||||
(λ [server file ?ast stack multival opts]
|
(λ [server file ?ast stack multival opts]
|
||||||
|
|||||||
@ -67,7 +67,8 @@ identifiers are declared / referenced in which places."
|
|||||||
scopes {} ; ast -> scope
|
scopes {} ; ast -> scope
|
||||||
calls {} ; all calls in the macro-expanded code -> true
|
calls {} ; all calls in the macro-expanded code -> true
|
||||||
lexical {} ; all lists, tables, and symbols in the original source
|
lexical {} ; all lists, tables, and symbols in the original source
|
||||||
require-calls {}] ; the keys are all the calls that start with `require
|
require-calls {} ; the keys are all the calls that start with `require
|
||||||
|
macro-calls {}]; ast -> expanded
|
||||||
|
|
||||||
(local defer [])
|
(local defer [])
|
||||||
|
|
||||||
@ -235,8 +236,9 @@ identifiers are declared / referenced in which places."
|
|||||||
(let [len (length ast)]
|
(let [len (length ast)]
|
||||||
(table.insert defer #(tset ast (+ len 1) nil))))))
|
(table.insert defer #(tset ast (+ len 1) nil))))))
|
||||||
|
|
||||||
(fn macroexpand [ast _transformed scope]
|
(fn macroexpand [ast transformed scope]
|
||||||
"every list that is a call to a macro"
|
"every list that is a call to a macro"
|
||||||
|
(tset macro-calls ast transformed)
|
||||||
(let [macro-id (. ast 1)
|
(let [macro-id (. ast 1)
|
||||||
macro-fn (accumulate [t scope.macros
|
macro-fn (accumulate [t scope.macros
|
||||||
_ part (ipairs (utils.multi-sym-split macro-id))]
|
_ part (ipairs (utils.multi-sym-split macro-id))]
|
||||||
@ -423,6 +425,7 @@ identifiers are declared / referenced in which places."
|
|||||||
(set file.references references)
|
(set file.references references)
|
||||||
(set file.require-calls require-calls)
|
(set file.require-calls require-calls)
|
||||||
(set file.allowed-globals allowed-globals)
|
(set file.allowed-globals allowed-globals)
|
||||||
(set file.macro-refs macro-refs))))
|
(set file.macro-refs macro-refs)
|
||||||
|
(set file.macro-calls macro-calls))))
|
||||||
|
|
||||||
{: compile}
|
{: compile}
|
||||||
|
|||||||
@ -205,22 +205,46 @@
|
|||||||
(check "|#$...")
|
(check "|#$...")
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
(fn test-thru-function-return []
|
||||||
|
(check {:button.fnl "(fn new []
|
||||||
|
{:options =={}==})
|
||||||
|
{: new}"
|
||||||
|
:main.fnl "(let [button (require :button)
|
||||||
|
b (button.new)]
|
||||||
|
b.options|"})
|
||||||
|
(check "(fn foo [] (values {} =={}== {}))
|
||||||
|
(local (x y| z) (foo))")
|
||||||
|
(check "(fn foo [] [{} =={}== {}])
|
||||||
|
(local [x y| z] (foo))")
|
||||||
|
nil)
|
||||||
|
(fn test-macro []
|
||||||
|
"Macros are mostly unsupported for now.
|
||||||
|
Fennel-ls can understand the expansion of macros, because it mostly operates
|
||||||
|
on the post-expansion version of the AST."
|
||||||
|
;; Can see the expansion of a macro
|
||||||
|
(check "(macro hello [x y z] y)
|
||||||
|
(local x| (hello {} =={}== {}))")
|
||||||
|
;; ;; Can see the macro itself
|
||||||
|
;; (check "==(macro hello [x y z] y)==
|
||||||
|
;; (local x (hello| {} {} {})")
|
||||||
|
|
||||||
|
nil)
|
||||||
|
|
||||||
; ;; (it "can go to a destructured function argument")
|
; ;; (it "can go to a destructured function argument")
|
||||||
; ;; (it "can go through more than one file")
|
|
||||||
; ;; (it "will give up instead of freezing on recursive requires")
|
; ;; (it "will give up instead of freezing on recursive requires")
|
||||||
; ;; (it "will give up instead of freezing on recursive tables constructed with (set)")
|
; ;; (it "will give up instead of freezing on recursive tables constructed with (set)")
|
||||||
; ;; (it "finds the definition of in-file macros")
|
|
||||||
; ;; (it "can follow import-macros (destructuring)")
|
; ;; (it "can follow import-macros (destructuring)")
|
||||||
; ;; (it "can follow import-macros (namespaced)")
|
; ;; (it "can follow import-macros (namespaced)")
|
||||||
; ;; (it "can go to the definition in a lua file")
|
; ;; (it "can go to the definition in a lua file")
|
||||||
; ;; (it "finds (set a.b) definitions")
|
; ;; (it "finds (set a.b) definitions")
|
||||||
; ;; (it "finds (tset a :b) definitions")
|
; ;; (it "finds (tset a :b) definitions")
|
||||||
; ;; (it "finds (setmetatable a {:__index {:b def}) 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")
|
|
||||||
; ;; (it "finds definitions through a function (fn foo [{: y}] {:x y}) (let [result (foo {:y {}})] (print result.x)) finds result.x")
|
; ;; (it "finds definitions through a function (fn foo [{: y}] {:x y}) (let [result (foo {:y {}})] (print result.x)) finds result.x")
|
||||||
; ;; (it "finds through setmetatable with an :__index function")
|
; ;; (it "finds through setmetatable with an :__index function")
|
||||||
|
|
||||||
{: test-local
|
{: test-local
|
||||||
: test-fields
|
: test-fields
|
||||||
: test-thru-require
|
: test-thru-require
|
||||||
|
: test-thru-function-return
|
||||||
|
: test-macro
|
||||||
: test-no-crash}
|
: test-no-crash}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user