From 165bd7277c1f3573af8e363f48824d01b2e317d2 Mon Sep 17 00:00:00 2001 From: Aire-One Date: Mon, 15 Aug 2022 15:44:00 +0200 Subject: [PATCH] feat(generator): initial --- .gitignore | 1 + .vscode/settings.json | 3 + rockspecs/awesomewm.d.tl-dev-1.rockspec | 1 + src/awesomewm.d.tl/generator/init.lua | 72 +++++++++++++++++++ src/awesomewm.d.tl/generator/snippets.lua | 52 ++++++++++++++ src/awesomewm.d.tl/generator/template.tl.tmpl | 20 ++++++ src/awesomewm.d.tl/init.lua | 10 ++- src/awesomewm.d.tl/properties.lua | 2 + src/awesomewm.d.tl/utils.lua | 12 ++++ 9 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 src/awesomewm.d.tl/generator/init.lua create mode 100644 src/awesomewm.d.tl/generator/snippets.lua create mode 100644 src/awesomewm.d.tl/generator/template.tl.tmpl diff --git a/.gitignore b/.gitignore index 450ff71..8df544e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ lua_modules +generated diff --git a/.vscode/settings.json b/.vscode/settings.json index 783318b..226142b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,14 +11,17 @@ "awesomewm", "getcontent", "htmlparser", + "isdir", "justfile", "lldebugger", "Luacheck", "luacheckrc", "lualogging", "Luarocks", + "mkdir", "setopt", "Stylua", + "tmpl", "wibox", "writefunction" ], diff --git a/rockspecs/awesomewm.d.tl-dev-1.rockspec b/rockspecs/awesomewm.d.tl-dev-1.rockspec index 654e6e8..a846424 100644 --- a/rockspecs/awesomewm.d.tl-dev-1.rockspec +++ b/rockspecs/awesomewm.d.tl-dev-1.rockspec @@ -15,6 +15,7 @@ dependencies = { "lua-curl 0.3.13", "htmlparser 0.3.9", "web_sanitize 1.3.0", + "penlight 1.13.1", } build = { type = "builtin", diff --git a/src/awesomewm.d.tl/generator/init.lua b/src/awesomewm.d.tl/generator/init.lua new file mode 100644 index 0000000..335bb79 --- /dev/null +++ b/src/awesomewm.d.tl/generator/init.lua @@ -0,0 +1,72 @@ +local file = require "pl.file" +local template = require "pl.template" +local path = require "pl.path" +local log = require "logger" +local utils = require "utils" +local snippets = require "generator.snippets" + +local tmpl = (function(mod) + local package_path = utils.do_or_fail(path.package_path, mod) + local package_dir = path.dirname(package_path) + return utils.do_or_fail(file.read, package_dir .. "/template.tl.tmpl", false) +end)(...) + +local generator = {} + +function generator.generate_teal(data) + -- TODO : add the required modules to the generated code + -- TODO : replace this with a proper way to get the module name (will also probably need the module path) + local module_data = { name = "module_name" } + for _, item in ipairs(data) do + if item.section == "Static functions" then + -- TODO + module_data.static_functions = item.items + elseif item.section == "Constructors" then + -- TODO + module_data.constructors = item.items + elseif item.section == "Object properties" then + -- TODO + module_data.properties = item.items + elseif item.section == "Object methods" then + module_data.methods = {} + -- TODO : add the self parameter + -- TODO : define overrides to use the signal type in connect/emit functions + for _, i in ipairs(item.items) do + table.insert( + module_data.methods, + i.name .. ": " .. snippets.anonymous_function(i) + ) + end + elseif item.section == "Signals" then + module_data.signals = item.items + end + end + + local env = { + ipairs = ipairs, + module = module_data, + } + return utils.do_or_fail(template.substitute, tmpl, env) +end + +function generator.write(file_content, file_path) + -- Make sure the directory we want to write the file to exists + local directory = path.dirname(file_path) + if not path.isdir(directory) then + path.mkdir(directory) + end + + local success, error = file.write(file_path, file_content, false) + + if not success then + log:error { + "generator.write error", + error = error, + } + return + end + + log:info { "Successfully wrote file", file = file_path } +end + +return generator diff --git a/src/awesomewm.d.tl/generator/snippets.lua b/src/awesomewm.d.tl/generator/snippets.lua new file mode 100644 index 0000000..9d29310 --- /dev/null +++ b/src/awesomewm.d.tl/generator/snippets.lua @@ -0,0 +1,52 @@ +local utils = require "utils" +local template = require "pl.template" + +-- Refactor scraper code to use pl.List objects +local function join(arr, delim) + local ret = "" + for i, type in ipairs(arr) do + ret = ret .. type + if i < #arr then + ret = ret .. delim + end + end + return ret +end + +local snippets = {} + +function snippets.types_list(types) + return join(types, ", ") +end + +function snippets.anonymous_function(item) + local parameters_string = "" + if item.parameters then + for i, param in ipairs(item.parameters) do + parameters_string = parameters_string .. param.name + local types = "any" + if param.type then + types = snippets.types_list(param.type) + end + parameters_string = parameters_string .. ": " .. types + if i < #item.parameters then + parameters_string = parameters_string .. ", " + end + end + end + + local returns_string = "" + if item.returns then + returns_string = snippets.types_list(item.returns) + end + + local tmpl = + [[function($(parameters_string))$(#returns_string > 0 and (": " .. returns_string))]] + + return utils.do_or_fail(template.substitute, tmpl, { + parameters_string = parameters_string, + returns_string = returns_string, + }) +end + +return snippets diff --git a/src/awesomewm.d.tl/generator/template.tl.tmpl b/src/awesomewm.d.tl/generator/template.tl.tmpl new file mode 100644 index 0000000..84df6b4 --- /dev/null +++ b/src/awesomewm.d.tl/generator/template.tl.tmpl @@ -0,0 +1,20 @@ +-- Auto generated file (Do not manually edit this file!) + +# if module.signals then +local enum signals +# for _, signal in ipairs(module.signals) do + "$(signal.name)" +# end +end + +# end -- /signals +local record $(module.name) +# if module.methods then + -- Object methods +# for _, method in ipairs(module.methods) do + $(method) +# end +# end -- /methods +end + +return $(module.name) diff --git a/src/awesomewm.d.tl/init.lua b/src/awesomewm.d.tl/init.lua index 0c3dd7a..decd5bb 100644 --- a/src/awesomewm.d.tl/init.lua +++ b/src/awesomewm.d.tl/init.lua @@ -3,6 +3,7 @@ local inspect = require "inspect" local log = require "logger" local properties = require "properties" local scraper = require "scraper" +local generator = require "generator" log:info( inspect { message = "Start extraction", base_url = properties.base_url } @@ -25,6 +26,11 @@ log:info( -- end local page = - crawler.fetch(properties.base_url .. "/widgets/awful.widget.button.html") + crawler.fetch(properties.base_url .. "/widgets/wibox.widget.imagebox.html") local items = scraper.get_doc_from_page(page) -log:info(inspect { items }) +-- log:info(inspect { items }) + +generator.write( + generator.generate_teal(items), + properties.out_directory .. "/test.tl" +) diff --git a/src/awesomewm.d.tl/properties.lua b/src/awesomewm.d.tl/properties.lua index d67d45b..0ca6f9a 100644 --- a/src/awesomewm.d.tl/properties.lua +++ b/src/awesomewm.d.tl/properties.lua @@ -5,6 +5,8 @@ properties.base_url = "file:///usr/share/doc/awesome/doc" properties.index_uri = "/index.html" +properties.out_directory = "generated" + --- Pages from the navigation menu to ignore. -- Sets to ignore documentations and sample file. I also added libraries with -- low quality API documentation, I'll probably work on them later, lets start diff --git a/src/awesomewm.d.tl/utils.lua b/src/awesomewm.d.tl/utils.lua index fb10136..ee4fb08 100644 --- a/src/awesomewm.d.tl/utils.lua +++ b/src/awesomewm.d.tl/utils.lua @@ -55,4 +55,16 @@ function utils.trim(string) return string:match "^%s*(.-)%s*$" end +function utils.do_or_fail(func, ...) + local log = require "logger" + local res, err = func(...) + + if not res then + log:error { "do_or_fail failed!", error = err } + error(err) + end + + return res +end + return utils