summaryrefslogtreecommitdiff
path: root/script-beta/core/hover/arg.lua
blob: 5dcf94b66166cbf250b6056c459ff6ab52254240 (plain)
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
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 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'):format(name, vm.getInferType(arg))
        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'):format(name, vm.getInferType(arg.extends))
    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