feat(Visitors): implement module_dependencies

This commit is contained in:
Aire-One 2023-05-21 20:00:09 +02:00
parent 37742f795d
commit e076a08572
10 changed files with 72 additions and 37 deletions

View File

@ -1,10 +1,12 @@
local type Node = require("types.Node")
local basic_nodes <total>: { Node.Token : function(name: string): Node } = {
module = function(name: string): Node
local basic_nodes <total>: { Node.Token : function(name: string, ...: any): Node } = {
module = function(name: string, module_path: string): Node
return {
token = "module",
name = name,
module_path = module_path,
dependencies = {},
children = {},
}
end,
@ -53,8 +55,8 @@ local basic_nodes <total>: { Node.Token : function(name: string): Node } = {
end,
}
local function create_node(token: Node.Token, name: string): Node
local node = basic_nodes[token](name)
local function create_node(token: Node.Token, name: string, ...: any): Node
local node = basic_nodes[token](name, ...)
return node
end

View File

@ -1,27 +1,13 @@
local type Dag = require("types.Dag")
local type Node = require("types.Node")
local function init(): Dag
local function new(): Dag
local dag <total>: Dag = {
nodes_by_module_name = {},
modules = {},
global_nodes = {},
}
return dag
end
local function insert(dag: Dag, module_name: string, node: Node)
if not dag.nodes_by_module_name[module_name] then
dag.nodes_by_module_name[module_name] = {}
end
table.insert(dag.nodes_by_module_name[module_name], node)
end
local function insert_global(dag: Dag, node: Node)
table.insert(dag.global_nodes, node)
end
return {
init = init,
insert = insert,
insert_global = insert_global,
new = new,
}

View File

@ -11,6 +11,7 @@ local logger = require "logger"
local Map = require "pl.Map"
local Module_Doc = require "entity.Module_Doc"
local Module_Info = require "entity.Module_Info"
local module_dependencies = require "visitors.module_dependencies"
local type Node = require "types.Node"
local property = require "property"
local scraper = require "scraper"
@ -156,10 +157,22 @@ local module_ast, other_nodes = scraper.module_doc.get_doc_from_page(
ast.in_order_visitor(module_ast, function(node: Node)
type_mapping.visit(node)
end)
ast.in_order_visitor(module_ast, function(node: Node)
module_dependencies.visit(node, module_ast, {
modules = {
Screen = {
name = "screen",
module_path = "awful.screen",
token = "module",
},
}
})
end)
log:info(logger.message_with_metadata("Finished", {
module_ast = module_ast,
other_nodes = other_nodes,
deps = module_ast.dependencies,
}))
filesystem.file_writer.write(

View File

@ -245,7 +245,7 @@ local section_scrapers <total>: { Section : function(html: string, record_name:
local module = {}
function module.get_doc_from_page(html: string, module_name: string): Node, { Node }
function module.get_doc_from_page(html: string, module_path: string): Node, { Node }
local html_nodes = scraper_utils.extract_nodes(html, {
"h2.section-header",
"dl.function",
@ -255,8 +255,8 @@ function module.get_doc_from_page(html: string, module_name: string): Node, { No
error "The list aren't the same size!"
end
local record_name <const> = utils.capitalize((module_name:gsub(".*%.", "")))
local module_root <const> = ast.create_node("module", record_name)
local record_name <const> = utils.capitalize((module_path:gsub(".*%.", "")))
local module_root <const> = ast.create_node("module", record_name, module_path)
local other_nodes <const>: { Node } = {}
local module_signals_node <const> = ast.create_node("enum", "Signal")
@ -268,7 +268,7 @@ function module.get_doc_from_page(html: string, module_name: string): Node, { No
local dl_html = html_nodes:get("dl.function")[i]:outer_html()
if section_scrapers[section_name] then
local module_nodes, global_nodes, signals_name = section_scrapers[section_name](dl_html, record_name, module_name)
local module_nodes, global_nodes, signals_name = section_scrapers[section_name](dl_html, record_name, module_path)
for _, node in ipairs(module_nodes) do
table.insert(module_root.children, node)
end

View File

@ -1,7 +1,7 @@
local type Node = require("types.Node")
local record Dag
nodes_by_module_name: { string : { Node } }
modules: { string : Node } -- module_name -> root_node (token = "module")
global_nodes: { Node }
end

View File

@ -20,6 +20,10 @@ local record Node
-- for "function" and "metamethod"
parameters: { Node }
return_types: { string }
-- for "module"
module_path: string
dependencies: { string : string } -- module_name -> module_path
end
return Node

View File

@ -1,7 +0,0 @@
local type Node = require("types.Node")
local record Visitor
visit: function(Node)
end
return Visitor

View File

@ -76,10 +76,13 @@ function utils.do_or_fail<T>(func: function<T>(...: any): (T | nil, string), ...
return res as T -- promote to T since pcall succeeded at this point
end
function utils.spread<T>(t: { T }, i: { T })
for _, v in ipairs(i) do
function utils.spread<T>(t: { T }, ...: { T }): { T }
for _, a in ipairs({ ... }) do
for _, v in ipairs(a) do
table.insert(t, v)
end
end
return t
end
return utils

View File

@ -0,0 +1,35 @@
local type Dag = require("types.Dag")
local type Node = require("types.Node")
local utils = require("utils")
local spread = utils.spread
local function get_all_types_in_node(node: Node): { string }
local parameters_types = {}
if node.parameters then
for _, v in ipairs(node.parameters) do
spread(parameters_types, v.types)
end
end
return spread(
{},
node.types or {},
node.return_types or {},
parameters_types or {})
end
local record Module_Dependencies
visit: function(node: Node, mod: Node, d: Dag)
end
function Module_Dependencies.visit(node: Node, mod: Node, d: Dag)
local all_types <const> = get_all_types_in_node(node)
for _, v in ipairs(all_types) do
local dependency = d.modules[v]
if dependency then
mod.dependencies[dependency.name] = dependency.module_path
end
end
end
return Module_Dependencies

View File

@ -1,5 +1,4 @@
local type Node = require("types.Node")
local type Visitor = require("types.Visitor")
-- Special types I don't want to deal with for now
local gears_shape_function = "function(cr: any, width: integer, height: integer)"