Support table parameters and record types (#37) #38

Merged
Aire-One merged 7 commits from feat/#37 into master 2022-11-06 19:23:20 +01:00
6 changed files with 65 additions and 17 deletions
Showing only changes of commit aa42419a54 - Show all commits

View File

@ -1,4 +1,5 @@
local List = require "pl.List"
local Type_Info = require "entity.Type_Info"
local record Function_Info
metamethod __call: function(Function_Info): Function_Info
@ -6,7 +7,7 @@ local record Function_Info
Function_Info: Function_Info
record Parameter
name: string
types: List<string>
types: List<Type_Info.Type_Info>
end
name: string
@ -27,7 +28,7 @@ local __Function_Info: metatable<Function_Info> = {
end,
}
function Function_Info:append_parameter(name: string, types: List<string>)
function Function_Info:append_parameter(name: string, types: List<Type_Info.Type_Info>)
self.parameters:append {
name = name,
types = types,

View File

@ -9,7 +9,9 @@ local record Module_Doc
record_name: string
constructors: List<Function_Info.Function_Info>
constructors: List<Function_Info.Function_Info> -- Translates to a list of methods
constructor_param_record: List<Variable_Info.Variable_Info> -- Constructor with the __call metamethod and named parameters pattern
methods: List<Function_Info.Function_Info>
properties: List<Variable_Info.Variable_Info>
static_functions: List<Function_Info.Function_Info>
@ -20,6 +22,7 @@ local __Module_Doc: metatable<Module_Doc> = {
__call = function(_: Module_Doc): Module_Doc
return {
constructors = List(),
constructor_param_record = List(),
methods = List(),
properties = List(),
static_functions = List(),

View File

@ -0,0 +1,31 @@
local Map = require "pl.Map"
local record Type_Info
metamethod __call: function(Type_Info, record_name: string): Type_Info
Type_Info: Type_Info
name: string
-- Map : name -> type
-- We can't use Variable_Info here because it's a circular dependency.
record_entries: Map<string, string> | nil
end
local __Type_Info: metatable<Type_Info> = {
__call = function(_self: Type_Info, record_name: string): Type_Info
if record_name ~= nil then
return {
name = record_name,
record_entries = Map()
}
end
return {
name = "",
record_entries = nil,
}
end,
}
return setmetatable({} as Type_Info, __Type_Info)

View File

@ -1,4 +1,5 @@
local List = require "pl.List"
local Type_Info = require "entity.Type_Info"
local record Variable_Info
metamethod __call: function(Variable_Info): Variable_Info
@ -6,7 +7,7 @@ local record Variable_Info
Variable_Info: Variable_Info
name: string
types: List<string>
types: List<Type_Info.Type_Info>
constraints: List<string>
end

View File

@ -2,6 +2,7 @@ local Function_Info = require "entity.Function_Info"
local List = require "pl.List"
local stringx = require "pl.stringx"
local template = require "pl.template"
local Type_Info = require "entity.Type_Info"
local utils = require "utils"
local Variable_Info = require "entity.Variable_Info"
@ -12,13 +13,13 @@ function snippets.indent(str: string, level: number): string
return stringx.rstrip(stringx.indent(str, level, string.rep(" ", 3)))
end
function snippets.render_typed_variable(name: string, types: List<string>): string
function snippets.render_typed_variable(name: string, types: List<Type_Info.Type_Info>): string
local tmpl =
[[$(name): $(types)]]
local tmpl_args = {
name = name,
types = types:concat(" | "),
types = types:map(function(t: Type_Info.Type_Info): string return t.name end):concat(" | "),
}
return utils.do_or_fail(template.substitute, tmpl, tmpl_args)
@ -70,10 +71,11 @@ function snippets.render_record_properties(items: List<Variable_Info.Variable_In
end
local enum_type = utils.capitalize(item.name)
local enum_type_info: Type_Info.Type_Info = { name = enum_type }
return string.format(
"%s%s",
snippets.render_enum(enum_type, item.constraints),
snippets.render_typed_variable(item.name, List({ enum_type })))
snippets.render_typed_variable(item.name, List({ enum_type_info })))
end):concat("\n")
end

View File

@ -5,6 +5,7 @@ local Module_Doc = require "entity.Module_Doc"
local scan = require "web_sanitize.query.scan_html"
local scraper_utils = require "scraper.utils"
local stringx = require "pl.stringx"
local Type_Info = require "entity.Type_Info"
local utils = require "utils"
local Variable_Info = require "entity.Variable_Info"
@ -14,12 +15,17 @@ local function extract_node_text(node: scan.HTMLNode): string
return utils.sanitize_string(node:inner_text())
end
local function parse_parameter_types(parameter_type: string): List<string>
local function parse_parameter_types(parameter_type: string): List<Type_Info.Type_Info>
if parameter_type == "" then
return List({ "any" })
local type_info: Type_Info.Type_Info = { name = "any" }
return List({ type_info })
end
return stringx.split(parameter_type, " or "):map(utils.sanitize_string)
return stringx.split(parameter_type, " or "):map(
function(type_name: string): Type_Info.Type_Info
return { name = utils.sanitize_string(type_name) }
end
)
end
local function extract_item_name(item_name_node: scan.HTMLNode): string
@ -50,12 +56,12 @@ local function extract_function_parameters(function_parameters_node: scan.HTMLNo
local name = extract_node_text(nodes[query_selectors.name] as scan.HTMLNode)
local types = parse_parameter_types(extract_node_text(nodes[query_selectors.types] as scan.HTMLNode))
if types == List({ "table" }) then
if #types == 1 and types[1].name == "table" then
local record_name = utils.capitalize(name)
current_record_parameter = record_name
return {
name = name,
types = List({ record_name }),
types = List({ Type_Info(record_name) }),
}
end
@ -132,7 +138,8 @@ local function extract_section_variables(dl: string): { Variable_Info.Variable_I
variable_info.name = extract_item_name(nodes[query_selectors.variable_name])
variable_info.types = parse_parameter_types(extract_node_text(nodes[query_selectors.variable_summary_type]))
if variable_info.types:contains("string") then
if #variable_info.types == 1 and variable_info.types[1].name == "string" then
log:debug("extract variable string with constraints, this is an enum")
variable_info.constraints = List(extract_property_constraints(nodes[query_selectors.variable_property_constraint])):map(
function(constraint: string): string
return (constraint:gsub("&quot;", ""))
@ -166,6 +173,12 @@ function module.get_doc_from_page(html: string, module_name: string): Module_Doc
local module_doc = Module_Doc()
module_doc.record_name = utils.capitalize((module_name:gsub(".*%.", "")))
local self_type: Type_Info.Type_Info = { name = module_doc.record_name }
local self_parameter: Function_Info.Parameter = {
name = "self",
types = List({ self_type }),
}
for i = 1, #nodes:get("h2.section-header") do
local h2 = nodes:get("h2.section-header")[i]
local section_name = utils.sanitize_string(h2:inner_text())
@ -181,10 +194,7 @@ function module.get_doc_from_page(html: string, module_name: string): Module_Doc
log:warn("Not implemented: Deprecated object properties")
elseif section_name == "Object methods" then
module_doc.methods = List(extract_section_functions(dl_html)):map(function(method: Function_Info.Function_Info): Function_Info.Function_Info
method.parameters:insert(1, {
name = "self",
types = List({ module_doc.record_name }),
})
method.parameters:insert(1, self_parameter)
return method
end)
elseif section_name == "Signals" then