From ddf9858aa081099b4fb5034383eaa63c916e5139 Mon Sep 17 00:00:00 2001 From: Aire-One Date: Sat, 22 Oct 2022 15:08:33 +0200 Subject: [PATCH] =?UTF-8?q?feat(generator):=20re-implement=20generator=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/awesomewm.d.tl/generator/snippets.tl | 90 ++++++++----------- .../generator/teal_type_definitions.tl | 82 +++++++---------- src/awesomewm.d.tl/generator/template.tl.tmpl | 20 ----- src/awesomewm.d.tl/init.tl | 14 +-- 4 files changed, 75 insertions(+), 131 deletions(-) delete mode 100644 src/awesomewm.d.tl/generator/template.tl.tmpl diff --git a/src/awesomewm.d.tl/generator/snippets.tl b/src/awesomewm.d.tl/generator/snippets.tl index 78ad3dc..ccd4084 100644 --- a/src/awesomewm.d.tl/generator/snippets.tl +++ b/src/awesomewm.d.tl/generator/snippets.tl @@ -1,66 +1,50 @@ +local Function_Info = require "entities.Function_Info" +local List = require "pl.List" local utils = require "utils" local template = require "pl.template" --- Refactor scraper code to use pl.List objects -local function join(arr: { string }, delim: string): string +local snippets = {} + +function snippets.indent(str: string, level: number): string + level = level or 1 local ret = "" - for i, t in ipairs(arr) do - ret = ret .. t - if i < #arr then - ret = ret .. delim - end + for line in str:gmatch("[^\n]+") do + ret = ret .. string.rep(" ", level * 3) .. line .. "\n" end return ret end -local record Anonymous_Function_Parameter_Record - name: string - type: { string } -end - -local record Anonymous_Function_Record - name: string - parameters: { Anonymous_Function_Parameter_Record } - returns: { string } -end - -local snippets = { - Anonymous_Function_Parameter_Record = Anonymous_Function_Parameter_Record, - Anonymous_Function_Record = Anonymous_Function_Record, -} - -function snippets.types_list(types: { string }): string - return join(types, ", ") -end - -function snippets.anonymous_function(item: Anonymous_Function_Record): string - 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 - +function snippets.render_typed_variable(name: string, types: List): string local tmpl = - [[function($(parameters_string))$(#returns_string > 0 and (": " .. returns_string))]] + [[$(name): $(types)]] - return utils.do_or_fail(template.substitute, tmpl, { - parameters_string = parameters_string, - returns_string = returns_string, - }) + local tmpl_args = { + name = name, + types = types:concat(", "), + } + + return utils.do_or_fail(template.substitute, tmpl, tmpl_args) +end + +function snippets.render_anonymous_function_signature(item: Function_Info.Function_Info): string + local tmpl = + [[$(function_name): function($(function_parameter))$(#function_return > 0 and (": " .. function_return))]] + + local tmpl_args = { + function_name = item.name, + function_parameter = item.parameters:map(function(param: Function_Info.Parameter): string + return snippets.render_typed_variable(param.name, List({param.type})) -- TODO : add support for multiple types + end):concat(", "), + function_return = item.return_types:concat(", "), + } + + return utils.do_or_fail(template.substitute, tmpl, tmpl_args) +end + +function snippets.render_record_functions(items: List): string + return items:map(function(item: Function_Info.Function_Info): string + return snippets.render_anonymous_function_signature(item) + end):concat("\n") end return snippets diff --git a/src/awesomewm.d.tl/generator/teal_type_definitions.tl b/src/awesomewm.d.tl/generator/teal_type_definitions.tl index 65c1c81..14568b1 100644 --- a/src/awesomewm.d.tl/generator/teal_type_definitions.tl +++ b/src/awesomewm.d.tl/generator/teal_type_definitions.tl @@ -1,64 +1,42 @@ -local file = require "pl.file" +local Module_Doc = require "entities.Module_Doc" local template = require "pl.template" -local path = require "pl.path" local utils = require "utils" local snippets = require "generator.snippets" -local tmpl = (function(mod: string): string - 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)(...) +-- The long therm goal is to have so many `snippets.render_*` functions that +-- we can render the whole file with the smallest template possible. +local tmpl = [[ +-- 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 $(mod_name) +# if #module.methods then + -- Object methods +$(snippets.indent(snippets.render_record_functions(module.methods))) +# end -- /methods +end + +return $(mod_name) +]] local module = {} -local record Generate_Teal_Data_Record - section: string - items: { snippets.Anonymous_Function_Record } -end - -function module.generate_teal(data: { Generate_Teal_Data_Record }): string - -- 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 record Module_Data_Record - name: string - static_functions: { snippets.Anonymous_Function_Record } - constructors: { snippets.Anonymous_Function_Record } - methods: { string } - properties: { snippets.Anonymous_Function_Record } - signals: { snippets.Anonymous_Function_Record } - end - local module_data: Module_Data_Record = { 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 = { +function module.generate_teal(mod: string, data: Module_Doc.Module_Doc): string + local tmpl_args = { ipairs = ipairs, - module = module_data, + mod_name = mod, + module = data, + snippets = snippets, } - return utils.do_or_fail(template.substitute, tmpl, env) + return utils.do_or_fail(template.substitute, tmpl, tmpl_args) + end return module diff --git a/src/awesomewm.d.tl/generator/template.tl.tmpl b/src/awesomewm.d.tl/generator/template.tl.tmpl deleted file mode 100644 index 84df6b4..0000000 --- a/src/awesomewm.d.tl/generator/template.tl.tmpl +++ /dev/null @@ -1,20 +0,0 @@ --- 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.tl b/src/awesomewm.d.tl/init.tl index 686c1ee..be63003 100644 --- a/src/awesomewm.d.tl/init.tl +++ b/src/awesomewm.d.tl/init.tl @@ -1,9 +1,10 @@ local crawler = require "crawler" +local filesystem = require "filesystem" local inspect = require "inspect" local log = require "logger" local properties = require "properties" local scraper = require "scraper" --- local generator = require "generator" +local generator = require "generator" log:info( inspect { message = "Start extraction", base_url = properties.base_url } @@ -28,12 +29,13 @@ log:info(inspect { modules_found = #module_infos }) local html = crawler.fetch(properties.base_url .. "/widgets/wibox.widget.textbox.html") local module_doc = scraper.module_doc.get_doc_from_page(html) -log:info(inspect { module_doc = module_doc }) +-- log:info(inspect { module_doc = module_doc }) -- local items = scraper.get_doc_from_page(page) -- log:info(inspect { items }) --- generator.write( --- generator.generate_teal(items), --- properties.out_directory .. "/test.tl" --- ) +local mod = "textbox" +filesystem.file_writer.write( + generator.teal_type_definitions.generate_teal(mod, module_doc), + properties.out_directory .. "/" .. mod .. ".d.tl" +)