Support &as, and ignore &
This commit is contained in:
parent
fe257c061a
commit
ee449df166
@ -3,7 +3,7 @@ This file is responsible for the low level tasks of analysis. Its main job
|
|||||||
is to recieve a file object and run all of the basic analysis that will be used
|
is to recieve a file object and run all of the basic analysis that will be used
|
||||||
later by fennel-ls.language to answer requests from the client."
|
later by fennel-ls.language to answer requests from the client."
|
||||||
|
|
||||||
(local {: sym? : list? : sequence? : sym : view &as fennel} (require :fennel))
|
(local {: sym? : list? : sequence? : table? : sym : view &as fennel} (require :fennel))
|
||||||
(local message (require :fennel-ls.message))
|
(local message (require :fennel-ls.message))
|
||||||
(local utils (require :fennel-ls.utils))
|
(local utils (require :fennel-ls.utils))
|
||||||
(local searcher (require :fennel-ls.searcher))
|
(local searcher (require :fennel-ls.searcher))
|
||||||
@ -82,30 +82,6 @@ later by fennel-ls.language to answer requests from the client."
|
|||||||
(if ?reference?
|
(if ?reference?
|
||||||
(reference ast scope)))
|
(reference ast scope)))
|
||||||
|
|
||||||
(λ mutate [?definition binding scope]
|
|
||||||
;; for now, mutating a field counts as a reference I guess
|
|
||||||
(λ recurse [binding keys]
|
|
||||||
(if (sym? binding)
|
|
||||||
(let [
|
|
||||||
;; ;; future work may need to care about mutations
|
|
||||||
;; _mutation
|
|
||||||
;; {: binding
|
|
||||||
;; :new-definition ?definition
|
|
||||||
;; :keys (if (< 0 (length keys))
|
|
||||||
;; (fcollect [i 1 (length keys)]
|
|
||||||
;; (. keys i)))}
|
|
||||||
name (string.match (tostring binding) "[^%.:]+")]
|
|
||||||
(when (multisym? binding)
|
|
||||||
(case (find-definition (tostring name) scope)
|
|
||||||
target
|
|
||||||
(table.insert target.referenced-by binding))))
|
|
||||||
(= :table (type binding))
|
|
||||||
(each [k v (iter binding)]
|
|
||||||
(table.insert keys k)
|
|
||||||
(recurse v keys)
|
|
||||||
(table.remove keys))))
|
|
||||||
(recurse binding []))
|
|
||||||
|
|
||||||
(λ define [?definition binding scope]
|
(λ define [?definition binding scope]
|
||||||
;; Add a definition to the definitions
|
;; Add a definition to the definitions
|
||||||
;; recursively explore the binding (which, in the general case, is a destructuring assignment)
|
;; recursively explore the binding (which, in the general case, is a destructuring assignment)
|
||||||
@ -129,6 +105,39 @@ later by fennel-ls.language to answer requests from the client."
|
|||||||
(for [i 1 (length binding)]
|
(for [i 1 (length binding)]
|
||||||
(define (. ?definition (+ i 1)) (. binding i) scope))
|
(define (. ?definition (+ i 1)) (. binding i) scope))
|
||||||
(recurse (. binding 1) keys))
|
(recurse (. binding 1) keys))
|
||||||
|
(table? binding)
|
||||||
|
(accumulate [prev nil
|
||||||
|
k v (iter binding)]
|
||||||
|
(if (or (sym? k :&as) (sym? prev :&as))
|
||||||
|
(recurse v)
|
||||||
|
(or (sym? k :&) (sym? prev :&))
|
||||||
|
;; currently the "rest" isn't counted as a binding
|
||||||
|
nil
|
||||||
|
(or (sym? v :&as) (sym? v :&))
|
||||||
|
v
|
||||||
|
(do
|
||||||
|
(table.insert keys k)
|
||||||
|
(recurse v keys)
|
||||||
|
(table.remove keys))))))
|
||||||
|
(recurse binding []))
|
||||||
|
|
||||||
|
(λ mutate [?definition binding scope]
|
||||||
|
;; for now, mutating a field counts as a reference I guess
|
||||||
|
(λ recurse [binding keys]
|
||||||
|
(if (sym? binding)
|
||||||
|
(let [
|
||||||
|
;; ;; future work may need to care about mutations
|
||||||
|
;; _mutation
|
||||||
|
;; {: binding
|
||||||
|
;; :new-definition ?definition
|
||||||
|
;; :keys (if (< 0 (length keys))
|
||||||
|
;; (fcollect [i 1 (length keys)]
|
||||||
|
;; (. keys i)))}
|
||||||
|
name (string.match (tostring binding) "[^%.:]+")]
|
||||||
|
(when (multisym? binding)
|
||||||
|
(case (find-definition (tostring name) scope)
|
||||||
|
target
|
||||||
|
(table.insert target.referenced-by binding))))
|
||||||
(= :table (type binding))
|
(= :table (type binding))
|
||||||
(each [k v (iter binding)]
|
(each [k v (iter binding)]
|
||||||
(table.insert keys k)
|
(table.insert keys k)
|
||||||
@ -279,6 +288,7 @@ later by fennel-ls.language to answer requests from the client."
|
|||||||
: scope}
|
: scope}
|
||||||
|
|
||||||
parser (let [p (fennel.parser file.text file.uri opts)]
|
parser (let [p (fennel.parser file.text file.uri opts)]
|
||||||
|
;; TODO factor this garbage out into a function
|
||||||
(fn p1 [p2 p3]
|
(fn p1 [p2 p3]
|
||||||
(case (xpcall #(p p2 p3) fennel.traceback)
|
(case (xpcall #(p p2 p3) fennel.traceback)
|
||||||
(true r1 r2) (values r1 r2)
|
(true r1 r2) (values r1 r2)
|
||||||
|
|||||||
@ -24,20 +24,20 @@
|
|||||||
|
|
||||||
(describe "capabilities negotiations"
|
(describe "capabilities negotiations"
|
||||||
|
|
||||||
; (it "chooses utf-16"
|
(it "chooses utf-16"
|
||||||
; (let [(self [response])
|
(let [(self [response])
|
||||||
; (create-client
|
(create-client
|
||||||
; {:params
|
{:params
|
||||||
; (client-initialization
|
(client-initialization
|
||||||
; {:capabilities
|
{:capabilities
|
||||||
; {:general
|
{:general
|
||||||
; {:positionEncodings
|
{:positionEncodings
|
||||||
; [:utf-16]}}})})]
|
[:utf-16]}}})})]
|
||||||
; (is.equal :utf-16 (. response :result :positionEncoding))
|
(is.equal :utf-16 (. response :result :positionEncoding))
|
||||||
; (self:open-file! "foo.fnl" "(let [𐐀𐐀 100] 𐐀𐐀)")
|
(self:open-file! "foo.fnl" "(let [𐐀𐐀 100] 𐐀𐐀)")
|
||||||
; (let [[response] (self:definition "foo.fnl" 0 16)]
|
(let [[response] (self:definition "foo.fnl" 0 16)]
|
||||||
; (is.equal 6 response.result.range.start.character)
|
(is.equal 6 response.result.range.start.character)
|
||||||
; (is.equal 10 response.result.range.end.character))))
|
(is.equal 10 response.result.range.end.character))))
|
||||||
|
|
||||||
(it "chooses utf-8 if at all possible"
|
(it "chooses utf-8 if at all possible"
|
||||||
(let [(self [response])
|
(let [(self [response])
|
||||||
|
|||||||
@ -112,6 +112,18 @@
|
|||||||
:end {:character 6 :line 0}}}
|
:end {:character 6 :line 0}}}
|
||||||
v))
|
v))
|
||||||
"not found")
|
"not found")
|
||||||
|
_ (error "did not match"))))
|
||||||
|
|
||||||
|
(it "does not warn in this particular code"
|
||||||
|
(let [self (create-client)
|
||||||
|
responses (self:open-file! filename "(let [[x & y] [1 2 3]] (print x (. y 1) (. y 2)))")]
|
||||||
|
(match responses
|
||||||
|
[{:params {: diagnostics}}]
|
||||||
|
(is.nil (find [i v (ipairs diagnostics)]
|
||||||
|
(match v
|
||||||
|
{:message "unused definition: &"}
|
||||||
|
v))
|
||||||
|
"not found")
|
||||||
_ (error "did not match")))))
|
_ (error "did not match")))))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user