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
|
---@param emmy EmmyFunctionType
local function buildEmmyArgs(emmy, object, select)
local start
if object then
start = 2
else
start = 1
end
local strs = {}
local i = 0
emmy:eachParam(function (name, typeObj)
i = i + 1
if i > start then
strs[#strs+1] = ', '
end
if i == select then
strs[#strs+1] = '@ARG'
end
strs[#strs+1] = name .. ': ' .. typeObj:getType()
if i == select then
strs[#strs+1] = '@ARG'
end
end)
local text = table.concat(strs)
local argLabel = {}
for i = 1, 2 do
local pos = text:find('@ARG', 1, true)
if pos then
if i == 1 then
argLabel[i] = pos
else
argLabel[i] = pos - 1
end
text = text:sub(1, pos-1) .. text:sub(pos+4)
end
end
if #argLabel == 0 then
argLabel = nil
end
return text, argLabel
end
local function buildEmmyReturns(emmy)
local rtns = {}
emmy:eachReturn(function (rtn)
rtns[#rtns+1] = rtn:getType()
end)
if #rtns == 0 then
return '\n -> ' .. 'any'
else
return '\n -> ' .. table.concat(rtns, ', ')
end
end
local function buildEnum(lib)
if not lib.enums then
return ''
end
local container = table.container()
for _, enum in ipairs(lib.enums) do
if not enum.name or (not enum.enum and not enum.code) then
goto NEXT_ENUM
end
if not container[enum.name] then
container[enum.name] = {}
if lib.args then
for _, arg in ipairs(lib.args) do
if arg.name == enum.name then
container[enum.name].type = arg.type
break
end
end
end
if lib.returns then
for _, rtn in ipairs(lib.returns) do
if rtn.name == enum.name then
container[enum.name].type = rtn.type
break
end
end
end
end
table.insert(container[enum.name], enum)
::NEXT_ENUM::
end
local strs = {}
for name, enums in pairs(container) do
local tp
if type(enums.type) == 'table' then
tp = table.concat(enums.type, '/')
else
tp = enums.type
end
strs[#strs+1] = ('\n%s: %s'):format(name, tp or 'any')
for _, enum in ipairs(enums) do
if enum.default then
strs[#strs+1] = '\n -> '
else
strs[#strs+1] = '\n | '
end
if enum.code then
strs[#strs+1] = tostring(enum.code)
else
strs[#strs+1] = ('%q'):format(enum.enum)
end
if enum.description then
strs[#strs+1] = ' -- ' .. enum.description
end
end
end
return table.concat(strs)
end
return function (name, emmy, object, select)
local args, argLabel = buildEmmyArgs(emmy, object, select)
local returns = buildEmmyReturns(emmy)
local enum = buildEnum(emmy)
local tip = emmy.description
local headLen = #('function %s('):format(name)
local title = ('function %s(%s)%s'):format(name, args, returns)
if argLabel then
argLabel[1] = argLabel[1] + headLen
argLabel[2] = argLabel[2] + headLen
end
return {
label = title,
description = tip,
enum = enum,
argLabel = argLabel,
}
end
|