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
|
local fs = require 'bee.filesystem'
local config = require 'config'
local util = require 'utility'
local await = require 'await'
local m = {}
---@class meta
---@field root string
---@field classes meta.class[]
---@class meta.class
---@field name string
---@field comment string
---@field location string
---@field namespace string
---@field baseClass string
---@field attribute string
---@field integerface string[]
---@field fields meta.field[]
---@field methods meta.method[]
---@class meta.field
---@field name string
---@field typeName string
---@field comment string
---@field location string
---@class meta.method
---@field name string
---@field comment string
---@field location string
---@field isStatic boolean
---@field returnTypeName string
---@field params {name: string, typeName: string}[]
---@param ... string
---@return string
local function mergeString(...)
local buf = {}
for i = 1, select('#', ...) do
local str = select(i, ...)
if str ~= '' then
buf[#buf+1] = str
end
end
return table.concat(buf, '.')
end
local function addComments(lines, comment)
if comment == '' then
return
end
lines[#lines+1] = '--'
lines[#lines+1] = '--' .. comment:gsub('[\r\n]+$', ''):gsub('\n', '\n--')
lines[#lines+1] = '--'
end
---@param lines string[]
---@param name string
---@param method meta.method
local function addMethod(lines, name, method)
if not method.name:match '^[%a_][%w_]*$' then
return
end
addComments(lines, method.comment)
local params = {}
for _, param in ipairs(method.params) do
lines[#lines+1] = ('---@param %s %s'):format(param.name, param.typeName)
params[#params+1] = param.name
end
if method.returnTypeName ~= ''
and method.returnTypeName ~= 'Void' then
lines[#lines+1] = ('---@return %s'):format(method.returnTypeName)
end
lines[#lines+1] = ('function %s%s%s(%s) end'):format(
name,
method.isStatic and ':' or '.',
method.name,
table.concat(params, ', ')
)
lines[#lines+1] = ''
end
---@param root string
---@param class meta.class
---@return string
local function buildText(root, class)
local lines = {}
addComments(lines, class.comment)
if class.baseClass == '' then
lines[#lines+1] = ('---@class %s'):format(mergeString(class.namespace, class.name))
else
lines[#lines+1] = ('---@class %s: %s'):format(mergeString(class.namespace, class.name), class.baseClass)
end
for _, field in ipairs(class.fields) do
addComments(lines, field.comment)
lines[#lines+1] = ('---@source %s'):format(field.location:gsub('#', ':'))
lines[#lines+1] = ('---@field %s %s'):format(field.name, field.typeName)
end
local name = mergeString(root, class.namespace, class.name)
lines[#lines+1] = ('%s = {}'):format(name)
lines[#lines+1] = ''
for _, method in ipairs(class.methods) do
addMethod(lines, name, method)
end
return table.concat(lines, '\n')
end
local function buildRootText(api)
local lines = {}
lines[#lines+1] = ('---@class %s'):format(api.root)
lines[#lines+1] = ('%s = {}'):format(api.root)
lines[#lines+1] = ''
return table.concat(lines, '\n')
end
---@async
---@param name string
---@param api meta
---@return string
function m.build(name, api)
local encoding = config.get(nil, 'Lua.runtime.fileEncoding')
local fileDir = fs.path(METAPATH) / (name .. ' ' .. encoding)
fs.create_directories(fileDir)
local files = util.multiTable(2, function ()
return { '---@meta' }
end)
files[api.root][#files[api.root]+1] = buildRootText(api)
for _, class in ipairs(api.classes) do
local space = class.namespace ~= '' and class.namespace or api.root
local text = buildText(api.root, class)
files[space][#files[space]+1] = text
await.delay()
end
for space, texts in pairs(files) do
util.saveFile((fileDir / (space .. '.lua')):string(), table.concat(texts, '\n\n'))
end
return fileDir:string()
end
return m
|