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
|
local guide = require 'parser.guide'
local vm = require 'vm'
local function mergeTypesInLibrary(types)
if type(types) == 'table' then
return table.concat(types, '|')
else
return types or 'any'
end
end
local function asLibrary(source, oop)
if not source.args then
return ''
end
local start = 1
local methodDef
local parent = source.parent
if parent and parent.type == 'setmethod' then
methodDef = true
end
if not methodDef and oop then
start = 2
end
local args = {}
local afterCount = 0
for i = start, #source.args do
local buf = {}
local arg = source.args[i]
local name = arg.name
if arg.optional then
if i == start then
buf[#buf+1] = '['
else
buf[#buf+1] = ' ['
end
end
if i > start then
buf[#buf+1] = ', '
end
if name then
buf[#buf+1] = ('%s: %s'):format(name, mergeTypesInLibrary(arg.type))
else
buf[#buf+1] = ('%s'):format(mergeTypesInLibrary(arg.type))
end
if arg.optional == 'after' then
afterCount = afterCount + 1
elseif arg.optional == 'self' then
buf[#buf+1] = ']'
end
if i == #source.args and afterCount > 0 then
buf[#buf+1] = (']'):rep(afterCount)
end
args[#args+1] = table.concat(buf)
end
return table.concat(args)
end
local function optionalArg(arg)
if not arg.bindDocs then
return false
end
local name = arg[1]
for _, doc in ipairs(arg.bindDocs) do
if doc.type == 'doc.param' and doc.param[1] == name then
return doc.optional
end
end
end
local function asFunction(source, oop)
if not source.args then
return ''
end
local args = {}
for i = 1, #source.args do
local arg = source.args[i]
local name = arg.name or guide.getName(arg)
if name then
args[i] = ('%s: %s%s'):format(
name,
vm.getInferType(arg),
optionalArg(arg) and '?' or ''
)
else
args[i] = ('%s'):format(vm.getInferType(arg))
end
end
local methodDef
local parent = source.parent
if parent and parent.type == 'setmethod' then
methodDef = true
end
if not methodDef and oop then
return table.concat(args, ', ', 2)
else
return table.concat(args, ', ')
end
end
local function asDocFunction(source)
if not source.args then
return ''
end
local args = {}
for i = 1, #source.args do
local arg = source.args[i]
local name = arg.name[1]
args[i] = ('%s: %s%s'):format(
name,
vm.getInferType(arg.extends),
arg.optional and '?' or ''
)
end
return table.concat(args, ', ')
end
return function (source, oop)
if source.type == 'library' then
return asLibrary(source.value, oop)
elseif source.library then
return asLibrary(source, oop)
end
if source.type == 'function' then
return asFunction(source, oop)
end
if source.type == 'doc.type.function' then
return asDocFunction(source)
end
return ''
end
|