Clean up love2d parser and restructure code
This commit is contained in:
parent
3816bd81cc
commit
e1d3b7b257
@ -5,21 +5,18 @@
|
||||
(local require-love-api
|
||||
(partial require (.. love-api-build-directory :/love_api)))
|
||||
|
||||
(local stringify-table fennel.view)
|
||||
|
||||
;
|
||||
; UTILS
|
||||
; -----
|
||||
(fn merge [...]
|
||||
(let [arg-count (select "#" ...)
|
||||
args [...]]
|
||||
(if (= arg-count 0)
|
||||
{}
|
||||
(faccumulate [result {} i 1 arg-count]
|
||||
(collect [k v (pairs (. args i)) &into result]
|
||||
(if (?. result k)
|
||||
(values k (merge v (. result k)))
|
||||
(values k v)))))))
|
||||
(fn build-lsp-value [name ?args ?docstring ?fields]
|
||||
"Takes ... and returns a table to be used with the LSP."
|
||||
(let [lsp-value {:binding name}
|
||||
?metadata (or ?args ?docstring)]
|
||||
(when ?metadata (set lsp-value.metadata {}))
|
||||
(when ?args (set lsp-value.metadata.fnl/arglist ?args))
|
||||
(when ?docstring (set lsp-value.metadata.fnl/docstring ?docstring))
|
||||
(when ?fields (set lsp-value.fields ?fields))
|
||||
lsp-value))
|
||||
|
||||
(fn download-love-api-tooling! []
|
||||
"Clones the LÖVE-API git repository that contains tooling to scrape and
|
||||
@ -28,62 +25,86 @@
|
||||
(git-clone love-api-build-directory
|
||||
"https://github.com/love2d-community/love-api")))
|
||||
|
||||
(fn build-lsp-value [name ?args ?docstring]
|
||||
"Takes ... and returns a table to be used with the LSP."
|
||||
(let [lsp-value {:binding name :metadata {}}]
|
||||
(when ?args (set lsp-value.metadata.fnl/arglist ?args))
|
||||
(when ?docstring (set lsp-value.metadata.fnl/docstring ?docstring))
|
||||
lsp-value))
|
||||
(fn merge [...]
|
||||
(let [arg-count (select "#" ...)
|
||||
args [...]]
|
||||
(if (= arg-count 0)
|
||||
{}
|
||||
(faccumulate [result {} i 1 arg-count]
|
||||
(collect [k v (pairs (. args i)) &into result]
|
||||
(values k v))))))
|
||||
|
||||
;
|
||||
; PARSERS
|
||||
; -------
|
||||
(fn fn-arguments->names [arguments]
|
||||
(fn variant-arguments->names [arguments]
|
||||
"Given an array of arguments, return all names as an array."
|
||||
(icollect [_i {:description _ : name :type _} (ipairs arguments)]
|
||||
name))
|
||||
|
||||
(fn fn-return->string [returns]
|
||||
"Given an array of arguments, return a formatted description."
|
||||
(fn variant-return->string [returns]
|
||||
"Given an array of return values, return a formatted description."
|
||||
(accumulate [x "\n\nReturns -" _i {: description : name :type return-type} (ipairs returns)]
|
||||
(.. x "\n" " * " name " (`" return-type "`) - " description)))
|
||||
|
||||
(fn parse-fn-variant [variant]
|
||||
"Given an array of fuction variants, return an object where the first variant
|
||||
is made the formatted LSP option, with any remaining variants being formatted
|
||||
as a single description."
|
||||
(fn parse-first-function-variant [[variant]]
|
||||
"Given an array of fuction variants, format and return the first variant
|
||||
for the LSP."
|
||||
(collect [v-key v-value (pairs variant)]
|
||||
(case v-key
|
||||
:returns (values :returns v-value)
|
||||
:arguments (values :args (fn-arguments->names v-value)))))
|
||||
:returns (values :returns (variant-return->string v-value))
|
||||
:arguments (values :args (variant-arguments->names v-value)))))
|
||||
|
||||
(fn parse-doc-module-tbl [docs-tbl]
|
||||
"Takes a LÖVE-API documentation table and generates a list of each
|
||||
key with values suitable for the Fennel LSP."
|
||||
{:fields (collect [_i value (ipairs docs-tbl)]
|
||||
(let [{: name : description} value
|
||||
?variants (?. value :variants)
|
||||
first-variant (if ?variants
|
||||
(parse-fn-variant (. ?variants 1))
|
||||
nil)
|
||||
?args (?. first-variant :args)
|
||||
?returns (?. first-variant :returns)
|
||||
docstring (.. description
|
||||
(if ?returns (fn-return->string ?returns) ""))]
|
||||
(values name (build-lsp-value name ?args docstring))))})
|
||||
(fn love-functions->lsp [docs-tbl prefix]
|
||||
"Given an array of documented functions for a LÖVE module, generate a table
|
||||
for the Fennel LSP."
|
||||
(collect [_i value (ipairs docs-tbl)]
|
||||
(let [{: name : description} value
|
||||
binding (.. prefix name)
|
||||
?variants (?. value :variants)
|
||||
first-variant (if ?variants
|
||||
(parse-first-function-variant ?variants)
|
||||
nil)
|
||||
?args (?. first-variant :args)
|
||||
?returns (or (?. first-variant :returns) "")
|
||||
docstring (.. description ?returns)]
|
||||
(values name (build-lsp-value binding ?args docstring)))))
|
||||
|
||||
(fn love-api->root-lsp-tbl [love-api]
|
||||
(let [love-doc-string (.. "LÖVE is a framework for making "
|
||||
"2D games in the Lua programming language.")
|
||||
love-docs (build-lsp-value :love nil love-doc-string)
|
||||
love-functions (parse-doc-module-tbl love-api.functions)
|
||||
love-callbacks (parse-doc-module-tbl love-api.callbacks)]
|
||||
{:love (merge love-docs love-functions love-callbacks)}))
|
||||
(fn module-list->fields [modules ?prefix]
|
||||
"Given a list of LÖVE modules from the LÖVE-API Lua library, recursively
|
||||
generate LSP data for Fennel."
|
||||
(collect [_i module (ipairs modules)]
|
||||
(let [{: name} module ; Other keys - :enum, :functions, :types
|
||||
prefix (if ?prefix (.. ?prefix ".") "")
|
||||
binding (.. prefix name)
|
||||
?docstring (?. module :description)
|
||||
?functions (?. module :functions)
|
||||
?modules (?. module :modules)
|
||||
function-keys (if ?functions
|
||||
(love-functions->lsp ?functions (.. binding "."))
|
||||
{})
|
||||
module-keys (if ?modules (module-list->fields ?modules binding) {})
|
||||
fields (merge function-keys module-keys)]
|
||||
(values name (build-lsp-value binding nil ?docstring fields)))))
|
||||
|
||||
(fn get-all-love-api-functions [love-api]
|
||||
[(table.unpack love-api.functions) (table.unpack love-api.callbacks)])
|
||||
|
||||
(fn love-api->lsp [love-api]
|
||||
"Given documentation for the entire LÖVE framework from the LÖVE-API Lua
|
||||
library, generate the root LÖVE object suitable for the Fennel LSP."
|
||||
(let [root-module {:description (.. "LÖVE is a framework for making 2D "
|
||||
"games in the Lua programming language.")
|
||||
:functions (get-all-love-api-functions love-api)
|
||||
:modules love-api.modules
|
||||
:name :love}]
|
||||
(module-list->fields [root-module])))
|
||||
|
||||
(fn convert []
|
||||
"Convert LÖVE framework from Lua table to a configuration object
|
||||
used by fennel-ls."
|
||||
(download-love-api-tooling!)
|
||||
(let [love-api (require-love-api)
|
||||
root-lsp-tbl (love-api->root-lsp-tbl love-api)]
|
||||
(stringify-table root-lsp-tbl)))
|
||||
(let [love-api (require-love-api)]
|
||||
(fennel.view (love-api->lsp love-api))))
|
||||
|
||||
{: convert}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user