feat: implement record's metamethod for Constructor
ci/woodpecker/pr/docker-build Pipeline was successful Details
ci/woodpecker/pr/lint Pipeline was successful Details
ci/woodpecker/pr/test Pipeline was successful Details
ci/woodpecker/pr/build-and-run Pipeline failed Details

This commit is contained in:
Aire-One 2023-12-21 00:09:09 +01:00
parent 37365431b2
commit c09409ac1c
6 changed files with 101 additions and 7 deletions

View File

@ -32,6 +32,7 @@
"Luarocks",
"luasec",
"luasocket",
"metamethods",
"mkdir",
"modname",
"reportfile",

View File

@ -171,4 +171,38 @@ describe("Teal type definition Printer", function()
return Module
]]))
it("should print __call metamethod", gen(
{
children = {
{
children = {},
name = "Signal",
token = "enum",
},
{
parameters = {},
return_types = {},
name = "timer",
metamethod = "__call",
token = "metamethod",
}
},
name = "Timer",
module_path = "gears.timer",
dependencies = {},
global = false,
token = "module",
},
[[
-- This file was auto-generated.
local record Timer
enum Signal
end
metamethod __call: function()
end
return Timer
]]))
end)

View File

@ -468,7 +468,7 @@ describe("Scrap documentation", function()
token = "module",
}))
it("should produce a Record node when a function parameter is a named-parameter-table #debug", test(
it("should produce a Record node when a function parameter is a named-parameter-table", test(
[[
<h2 class="section-header">
<a name="Static_module_functions"></a>Static module functions
@ -833,7 +833,7 @@ describe("Scrap documentation", function()
}
}))
it("should parse function return union types and multiple return values #debug", test(
it("should parse function return union types and multiple return values", test(
[[
<h2 class="section-header "><a name="Static_module_functions"></a>Static module functions</h2>
<dl class="function">
@ -882,4 +882,40 @@ describe("Scrap documentation", function()
global = false,
token = "module",
}))
it("should produce a __call metamethod for constructor", test(
[[
<h2 class="section-header "><a name="Constructors"></a>Constructors</h2>
<dl class="function">
<dt>
<a class="copy-link js-copy-link" name="gears.timer" href="#gears.timer">🔗</a>
<strong>gears.timer <span class="function_named_args"><b>{</b>[args]<b>}</b></span></strong>
<span class="baseclass"></span>
</dt>
<dd>
</dd>
</dl>
]],
"gears.timer",
{
children = {
{
children = {},
name = "Signal",
token = "enum",
},
{
parameters = {},
return_types = {},
name = "timer",
metamethod = "__call",
token = "metamethod",
}
},
name = "Timer",
module_path = "gears.timer",
dependencies = {},
global = false,
token = "module",
}))
end)

View File

@ -28,6 +28,11 @@ local function render_function_return_types(types: { { string } }): string
return ": " .. table.concat(positional_return_types, ", ")
end
local function render_metamethod_type(metamethod: Node.Metamethod): string
-- Node.Metamethod enum matches the metamethods names, so we can simply print them as-is
return metamethod
end
local function dedent(str: string): string
return stringx.dedent(str):sub(1, -2)
end
@ -155,8 +160,19 @@ local node_printer <total>: { Node.Token : Node_Printer_Function } = {
end,
},
["metamethod"] = {
on_node = function(): string, integer
log:warn("Metamethods are not supported yet")
on_node = function(node: Node, indent_level: integer): string, integer
local args = {}
for _, parameter in ipairs(node.parameters) do
table.insert(args, print_teal(parameter):sub(1, -2)) -- need to remove the newline ending
end
return render_code(
string.format(
"metamethod %s: function(%s)%s",
render_metamethod_type(node.metamethod),
table.concat(args, ", "),
render_function_return_types(node.return_types)
),
indent_level), indent_level
end,
},
["type"] = {

View File

@ -234,11 +234,12 @@ end
-- - Nodes that should be added to the global scope
-- - Strings that should be added to the record Signals
local section_scrapers <total>: { Section : function(html: string, record_name: string, module_name: string): { Node }, { Node }, { string } } = {
["Constructors"] = function(html: string): { Node }, { Node }, { string }
["Constructors"] = function(html: string, record_name: string): { Node }, { Node }, { string }
local constructors <const> = extract_section_functions(html)
for _, constructor in ipairs(constructors) do
if constructor.token == "function" then
constructor.name = "new"
if constructor.token == "function" and constructor.name == utils.lowercase(record_name) then
constructor.token = "metamethod"
constructor.metamethod = "__call"
end
end
return constructors, {}, {}

View File

@ -22,6 +22,12 @@ local record Node
parameters: { Node }
return_types: { { string } }
-- for "methamethod"
enum Metamethod
"__call"
end
metamethod: Metamethod
-- for "module"
module_path: string
dependencies: { string : string } -- module_name -> module_path