summaryrefslogtreecommitdiff
path: root/server/src/core/references.lua
blob: d07e48c7b75d6c7fa106ec484760eb35864450f3 (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
local findSource = require 'core.find_source'

local function parseResult(vm, source, declarat, callback)
    local isGlobal
    if source:bindLabel() then
        source:bindLabel():eachInfo(function (info, src)
            if (declarat and info.type == 'set') or info.type == 'get' then
                callback(src)
            end
        end)
    end
    if source:bindLocal() then
        local loc = source:bindLocal()
        callback(loc:getSource())
        loc:eachInfo(function (info, src)
            if (declarat and info.type == 'set') or info.type == 'get' then
                callback(src)
            end
        end)
        loc:getValue():eachInfo(function (info, src)
            if (declarat and (info.type == 'set' or info.type == 'local' or info.type == 'return')) or info.type == 'get' then
                callback(src)
            end
        end)
    end
    if source:bindFunction() then
        if declarat then
            callback(source:bindFunction():getSource())
        end
        source:bindFunction():eachInfo(function (info, src)
            if (declarat and (info.type == 'set' or info.type == 'local')) or info.type == 'get' then
                callback(src)
            end
        end)
    end
    if source:bindValue() then
        source:bindValue():eachInfo(function (info, src)
            if (declarat and (info.type == 'set' or info.type == 'local')) or info.type == 'get' then
                callback(src)
            end
        end)
        if source:bindValue():isGlobal() then
            isGlobal = true
        end
    end
    local parent = source:get 'parent'
    if parent then
        parent:eachInfo(function (info, src)
            if info[1] == source[1] then
                if (declarat and info.type == 'set child') or info.type == 'get child' then
                    callback(src)
                end
            end
        end)
    end
    return isGlobal
end

return function (vm, pos, declarat)
    local source = findSource(vm, pos)
    if not source then
        return nil
    end
    local positions = {}
    local mark = {}
    local isGlobal = parseResult(vm, source, declarat, function (src)
        if mark[src] then
            return
        end
        mark[src] = true
        if src.start == 0 then
            return
        end
        local uri = src.uri
        if uri == '' then
            uri = nil
        end
        positions[#positions+1] = {
            src.start,
            src.finish,
            uri,
        }
    end)
    return positions, isGlobal
end