diff --git a/src/fennel-ls/compiler.fnl b/src/fennel-ls/compiler.fnl index 4a51ea2..eaf3739 100644 --- a/src/fennel-ls/compiler.fnl +++ b/src/fennel-ls/compiler.fnl @@ -21,15 +21,6 @@ identifiers are declared / referenced in which places." (= (type candidate.specials) :table) (= (type candidate.gensyms) :table))) -;; words surrounded by - are symbols, -;; because fennel doesn't allow 'require in a runtime file -(local -require- (sym :require)) -(local -include- (sym :include)) -(local -fn- (sym :fn)) -(local -if- (sym :if)) -(local -lambda- (sym :lambda)) -(local -λ- (sym :λ)) - (λ ast->macro-ast [ast] [(fennel.list (sym :eval-compiler) ((or table.unpack _G.unpack) ast))]) @@ -220,22 +211,24 @@ identifiers are declared / referenced in which places." (tset calls ast true) (tset scopes ast scope) ;; Most calls aren't interesting, but here's the list of the ones that are: - (case ast + (case (and (sym? (. ast 1)) (tostring (. ast 1))) ;; 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 (or [(= -fn-)] [(= -lambda-)] [(= -λ-)])) + (where (or :fn :lambda :λ)) (define-function ast scope) - (where (or [(= -require-) _modname] - [(= -include-) _modname])) + (where (or :require :include)) (tset require-calls ast true) ;; fennel expands multisym calls into the `:` special, so we need to reference the symbol while we still can - (where [sym] (multisym? sym) (: (tostring sym) :find ":")) - (reference sym scope :read) + (where method-call (= (type method-call) :string) (method-call:find ":")) + (reference (. ast 1) scope :read) ;; NOTE HACK TODO this should be removed once fennel makes if statements work like normal - (where [(= -if-)]) + (where :if) (let [len (length ast)] - (table.insert defer #(tset ast (+ len 1) nil))))) + (table.insert defer #(tset ast (+ len 1) nil))) + (where :hashfn) + (let [head (. ast 1)] + (table.insert defer #(set head.byteend head.bytestart))))) (λ attempt-to-recover! [msg ?ast] (or (= 1 (msg:find "unknown identifier")) diff --git a/test/hover.fnl b/test/hover.fnl index 0ffdc49..c0a95a7 100644 --- a/test/hover.fnl +++ b/test/hover.fnl @@ -132,6 +132,21 @@ new message handler `msgh`.") (check "(let [(x y z a) (do (do (values 1 (do (values (values 2 4) (do 3))))))]\n (print x y z a|))" nil) nil) +(fn test-macro [] + (check "(macro bind [a b c] + \"docstring!\" + `(let [,a ,b] ,c)) + (bind x print |x)" + #($:find "```fnl\n(print ...)\n```" 1 true)) + ; (check "(macro foo [a b c] + ; \"docstring!\" + ; `(,a ,b ,c)) + ; (fo|o print :hello :world)" + ; "```fnl\n(macro foo [a b c] ...)\n```\ndocstring!") + (check "#(prin|t :hello)" + #($:find "```fnl\n(print ...)\n```" 1 true)) + nil) + {: test-literals : test-builtins : test-globals @@ -139,4 +154,5 @@ new message handler `msgh`.") : test-functions : test-multisym : test-crash - : test-multival} + : test-multival + : test-macro} diff --git a/test/lint.fnl b/test/lint.fnl index 43a7cb2..9c64cf6 100644 --- a/test/lint.fnl +++ b/test/lint.fnl @@ -93,7 +93,8 @@ (check "table.insert2 table.insert" [{:code 302 :message "unknown field: table.insert2"}] [{:code 302 :message "unknown field: table.insert"}]) - ;; if you explicitly write "_G", it should turn off this test. Hardcoded. + ;; if you explicitly write "_G", it should turn off this test. + ;; Hardcoded at the top of language.fnl/search-document. (check "_G.insert2" [] [{:code 302}])