summaryrefslogtreecommitdiff
path: root/script-beta/vm/getGlobals.lua
blob: 9d51ec313a79d5eb7ed655f4c9be8f2da72f8b5f (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
112
113
local guide   = require 'parser.guide'
local vm      = require 'vm.vm'
local files   = require 'files'
local library = require 'library'
local util    = require 'utility'
local config  = require 'config'

local function getGlobalsOfFile(uri)
    local globals = {}
    local ast = files.getAst(uri)
    if not ast then
        return globals
    end
    local results = guide.findGlobals(ast.ast)
    local mark = {}
    for _, res in ipairs(results) do
        if mark[res] then
            goto CONTINUE
        end
        mark[res] = true
        local name = guide.getSimpleName(res)
        if name then
            if not globals[name] then
                globals[name] = {}
            end
            globals[name][#globals[name]+1] = res
        end
        ::CONTINUE::
    end
    return globals
end

local function insertLibrary(results, name)
    if name:sub(1, 2) == 's|' then
        local libname = name:sub(3)
        results[#results+1] = library.global[libname]
        local asName = config.config.runtime.special[libname]
        results[#results+1] = library.global[asName]
    elseif name == '*' then
        for _, lib in pairs(library.global) do
            results[#results+1] = lib
        end
    end
end

local function getGlobals(name)
    local results = {}
    for uri in files.eachFile() do
        local cache = files.getCache(uri)
        cache.globals = cache.globals or getGlobalsOfFile(uri)
        if name == '*' then
            for _, sources in util.sortPairs(cache.globals) do
                for _, source in ipairs(sources) do
                    results[#results+1] = source
                end
            end
        else
            if cache.globals[name] then
                for _, source in ipairs(cache.globals[name]) do
                    results[#results+1] = source
                end
            end
        end
    end
    insertLibrary(results, name)
    return results
end

local function getAnyGlobalsFast()
    local results = {}
    local mark = {}
    for uri in files.eachFile() do
        local cache = files.getCache(uri)
        cache.globals = cache.globals or getGlobalsOfFile(uri)
        for destName, sources in util.sortPairs(cache.globals) do
            if not mark[destName] then
                mark[destName] = true
                results[#results+1] = sources[1]
            end
        end
    end
    insertLibrary(results, '*')
    return results
end

function vm.getGlobals(key)
    if key == '*' and config.config.intelliSense.fastGlobal then
        return getAnyGlobalsFast()
    end
    local cache = vm.getCache('getGlobals')[key]
    if cache ~= nil then
        return cache
    end
    cache = getGlobals(key)
    vm.getCache('getGlobals')[key] = cache
    return cache
end

function vm.getGlobalSets(name)
    local cache = vm.getCache('getGlobalSets')[name]
    if cache ~= nil then
        return cache
    end
    cache = {}
    local refs = getGlobals(name)
    for _, source in ipairs(refs) do
        if vm.isSet(source) then
            cache[#cache+1] = source
        end
    end
    vm.getCache('getGlobalSets')[name] = cache
    return cache
end