dotfiles from arch
This commit is contained in:
119
nvim/mason/packages/lua-language-server/libexec/script/vm/vm.lua
Normal file
119
nvim/mason/packages/lua-language-server/libexec/script/vm/vm.lua
Normal file
@@ -0,0 +1,119 @@
|
||||
local guide = require 'parser.guide'
|
||||
local files = require 'files'
|
||||
local timer = require 'timer'
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local log = log
|
||||
local xpcall = xpcall
|
||||
local mathHuge = math.huge
|
||||
|
||||
local weakMT = { __mode = 'kv' }
|
||||
|
||||
---@class vm
|
||||
local m = {}
|
||||
|
||||
m.ID_SPLITE = '\x1F'
|
||||
|
||||
function m.getSpecial(source)
|
||||
if not source then
|
||||
return nil
|
||||
end
|
||||
return source.special
|
||||
end
|
||||
|
||||
---@param source parser.object
|
||||
---@return string?
|
||||
function m.getKeyName(source)
|
||||
if not source then
|
||||
return nil
|
||||
end
|
||||
if source.type == 'call' then
|
||||
local special = m.getSpecial(source.node)
|
||||
if special == 'rawset'
|
||||
or special == 'rawget' then
|
||||
return guide.getKeyNameOfLiteral(source.args[2])
|
||||
end
|
||||
end
|
||||
return guide.getKeyName(source)
|
||||
end
|
||||
|
||||
function m.getKeyType(source)
|
||||
if not source then
|
||||
return nil
|
||||
end
|
||||
if source.type == 'call' then
|
||||
local special = m.getSpecial(source.node)
|
||||
if special == 'rawset'
|
||||
or special == 'rawget' then
|
||||
return guide.getKeyTypeOfLiteral(source.args[2])
|
||||
end
|
||||
end
|
||||
return guide.getKeyType(source)
|
||||
end
|
||||
|
||||
---@param source parser.object
|
||||
---@return parser.object?
|
||||
function m.getObjectValue(source)
|
||||
if source.value then
|
||||
return source.value
|
||||
end
|
||||
if source.special == 'rawset' then
|
||||
return source.args and source.args[3]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---@param source parser.object
|
||||
---@return parser.object?
|
||||
function m.getObjectFunctionValue(source)
|
||||
local value = m.getObjectValue(source)
|
||||
if value == nil then return end
|
||||
if value.type == 'function' or value.type == 'doc.type.function' then
|
||||
return value
|
||||
end
|
||||
if value.type == 'getlocal' then
|
||||
return m.getObjectFunctionValue(value.node)
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
m.cacheTracker = setmetatable({}, weakMT)
|
||||
|
||||
function m.flushCache()
|
||||
if m.cache then
|
||||
m.cache.dead = true
|
||||
end
|
||||
m.cacheVersion = files.globalVersion
|
||||
m.cache = {}
|
||||
m.cacheActiveTime = mathHuge
|
||||
m.locked = setmetatable({}, weakMT)
|
||||
m.cacheTracker[m.cache] = true
|
||||
end
|
||||
|
||||
function m.getCache(name, weak)
|
||||
if m.cacheVersion ~= files.globalVersion then
|
||||
m.flushCache()
|
||||
end
|
||||
m.cacheActiveTime = timer.clock()
|
||||
if not m.cache[name] then
|
||||
m.cache[name] = weak and setmetatable({}, weakMT) or {}
|
||||
end
|
||||
return m.cache[name]
|
||||
end
|
||||
|
||||
local function init()
|
||||
m.flushCache()
|
||||
|
||||
-- 可以在一段时间不活动后清空缓存,不过目前看起来没有必要
|
||||
--timer.loop(1, function ()
|
||||
-- if timer.clock() - m.cacheActiveTime > 10.0 then
|
||||
-- log.info('Flush cache: Inactive')
|
||||
-- m.flushCache()
|
||||
-- collectgarbage()
|
||||
-- end
|
||||
--end)
|
||||
end
|
||||
|
||||
xpcall(init, log.error)
|
||||
|
||||
return m
|
||||
Reference in New Issue
Block a user