summaryrefslogtreecommitdiff
path: root/script/vm/global-manager.lua
diff options
context:
space:
mode:
authorAlexCai2019 <89138532+AlexCai2019@users.noreply.github.com>2022-05-08 01:43:28 +0800
committerGitHub <noreply@github.com>2022-05-08 01:43:28 +0800
commit0fd83c4ca9f82a02becab6c304a8a7de75098507 (patch)
treebe9790d9d4823fe728c5b36e94093fe5f42b7725 /script/vm/global-manager.lua
parent89203efad8c9b5513e05ca4d5696107924865b10 (diff)
parent67b4c574849d1667e0ecb39c51aeed8e30b43056 (diff)
downloadlua-language-server-0fd83c4ca9f82a02becab6c304a8a7de75098507.zip
Merge branch 'sumneko:master' into master
Diffstat (limited to 'script/vm/global-manager.lua')
-rw-r--r--script/vm/global-manager.lua364
1 files changed, 0 insertions, 364 deletions
diff --git a/script/vm/global-manager.lua b/script/vm/global-manager.lua
deleted file mode 100644
index f25bb5a0..00000000
--- a/script/vm/global-manager.lua
+++ /dev/null
@@ -1,364 +0,0 @@
-local util = require 'utility'
-local guide = require 'parser.guide'
-local globalBuilder = require 'vm.global'
-local signMgr = require 'vm.sign'
-local genericMgr = require 'vm.generic'
----@class vm
-local vm = require 'vm.vm'
-
----@class parser.object
----@field _globalNode vm.global
-
----@class vm.global-manager
-local m = {}
----@type table<string, vm.global>
-m.globals = {}
----@type table<uri, table<string, boolean>>
-m.globalSubs = util.multiTable(2)
-
-local compilerGlobalSwitch = util.switch()
- : case 'local'
- : call(function (source)
- if source.special ~= '_G' then
- return
- end
- if source.ref then
- for _, ref in ipairs(source.ref) do
- m.compileObject(ref)
- end
- end
- end)
- : case 'getlocal'
- : call(function (source)
- if source.special ~= '_G' then
- return
- end
- if not source.next then
- return
- end
- m.compileObject(source.next)
- end)
- : case 'setglobal'
- : call(function (source)
- local uri = guide.getUri(source)
- local name = guide.getKeyName(source)
- local global = m.declareGlobal('variable', name, uri)
- global:addSet(uri, source)
- source._globalNode = global
- end)
- : case 'getglobal'
- : call(function (source)
- local uri = guide.getUri(source)
- local name = guide.getKeyName(source)
- local global = m.declareGlobal('variable', name, uri)
- global:addGet(uri, source)
- source._globalNode = global
-
- local nxt = source.next
- if nxt then
- m.compileObject(nxt)
- end
- end)
- : case 'setfield'
- : case 'setmethod'
- : case 'setindex'
- ---@param source parser.object
- : call(function (source)
- local name
- local keyName = guide.getKeyName(source)
- if not keyName then
- return
- end
- if source.node._globalNode then
- local parentName = source.node._globalNode:getName()
- if parentName == '_G' then
- name = keyName
- else
- name = ('%s%s%s'):format(parentName, vm.ID_SPLITE, keyName)
- end
- elseif source.node.special == '_G' then
- name = keyName
- end
- if not name then
- return
- end
- local uri = guide.getUri(source)
- local global = m.declareGlobal('variable', name, uri)
- global:addSet(uri, source)
- source._globalNode = global
- end)
- : case 'getfield'
- : case 'getmethod'
- : case 'getindex'
- ---@param source parser.object
- : call(function (source)
- local name
- local keyName = guide.getKeyName(source)
- if not keyName then
- return
- end
- if source.node._globalNode then
- local parentName = source.node._globalNode:getName()
- if parentName == '_G' then
- name = keyName
- else
- name = ('%s%s%s'):format(parentName, vm.ID_SPLITE, keyName)
- end
- elseif source.node.special == '_G' then
- name = keyName
- end
- local uri = guide.getUri(source)
- local global = m.declareGlobal('variable', name, uri)
- global:addGet(uri, source)
- source._globalNode = global
-
- local nxt = source.next
- if nxt then
- m.compileObject(nxt)
- end
- end)
- : case 'call'
- : call(function (source)
- if source.node.special == 'rawset'
- or source.node.special == 'rawget' then
- if not source.args then
- return
- end
- local g = source.args[1]
- local key = source.args[2]
- if g and key and g.special == '_G' then
- local name = guide.getKeyName(key)
- if name then
- local uri = guide.getUri(source)
- local global = m.declareGlobal('variable', name, uri)
- if source.node.special == 'rawset' then
- global:addSet(uri, source)
- source.value = source.args[3]
- else
- global:addGet(uri, source)
- end
- source._globalNode = global
-
- local nxt = source.next
- if nxt then
- m.compileObject(nxt)
- end
- end
- end
- end
- end)
- : case 'doc.class'
- ---@param source parser.object
- : call(function (source)
- local uri = guide.getUri(source)
- local name = guide.getKeyName(source)
- local class = m.declareGlobal('type', name, uri)
- class:addSet(uri, source)
- source._globalNode = class
-
- if source.signs then
- source._sign = signMgr()
- for _, sign in ipairs(source.signs) do
- source._sign:addSign(vm.compileNode(sign))
- end
- if source.extends then
- for _, ext in ipairs(source.extends) do
- if ext.type == 'doc.type.table' then
- ext._generic = genericMgr(ext, source._sign)
- end
- end
- end
- end
- end)
- : case 'doc.alias'
- : call(function (source)
- local uri = guide.getUri(source)
- local name = guide.getKeyName(source)
- local alias = m.declareGlobal('type', name, uri)
- alias:addSet(uri, source)
- source._globalNode = alias
-
- if source.signs then
- source._sign = signMgr()
- for _, sign in ipairs(source.signs) do
- source._sign:addSign(vm.compileNode(sign))
- end
- source.extends._generic = genericMgr(source.extends, source._sign)
- end
- end)
- : case 'doc.type.name'
- : call(function (source)
- local uri = guide.getUri(source)
- local name = source[1]
- local type = m.declareGlobal('type', name, uri)
- type:addGet(uri, source)
- source._globalNode = type
- end)
- : case 'doc.extends.name'
- : call(function (source)
- local uri = guide.getUri(source)
- local name = source[1]
- local class = m.declareGlobal('type', name, uri)
- class:addGet(uri, source)
- source._globalNode = class
- end)
-
-
----@alias vm.global.cate '"variable"' | '"type"'
-
----@param cate vm.global.cate
----@param name string
----@param uri uri
----@return vm.global
-function m.declareGlobal(cate, name, uri)
- local key = cate .. '|' .. name
- m.globalSubs[uri][key] = true
- if not m.globals[key] then
- m.globals[key] = globalBuilder(name, cate)
- end
- return m.globals[key]
-end
-
----@param cate vm.global.cate
----@param name string
----@param field? string
----@return vm.global?
-function m.getGlobal(cate, name, field)
- local key = cate .. '|' .. name
- if field then
- key = key .. vm.ID_SPLITE .. field
- end
- return m.globals[key]
-end
-
----@param cate vm.global.cate
----@param name string
----@return vm.global[]
-function m.getFields(cate, name)
- local globals = {}
- local key = cate .. '|' .. name
-
- -- TODO: optimize
- local clock = os.clock()
- for gid, global in pairs(m.globals) do
- if gid ~= key
- and util.stringStartWith(gid, key)
- and gid:sub(#key + 1, #key + 1) == vm.ID_SPLITE
- and not gid:find(vm.ID_SPLITE, #key + 2) then
- globals[#globals+1] = global
- end
- end
- local cost = os.clock() - clock
- if cost > 0.1 then
- log.warn('global-manager getFields cost %.3f', cost)
- end
-
- return globals
-end
-
----@param cate vm.global.cate
----@return vm.global[]
-function m.getGlobals(cate)
- local globals = {}
-
- -- TODO: optimize
- local clock = os.clock()
- for gid, global in pairs(m.globals) do
- if util.stringStartWith(gid, cate)
- and not gid:find(vm.ID_SPLITE) then
- globals[#globals+1] = global
- end
- end
- local cost = os.clock() - clock
- if cost > 0.1 then
- log.warn('global-manager getGlobals cost %.3f', cost)
- end
-
- return globals
-end
-
----@param suri uri
----@param cate vm.global.cate
----@return parser.object[]
-function m.getGlobalSets(suri, cate)
- local globals = m.getGlobals(cate)
- local result = {}
- for _, global in ipairs(globals) do
- local sets = global:getSets(suri)
- for _, set in ipairs(sets) do
- result[#result+1] = set
- end
- end
- return result
-end
-
----@param suri uri
----@param cate vm.global.cate
----@param name string
----@return boolean
-function m.hasGlobalSets(suri, cate, name)
- local global = m.getGlobal(cate, name)
- if not global then
- return false
- end
- local sets = global:getSets(suri)
- if #sets == 0 then
- return false
- end
- return true
-end
-
----@param source parser.object
-function m.compileObject(source)
- if source._globalNode ~= nil then
- return
- end
- source._globalNode = false
- compilerGlobalSwitch(source.type, source)
-end
-
----@param source parser.object
-function m.compileAst(source)
- local env = guide.getENV(source)
- m.compileObject(env)
- guide.eachSpecialOf(source, 'rawset', function (src)
- m.compileObject(src.parent)
- end)
- guide.eachSpecialOf(source, 'rawget', function (src)
- m.compileObject(src.parent)
- end)
- guide.eachSourceTypes(source.docs, {
- 'doc.class',
- 'doc.alias',
- 'doc.type.name',
- 'doc.extends.name',
- }, function (src)
- m.compileObject(src)
- end)
-end
-
----@return vm.global
-function m.getNode(source)
- if source.type == 'field'
- or source.type == 'method' then
- source = source.parent
- end
- return source._globalNode
-end
-
----@param uri uri
-function m.dropUri(uri)
- local globalSub = m.globalSubs[uri]
- m.globalSubs[uri] = nil
- for key in pairs(globalSub) do
- local global = m.globals[key]
- if global then
- global:dropUri(uri)
- if not global:isAlive() then
- m.globals[key] = nil
- end
- end
- end
-end
-
-return m