refactor compiler.fnl
This commit is contained in:
parent
4b8172ac05
commit
3c2bc8c35c
16
TODO.md
16
TODO.md
@ -2,8 +2,20 @@
|
||||
([X] = complete, [ ] = planned)
|
||||
|
||||
My current goal is to work on completions a little bit more.
|
||||
- [ ] create a release
|
||||
|
||||
- [ ] Fix crash-files.test2
|
||||
refactor brainstorm:
|
||||
- [ ] get rid of `bytes` stuff and use "stack" everywhere
|
||||
- [ ] search caching
|
||||
- [ ] search depth limit / stop recursion
|
||||
- [ ] search into calls
|
||||
|
||||
- [ ] entry point measurement for reference search
|
||||
|
||||
- [ ] arg return count
|
||||
- [ ] i guess searching into calls could do this?
|
||||
|
||||
- [ ] diagnostic code actions
|
||||
|
||||
Here is my feature wishlist. I don't expect to ever get all of this done, but these are the sort of enhancements I am thinking about.
|
||||
- [X] Able to connect to a client
|
||||
@ -36,7 +48,7 @@ Here is my feature wishlist. I don't expect to ever get all of this done, but th
|
||||
- [X] from macros (only on first form in a list)
|
||||
- [X] from specials (only on first form in a list)
|
||||
- [X] "dot completion" for table fields
|
||||
- [ ] dot completion is aware of a stdlib
|
||||
- [1/2] dot completion is aware of a stdlib
|
||||
- [ ] actually compliant rules about lexical scope (only see things declared before, not after)
|
||||
- [x] show docs/icons on each suggestion
|
||||
- [ ] "dot completion" for metatable `__index` fields
|
||||
|
||||
@ -261,7 +261,11 @@ later by fennel-ls.language to answer requests from the client."
|
||||
(local allowed-globals
|
||||
(icollect [k _ (pairs _G)]
|
||||
k))
|
||||
|
||||
;; just a couple of globals that are probably not errors
|
||||
;; TODO make this configurable in a better way
|
||||
(table.insert allowed-globals :vim)
|
||||
(table.insert allowed-globals :love)
|
||||
|
||||
;; TODO clean up this code. It's awful now that there is error handling
|
||||
(let [macro-file? (= (: file.text :sub 1 24) ";; fennel-ls: macro-file")
|
||||
@ -286,47 +290,35 @@ later by fennel-ls.language to answer requests from the client."
|
||||
:allowedGlobals allowed-globals
|
||||
:requireAsInclude false
|
||||
: scope}
|
||||
filter-errors (fn _filter-errors [component ...]
|
||||
(case ...
|
||||
(true ?item1 ?item2) (values ?item1 ?item2)
|
||||
(where (or (nil err) (false err)) (not (err:find "^[^\n]-__NOT_AN_ERROR\n")))
|
||||
(if (os.getenv :TESTING)
|
||||
(error (.. "\nYou have crashed fennel-ls (or the fennel " component ") with the following message\n:" err
|
||||
"\n\n^^^ the error message above here is the root problem\n\n"))
|
||||
(table.insert diagnostics
|
||||
{:range (line+byte->range self file 1 1)
|
||||
:message (.. "unrecoverable " component " error: " err)}))))
|
||||
|
||||
parser (let [p (fennel.parser file.text file.uri opts)]
|
||||
;; TODO factor this garbage out into a function
|
||||
(fn p1 [p2 p3]
|
||||
(case (xpcall #(p p2 p3) fennel.traceback)
|
||||
(true r1 r2) (values r1 r2)
|
||||
(where (or (nil err) (false err)) (not (err:find "^[^\n]-__NOT_AN_ERROR\n")))
|
||||
(if (os.getenv :TESTING)
|
||||
(error (.. "\nYou have crashed the fennel parser or fennel-ls with the following message\n:" err
|
||||
"\n\n^^^ the error message above here is the root problem\n\n"))
|
||||
(table.insert diagnostics
|
||||
{:range (line+byte->range self file 1 1)
|
||||
:message (.. "unrecoverable compiler error: " err)})))))
|
||||
(fn _p1 [p2 p3]
|
||||
(filter-errors :parser (xpcall #(p p2 p3) fennel.traceback))))
|
||||
|
||||
ast (icollect [ok ast parser &until (not ok)] ast)]
|
||||
|
||||
|
||||
;; This is bad; we mutate fennel.macro-path
|
||||
(let [old-macro-path fennel.macro-path]
|
||||
(set fennel.macro-path (searcher.add-workspaces-to-path macro-path [root-uri]))
|
||||
(set fennel.macro-path
|
||||
(searcher.add-workspaces-to-path macro-path [root-uri]))
|
||||
|
||||
;; compile
|
||||
(each [_i form (ipairs (if macro-file? (ast->macro-ast ast) ast))]
|
||||
(case (xpcall #(fennel.compile form opts) fennel.traceback)
|
||||
(where (or (nil err) (false err)) (not (err:find "^[^\n]-__NOT_AN_ERROR\n")))
|
||||
(if (os.getenv :TESTING)
|
||||
(error (.. "\nYou have crashed the fennel compiler or fennel-ls with the following message\n:" err
|
||||
"\n\n^^^ the error message above here is the root problem\n\n"))
|
||||
(table.insert diagnostics
|
||||
{:range (line+byte->range self file 1 1)
|
||||
:message (.. "unrecoverable compiler error: " err)}))))
|
||||
(filter-errors :compiler (xpcall #(fennel.compile form opts) fennel.traceback)))
|
||||
|
||||
(set fennel.macro-path old-macro-path))
|
||||
|
||||
; (each [sym target (pairs references)]
|
||||
; (if
|
||||
; (sym? target)
|
||||
; (list? target)
|
||||
; (= :table (type target))))
|
||||
; ;; base case???
|
||||
|
||||
(set file.ast ast)
|
||||
(set file.calls calls)
|
||||
(set file.scope scope)
|
||||
|
||||
@ -115,7 +115,6 @@ However, fennel-ls can fall back to positionEncoding=utf-16 (with a performance
|
||||
:utf-8
|
||||
:utf-16)))
|
||||
|
||||
|
||||
(λ init-state [self params]
|
||||
(set self.files {})
|
||||
(set self.modules {})
|
||||
|
||||
@ -156,26 +156,49 @@
|
||||
{:label :-?>
|
||||
:kind (= kinds.Keyword)
|
||||
:documentation documentation}
|
||||
(not= documentation :nil)))))))
|
||||
(not= documentation :nil)))))
|
||||
|
||||
; (it "offers rich information about everything"
|
||||
(it "offers rich information about all builtin/globals"
|
||||
(let [client (doto (create-client)
|
||||
(: :open-file! filename "("))
|
||||
[{:result completions}] (client:completion filename 0 1)
|
||||
_ (table.sort completions #(< $1.label $2.label))
|
||||
missing-docs (icollect [_ completion (ipairs completions)]
|
||||
(if (not (and (= (type completion.label) :string)
|
||||
(= (type completion.kind) :number)
|
||||
(= (type completion.documentation) :table)))
|
||||
completion.label))
|
||||
allowed-missing-docs {:lua true
|
||||
:set-forcibly! true
|
||||
;; TODO remove these from fennel-ls when they become configurable
|
||||
:love true
|
||||
:vim true}]
|
||||
(each [_ completion (ipairs completions)]
|
||||
(when (not (. allowed-missing-docs completion.label))
|
||||
(is.same (type completion.label) :string "unlabeled completion")
|
||||
(is.same (type completion.kind) :number (.. completion.label " needs a kind"))
|
||||
(is.same (type completion.documentation) :table (.. completion.label " needs documentation"))
|
||||
(is.not.same completion.documentation :nil (.. completion.label " needs documentation"))))))))
|
||||
|
||||
; (it "offers rich information about fields"
|
||||
; (let [client (doto (create-client)
|
||||
; (: :open-file! filename "("))
|
||||
; [{:result completions}] (client:completion filename 0 1)
|
||||
; (: :open-file! filename "(let [x (fn x [a b c] \"\"\"docstring\"\"\" nil)\n t {: x}]\n (t."))
|
||||
; [{:result completions}] (client:completion filename 2 5)
|
||||
; _ (table.sort completions #(< $1.label $2.label))
|
||||
; count (accumulate [sum 0 _ completion (ipairs completions)]
|
||||
; (if (and (= (type completion.label) :string)
|
||||
; (= (type completion.kind) :number)
|
||||
; (= (type completion.documentation) :table))
|
||||
; (+ sum 1)
|
||||
; sum))]
|
||||
; (if (< count (length completions))
|
||||
; (print "!!!" (- (length completions) count) "items are missing a label or kind or doc"))
|
||||
; missing-docs (icollect [_ completion (ipairs completions)]
|
||||
; (if (not (and (= (type completion.label) :string)
|
||||
; (= (type completion.kind) :number)
|
||||
; (= (type completion.documentation) :table)))
|
||||
; completion.label))
|
||||
; allowed-missing-docs {}]
|
||||
; (each [_ completion (ipairs completions)]
|
||||
; (is.same (type completion.label) :string "unlabeled completion")
|
||||
; (is.same (type completion.kind) :number (.. completion.label " needs a kind"))
|
||||
; (is.same (type completion.documentation) :table (.. completion.label " needs documentation"))
|
||||
; (is.not.same completion.documentation :nil (.. completion.label " needs documentation")))))))
|
||||
; (when (not (. allowed-missing-docs completion.label))
|
||||
; (is.same (type completion.label) :string "unlabeled completion")
|
||||
; (is.same (type completion.kind) :number (.. completion.label " needs a kind"))
|
||||
; (is.same (type completion.documentation) :table (.. completion.label " needs documentation"))
|
||||
; (is.not.same completion.documentation :nil (.. completion.label " needs documentation"))))))))
|
||||
|
||||
|
||||
|
||||
|
||||
;; (it "offers rich information about variable completions")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user