-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgenEmmyAPI.lua
More file actions
182 lines (154 loc) · 5.1 KB
/
Copy pathgenEmmyAPI.lua
File metadata and controls
182 lines (154 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
local time = os.clock()
print("Requiring love_api")
local api = require('love_api')
local function safeDesc(src, prefix)
prefix = prefix or ""
return "--- " .. string.gsub(src, "\n", "\n" .. prefix .. "--- ")
end
local function stripNewlines(src)
return string.gsub(src, "\n", " ")
end
local function genReturns(variant)
local returns = variant.returns
local s = ""
local num = 0
if returns and #returns > 0 then
num = #returns
for i, ret in ipairs(returns) do
if i == 1 then
s = ret.type
else
s = s .. ', ' .. ret.type
end
end
else
s = "void"
end
return s, num
end
local function genFunction(moduleName, fun, static)
local code = safeDesc(fun.description) .. "\n"
local argList = ''
local ordered = {}
for i, variant in ipairs(fun.variants) do
table.insert(ordered, variant)
end
-- Sort variants by number of arguments, then by name
table.sort(ordered, function(a, b)
return #(a.arguments or {}) > #(b.arguments or {})
end)
for vIdx, variant in ipairs(ordered) do
-- args
local arguments = variant.arguments or {}
if vIdx == 1 then
for argIdx, argument in ipairs(arguments) do
if argIdx == 1 then
argList = argument.name
else
argList = argList .. ', ' .. argument.name
end
local type = argument.type
local description = argument.description
if (argument.default) then
type = type .. "?"
description = description .. " (Defaults to " .. argument.default .. ".)"
end
code = code .. '---@param ' .. argument.name .. ' ' .. type .. ' # ' .. description .. '\n'
end
else
code = code .. '---@overload fun('
for argIdx, argument in ipairs(arguments) do
if argIdx == 1 then
code = code .. argument.name .. ':' .. argument.type
if (argument.default) then
code = code .. '?'
end
else
code = code .. ', '
code = code .. argument.name .. ':' .. argument.type
if (argument.default) then
code = code .. '?'
end
end
end
code = code .. '):' .. genReturns(variant)
code = code .. '\n'
end
if vIdx == 1 then
local type, num = genReturns(variant)
if num > 0 then
code = code .. '---@return ' .. type .. '\n'
end
end
end
local dot = static and '.' or ':'
code = code .. "function " .. moduleName .. dot .. fun.name .. "(" .. argList .. ") end\n\n"
return code
end
local function genType(name, type)
local code = safeDesc(type.description) .. '\n'
code = code .. "---@class " .. type.name
if type.supertypes then
code = code .. ' : ' .. table.concat(type.supertypes, ", ")
end
code = code .. '\nlocal ' .. name .. ' = {}\n'
-- functions
if type.functions then
for i, fun in ipairs(type.functions) do
code = code .. genFunction(name, fun, false)
end
end
return code
end
local function genEnum(enum)
-- These'll have to actually be aliases, since LOVE isn't going to expose these or anything.
local code = safeDesc(enum.description) .. '\n'
code = code .. '---@alias ' .. enum.name .. '\n'
for i, const in ipairs(enum.constants) do
code = code .. '---| "' .. const.name .. '" -- ' .. stripNewlines(const.description) .. '\n'
end
code = code .. '\n'
return code
end
local function genModule(name, api)
print("Generating module " .. name)
local f = assert(io.open("api/" .. name .. ".lua", 'w'))
f:write("---@meta\n")
f:write("---@namespace love\n\n")
if api.description then
f:write(safeDesc(api.description) .. '\n')
end
f:write(name .. " = {}\n\n")
-- types
if api.types then
for i, type in ipairs(api.types) do
f:write('--region ' .. type.name .. '\n\n')
f:write(genType(type.name, type))
f:write('--endregion ' .. type.name .. '\n\n')
end
end
-- enums
if api.enums then
for i, enum in ipairs(api.enums) do
f:write(genEnum(enum))
end
end
-- modules
if api.modules then
for i, m in ipairs(api.modules) do
--f:write("---@type " .. name .. '.' .. m.name .. '\n')
--f:write(name .. "." .. m.name .. ' = nil\n\n')
genModule(name .. '.' .. m.name, m)
end
end
-- functions
for i, fun in ipairs(api.functions) do
f:write(genFunction(name, fun, true))
end
-- Add newline at the end of the file
f:close()
end
genModule('love', api)
local completed = os.clock() - time
print("--------")
print('Completed in ' .. (completed * 1000) .. 'ms.')