Reviewed-on: #64
This commit is contained in:
commit
866c4e6920
5
justfile
5
justfile
|
@ -41,7 +41,10 @@ run:
|
||||||
{{ tl }} src/awesomewm.d.tl/init.tl
|
{{ tl }} src/awesomewm.d.tl/init.tl
|
||||||
|
|
||||||
validate:
|
validate:
|
||||||
cyan check `find generated/ -type f -iname '*.d.tl' | xargs`
|
cd generated && cyan \
|
||||||
|
check \
|
||||||
|
--global-env-def "global_env" \
|
||||||
|
`find . -type f -iname '*.d.tl' | xargs`
|
||||||
|
|
||||||
# TODO : how to run a debugger on Teal code?
|
# TODO : how to run a debugger on Teal code?
|
||||||
debug:
|
debug:
|
||||||
|
|
|
@ -2,16 +2,21 @@ local List = require "pl.List"
|
||||||
local Map = require "pl.Map"
|
local Map = require "pl.Map"
|
||||||
|
|
||||||
local type_fix <const> : Map<string, string> = Map({
|
local type_fix <const> : Map<string, string> = Map({
|
||||||
|
awesome = "awesome",
|
||||||
|
Awesome = "awesome",
|
||||||
bool = "boolean",
|
bool = "boolean",
|
||||||
client = "Client",
|
client = "client",
|
||||||
|
Client = "client",
|
||||||
["gears.shape"] = "Shape",
|
["gears.shape"] = "Shape",
|
||||||
["gears.surface"] = "Surface",
|
["gears.surface"] = "Surface",
|
||||||
image = "Image",
|
image = "Image",
|
||||||
int = "integer",
|
int = "integer",
|
||||||
screen = "Screen",
|
screen = "screen",
|
||||||
|
Screen = "screen",
|
||||||
shape = "Shape",
|
shape = "Shape",
|
||||||
surface = "Surface",
|
surface = "Surface",
|
||||||
tag = "Tag",
|
tag = "tag",
|
||||||
|
Tag = "tag",
|
||||||
["wibox.widget"] = "Widget",
|
["wibox.widget"] = "Widget",
|
||||||
widget = "Widget",
|
widget = "Widget",
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
local List = require "pl.List"
|
||||||
|
local Module_Doc = require "entity.Module_Doc"
|
||||||
|
local template = require "pl.template"
|
||||||
|
local utils = require "utils"
|
||||||
|
local snippets = require "generator.snippets"
|
||||||
|
|
||||||
|
-- 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!)
|
||||||
|
|
||||||
|
# for module in modules:iter() do
|
||||||
|
global record $(module.record_name)
|
||||||
|
# if #module.signals ~= 0 then
|
||||||
|
$(snippets.indent(snippets.render_enum("Signal", module.signals)))
|
||||||
|
|
||||||
|
# end -- /signals
|
||||||
|
# if #module.methods ~= 0 then
|
||||||
|
-- Object methods
|
||||||
|
$(snippets.indent(snippets.render_record_functions(module.methods)))
|
||||||
|
|
||||||
|
# end -- /methods
|
||||||
|
# if #module.properties ~= 0 then
|
||||||
|
-- Object properties
|
||||||
|
$(snippets.indent(snippets.render_record_properties(module.properties)))
|
||||||
|
|
||||||
|
# end -- /properties
|
||||||
|
# if #module.constructors ~= 0 then
|
||||||
|
-- Constructors
|
||||||
|
$(snippets.indent(snippets.render_record_functions(module.constructors)))
|
||||||
|
|
||||||
|
# end -- /constructors
|
||||||
|
# if #module.static_functions ~= 0 then
|
||||||
|
-- Static functions
|
||||||
|
$(snippets.indent(snippets.render_record_functions(module.static_functions)))
|
||||||
|
# end -- /static_functions
|
||||||
|
end
|
||||||
|
|
||||||
|
# end -- /modules
|
||||||
|
]]
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
|
||||||
|
function module.generate_teal(data: List<Module_Doc.Module_Doc>): string
|
||||||
|
local tmpl_args = {
|
||||||
|
ipairs = ipairs,
|
||||||
|
modules = data,
|
||||||
|
snippets = snippets,
|
||||||
|
}
|
||||||
|
return utils.do_or_fail(template.substitute, tmpl, tmpl_args)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return module
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
return {
|
return {
|
||||||
|
global_env_def = require "generator.global_env_def",
|
||||||
teal_type_definitions = require "generator.teal_type_definitions",
|
teal_type_definitions = require "generator.teal_type_definitions",
|
||||||
snippets = require "generator.snippets",
|
snippets = require "generator.snippets",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,97 @@
|
||||||
local crawler = require "crawler"
|
local crawler = require "crawler"
|
||||||
local filesystem = require "filesystem"
|
local filesystem = require "filesystem"
|
||||||
|
local generator = require "generator"
|
||||||
local List = require "pl.List"
|
local List = require "pl.List"
|
||||||
local logger = require "logger"
|
local logger = require "logger"
|
||||||
|
local Module_Doc = require "entity.Module_Doc"
|
||||||
local Module_Info = require "entity.Module_Info"
|
local Module_Info = require "entity.Module_Info"
|
||||||
local property = require "property"
|
local property = require "property"
|
||||||
local scraper = require "scraper"
|
local scraper = require "scraper"
|
||||||
local generator = require "generator"
|
local utils = require "utils"
|
||||||
|
|
||||||
local log = logger.log("main")
|
local log = logger.log("main")
|
||||||
|
|
||||||
log:info(logger.message_with_metadata("Start", { property = property }))
|
log:info(logger.message_with_metadata("Start", { property = property }))
|
||||||
|
|
||||||
local index = crawler.fetch(property.base_url .. property.index_uri)
|
local function module_lists(
|
||||||
|
doc_index_url: string,
|
||||||
|
global_modules: List<string>,
|
||||||
|
ignored_modules: List<string>
|
||||||
|
): List<Module_Info.Module_Info>, List<Module_Info.Module_Info>, List<Module_Info.Module_Info>
|
||||||
|
local index = crawler.fetch(doc_index_url)
|
||||||
|
local all_module_infos = List(scraper.module_info_list.get_modules_from_index(index))
|
||||||
|
|
||||||
local ignored_modules = List(property.ignored_modules)
|
local global_module_infos: List<Module_Info.Module_Info> = List()
|
||||||
local module_infos = List(scraper.module_info_list.get_modules_from_index(index)):filter(
|
local module_infos: List<Module_Info.Module_Info> = List()
|
||||||
function(module: Module_Info.Module_Info): boolean
|
|
||||||
return not ignored_modules:contains(module.name)
|
for module in all_module_infos:iter() do
|
||||||
|
if global_modules:contains(module.name) then
|
||||||
|
global_module_infos:append(module)
|
||||||
|
elseif not ignored_modules:contains(module.name) then
|
||||||
|
module_infos:append(module)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return all_module_infos, module_infos, global_module_infos
|
||||||
|
end
|
||||||
|
|
||||||
|
local function do_one_file(
|
||||||
|
url: string,
|
||||||
|
record_name: string,
|
||||||
|
output_path: string
|
||||||
)
|
)
|
||||||
|
|
||||||
log:info("Finished Module List scrapping, found " .. #module_infos .. " modules")
|
|
||||||
|
|
||||||
local function do_one_file(url: string, output_base_dir: string)
|
|
||||||
local module_name = url:gsub(".*/", ""):gsub(".html", "")
|
|
||||||
local html = crawler.fetch(url)
|
local html = crawler.fetch(url)
|
||||||
local module_doc = scraper.module_doc.get_doc_from_page(html, module_name)
|
local module_doc = scraper.module_doc.get_doc_from_page(html, record_name)
|
||||||
module_doc:fixup()
|
module_doc:fixup()
|
||||||
module_doc:populate_requires()
|
module_doc:populate_requires()
|
||||||
filesystem.file_writer.write(
|
filesystem.file_writer.write(
|
||||||
generator.teal_type_definitions.generate_teal(module_doc),
|
generator.teal_type_definitions.generate_teal(module_doc),
|
||||||
output_base_dir .. module_name:gsub("%.", "/") .. ".d.tl"
|
output_path
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = 1, #module_infos do
|
local all_module_infos, module_infos, global_module_infos = module_lists(
|
||||||
|
property.base_url .. property.index_uri,
|
||||||
|
List(property.capi_modules),
|
||||||
|
List(property.ignored_modules)
|
||||||
|
)
|
||||||
|
|
||||||
|
log:info(
|
||||||
|
logger.message_with_metadata(
|
||||||
|
"Finished Module List scrapping",
|
||||||
|
{
|
||||||
|
total_module_count = #all_module_infos,
|
||||||
|
module_count = #module_infos,
|
||||||
|
global_module_count = #global_module_infos
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for module in module_infos:iter() do
|
||||||
do_one_file(
|
do_one_file(
|
||||||
property.base_url .. "/" .. module_infos[i].uri,
|
property.base_url .. "/" .. module.uri,
|
||||||
property.out_directory .. "/"
|
module.name,
|
||||||
|
property.out_directory .. "/" .. module.name:gsub("%.", "/") .. ".d.tl"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local global_env_def: List<Module_Doc.Module_Doc> = List()
|
||||||
|
for module in global_module_infos:iter() do
|
||||||
|
if module.name:gmatch(".*%sand%s.*") then
|
||||||
|
do_one_file(
|
||||||
|
property.base_url .. "/" .. module.uri,
|
||||||
|
module.name,
|
||||||
|
property.out_directory .. "/" .. module.name:gsub(".*%sand%s", ""):gsub("%.", "/") .. ".d.tl"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
local html = crawler.fetch(property.base_url .. "/" .. module.uri)
|
||||||
|
local module_doc = scraper.module_doc.get_doc_from_page(html, (module.name:gsub("%sand%s.*", "")))
|
||||||
|
module_doc:fixup()
|
||||||
|
module_doc.record_name = utils.lowercase(module_doc.record_name)
|
||||||
|
global_env_def:append(module_doc)
|
||||||
|
end
|
||||||
|
filesystem.file_writer.write(
|
||||||
|
generator.global_env_def.generate_teal(global_env_def),
|
||||||
|
property.out_directory .. "/global_env.d.tl"
|
||||||
|
)
|
||||||
|
|
|
@ -4,6 +4,12 @@ local record Property
|
||||||
|
|
||||||
out_directory: string
|
out_directory: string
|
||||||
|
|
||||||
|
--- Pages with modules from the C API.
|
||||||
|
-- These pages contains definitions for both, the global C API and the
|
||||||
|
-- `awful` library. We have to manage them separately, because the global C
|
||||||
|
-- API should be part of the global_en_def.
|
||||||
|
capi_modules: { string }
|
||||||
|
|
||||||
--- Pages from the navigation menu to ignore.
|
--- Pages from the navigation menu to ignore.
|
||||||
-- Sets to ignore documentations and sample file. I also added libraries with
|
-- 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
|
-- low quality API documentation, I'll probably work on them later, lets start
|
||||||
|
@ -16,6 +22,12 @@ local property: Property = {
|
||||||
base_url = "file:///usr/share/doc/awesome/doc",
|
base_url = "file:///usr/share/doc/awesome/doc",
|
||||||
index_uri = "/index.html",
|
index_uri = "/index.html",
|
||||||
out_directory = "generated",
|
out_directory = "generated",
|
||||||
|
capi_modules = {
|
||||||
|
"awesome",
|
||||||
|
"client and awful.client",
|
||||||
|
"screen and awful.screen",
|
||||||
|
"tag and awful.tag",
|
||||||
|
},
|
||||||
ignored_modules = {
|
ignored_modules = {
|
||||||
-- Sample files
|
-- Sample files
|
||||||
"rc.lua",
|
"rc.lua",
|
||||||
|
|
|
@ -43,6 +43,10 @@ function utils.capitalize(s: string): string
|
||||||
return (s:gsub("^%l", string.upper))
|
return (s:gsub("^%l", string.upper))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function utils.lowercase(s: string): string
|
||||||
|
return (s:gsub("^%L", string.lower))
|
||||||
|
end
|
||||||
|
|
||||||
function utils.is_empty(s: string): boolean
|
function utils.is_empty(s: string): boolean
|
||||||
return s == nil or s == ""
|
return s == nil or s == ""
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,5 @@ return {
|
||||||
include_dir = {
|
include_dir = {
|
||||||
"src/awesomewm.d.tl",
|
"src/awesomewm.d.tl",
|
||||||
"types",
|
"types",
|
||||||
"generated", -- used to remove require error when visualizing the generated type definitions
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue