add undocumented :compiler-instruction-limit setting
Not sure if I want to keep this, but you can now configure fennel-ls to cap how long it allows the compiler to compile each top level form. It will stay undocumented for now.
This commit is contained in:
parent
ef9cf289c5
commit
251a7789a4
@ -11,6 +11,7 @@ identifiers are declared / referenced in which places."
|
|||||||
(local message (require :fennel-ls.message))
|
(local message (require :fennel-ls.message))
|
||||||
(local searcher (require :fennel-ls.searcher))
|
(local searcher (require :fennel-ls.searcher))
|
||||||
(local utils (require :fennel-ls.utils))
|
(local utils (require :fennel-ls.utils))
|
||||||
|
(local print print)
|
||||||
|
|
||||||
(local nil* (sym :nil))
|
(local nil* (sym :nil))
|
||||||
|
|
||||||
@ -396,7 +397,7 @@ identifiers are declared / referenced in which places."
|
|||||||
|
|
||||||
ast (parse-ast parser)]
|
ast (parse-ast parser)]
|
||||||
|
|
||||||
(λ parsed [ast]
|
(λ traverse [ast]
|
||||||
"runs on every ast tree that was parsed"
|
"runs on every ast tree that was parsed"
|
||||||
(if (sym? ast)
|
(if (sym? ast)
|
||||||
(case (values (tostring ast) (file.text:sub ast.bytestart ast.bytestart))
|
(case (values (tostring ast) (file.text:sub ast.bytestart ast.bytestart))
|
||||||
@ -411,8 +412,8 @@ identifiers are declared / referenced in which places."
|
|||||||
;; recursive call
|
;; recursive call
|
||||||
(when (or (table? ast) (list? ast))
|
(when (or (table? ast) (list? ast))
|
||||||
(each [k v (iter ast)]
|
(each [k v (iter ast)]
|
||||||
(parsed k)
|
(traverse k)
|
||||||
(parsed v)))
|
(traverse v)))
|
||||||
(when (and (list? ast)
|
(when (and (list? ast)
|
||||||
(or (sym? (. ast 1) :λ)
|
(or (sym? (. ast 1) :λ)
|
||||||
(sym? (. ast 1) :lambda)))
|
(sym? (. ast 1) :lambda)))
|
||||||
@ -420,26 +421,38 @@ identifiers are declared / referenced in which places."
|
|||||||
(tset ast 1 (sym :fn))
|
(tset ast 1 (sym :fn))
|
||||||
(table.insert defer #(tset ast 1 old-sym)))))
|
(table.insert defer #(tset ast 1 old-sym)))))
|
||||||
|
|
||||||
(parsed ast)
|
(traverse ast)
|
||||||
|
|
||||||
;; This is bad; we have to mutate fennel.macro-path to use fennel's native macro loader
|
|
||||||
(let [old-macro-path fennel.macro-path
|
|
||||||
print* _G.print]
|
|
||||||
|
|
||||||
|
;; Currently, we mutate fennel.macro-path and use fennel's native macro loader
|
||||||
(when ?root-uri
|
(when ?root-uri
|
||||||
(set fennel.macro-path
|
(let [old-macro-path 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]))
|
||||||
|
(table.insert defer #(set fennel.macro-path old-macro-path))))
|
||||||
|
|
||||||
|
;; Don't allow macros to print things out
|
||||||
|
(set _G.print #(values))
|
||||||
|
(table.insert defer #(set _G.print print))
|
||||||
|
|
||||||
;; don't allow macros to print during compilation
|
|
||||||
(set _G.print #nil)
|
|
||||||
;; compile
|
|
||||||
(each [_i form (ipairs (if macro-file? (ast->macro-ast ast) ast))]
|
(each [_i form (ipairs (if macro-file? (ast->macro-ast ast) ast))]
|
||||||
(filter-errors :compiler (xpcall #(fennel.compile form opts)
|
(filter-errors :compiler
|
||||||
|
;; this entire block of code is for making the instruction limit work
|
||||||
|
(xpcall #(let [limiting? (not= server.configuration.compiler-instruction-limit -1)]
|
||||||
|
(when limiting?
|
||||||
|
(fn hook []
|
||||||
|
(debug.sethook nil nil)
|
||||||
|
(if _G.jit (_G.jit.on))
|
||||||
|
(table.insert diagnostics
|
||||||
|
{:range message.unknown-range
|
||||||
|
:message "instruction limit reached"
|
||||||
|
:severity message.severity.ERROR})
|
||||||
|
(error "__NOT_AN_ERROR"))
|
||||||
|
(if _G.jit (_G.jit.off))
|
||||||
|
(debug.sethook hook "" server.configuration.compiler-instruction-limit))
|
||||||
|
(fennel.compile form opts)
|
||||||
|
(when limiting?
|
||||||
|
(debug.sethook nil nil)
|
||||||
|
(if _G.jit (_G.jit.on))))
|
||||||
fennel.traceback)))
|
fennel.traceback)))
|
||||||
(set _G.print print*)
|
|
||||||
|
|
||||||
(when ?root-uri
|
|
||||||
(set fennel.macro-path old-macro-path)))
|
|
||||||
|
|
||||||
(each [_ cmd (ipairs defer)]
|
(each [_ cmd (ipairs defer)]
|
||||||
(cmd))
|
(cmd))
|
||||||
|
|||||||
@ -34,6 +34,7 @@ to server.configuration. Every other use case should be read-only."
|
|||||||
:lints (collect [_ lint (ipairs lint.list)]
|
:lints (collect [_ lint (ipairs lint.list)]
|
||||||
lint.name (option (not lint.disabled)))
|
lint.name (option (not lint.disabled)))
|
||||||
:libraries (option {} docs.validate-libraries)
|
:libraries (option {} docs.validate-libraries)
|
||||||
|
:compiler-instruction-limit (option -1)
|
||||||
:extra-globals (option "")})
|
:extra-globals (option "")})
|
||||||
|
|
||||||
(fn extend-path [?root extra]
|
(fn extend-path [?root extra]
|
||||||
|
|||||||
@ -63,9 +63,9 @@
|
|||||||
nil)
|
nil)
|
||||||
|
|
||||||
(fn test-config-validation []
|
(fn test-config-validation []
|
||||||
(let [client (create-client {:main.fnl ""
|
(let [{: initialize-response} (create-client {:main.fnl ""
|
||||||
:flsproject.fnl "{:lua-version \"lua5.0\"}"})
|
:flsproject.fnl "{:lua-version \"lua5.0\"}"})
|
||||||
[_init show] client.initialize-response]
|
[_init show] initialize-response]
|
||||||
(faith.= "window/showMessage" show.method)
|
(faith.= "window/showMessage" show.method)
|
||||||
(faith.match "doesn't know about lua version lua5.0" show.params.message))
|
(faith.match "doesn't know about lua version lua5.0" show.params.message))
|
||||||
(let [{: initialize-response : client} (create-client {:main.fnl ""
|
(let [{: initialize-response : client} (create-client {:main.fnl ""
|
||||||
@ -81,8 +81,22 @@
|
|||||||
(faith.match "Could not find docset for library nasilemak" (. diagnostics.params.diagnostics 1 :message))))
|
(faith.match "Could not find docset for library nasilemak" (. diagnostics.params.diagnostics 1 :message))))
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
(fn test-infinite-macro []
|
||||||
|
(when (not debug.debug)
|
||||||
|
(faith.skip))
|
||||||
|
(let [{: diagnostics} (create-client {:main.fnl "(macro infinite [] (while true nil))\n(infinite)\n"
|
||||||
|
:flsproject.fnl "{:compiler-instruction-limit 25000}"})]
|
||||||
|
(faith.= "instruction limit reached"
|
||||||
|
(?. diagnostics 1 :message)))
|
||||||
|
(let [{: diagnostics} (create-client {:main.fnl "(macro finite [] (while false nil))\n(finite)\n"
|
||||||
|
:flsproject.fnl "{:compiler-instruction-limit 25000}"})]
|
||||||
|
(faith.= [] diagnostics))
|
||||||
|
nil)
|
||||||
|
|
||||||
|
|
||||||
{: test-path
|
{: test-path
|
||||||
: test-extra-globals
|
: test-extra-globals
|
||||||
: test-lints
|
: test-lints
|
||||||
: test-config-validation
|
: test-config-validation
|
||||||
: test-editing-settings}
|
: test-editing-settings
|
||||||
|
: test-infinite-macro}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user