summaryrefslogtreecommitdiff
path: root/script-beta/vm/eachField.lua
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-12-20 18:08:11 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-12-20 18:08:11 +0800
commitb02922cb72d175501bf41fe5c7d3e7c71d71b0b6 (patch)
treefee38471f244fb7be7f3766a9ab35fe62e43139b /script-beta/vm/eachField.lua
parent2213f1332859562505a39a85cebb14d11265f95f (diff)
downloadlua-language-server-b02922cb72d175501bf41fe5c7d3e7c71d71b0b6.zip
暂存
Diffstat (limited to 'script-beta/vm/eachField.lua')
-rw-r--r--script-beta/vm/eachField.lua241
1 files changed, 52 insertions, 189 deletions
diff --git a/script-beta/vm/eachField.lua b/script-beta/vm/eachField.lua
index 79793389..c776f546 100644
--- a/script-beta/vm/eachField.lua
+++ b/script-beta/vm/eachField.lua
@@ -1,211 +1,74 @@
local guide = require 'parser.guide'
-local vm = require 'vm.vm'
local files = require 'files'
-local await = require 'await'
-local library = require 'library'
+local vm = require 'vm.vm'
-local function ofTabel(value, callback)
- if value.library then
- if value.child then
- for k, field in pairs(value.child) do
- callback {
- source = field,
- key = 's|' .. k,
- value = field,
- mode = 'set',
- }
- end
- end
- else
- for _, field in ipairs(value) do
- if field.type == 'tablefield'
- or field.type == 'tableindex' then
- callback {
- source = field,
- key = guide.getKeyName(field),
- value = field.value,
- mode = 'set',
- }
- end
- end
+local function checkNext(source)
+ local nextSrc = source.next
+ if not nextSrc then
+ return nil
+ end
+ local ntype = nextSrc.type
+ if ntype == 'setfield'
+ or ntype == 'setmethod'
+ or ntype == 'setindex' then
+ return nextSrc, 'set'
+ elseif ntype == 'getfield'
+ or ntype == 'getmethod'
+ or ntype == 'getindex' then
+ return nextSrc, 'get'
end
+ return nil
end
local function ofENV(source, callback)
- if source.type == 'getlocal' then
- local parent = source.parent
- if parent.type == 'getfield'
- or parent.type == 'getmethod'
- or parent.type == 'getindex' then
- callback {
- source = parent,
- key = guide.getKeyName(parent),
- mode = 'get',
- }
- end
- elseif source.type == 'getglobal' then
- callback {
- source = source,
- key = guide.getKeyName(source),
- mode = 'get',
- }
- elseif source.type == 'setglobal' then
- callback {
- source = source,
- key = guide.getKeyName(source),
- mode = 'set',
- value = source.value,
- }
+ local refs = source.ref
+ if not refs then
+ return
end
-end
-
-local function ofSpecialArg(source, callback)
- local args = source.parent
- local call = args.parent
- local func = call.node
- local name = func.special
- if name == 'rawset' then
- if args[1] == source and args[2] then
+ for i = 1, #refs do
+ local ref = refs[i]
+ if ref.type == 'getglobal' then
callback {
- source = call,
- key = guide.getKeyName(args[2]),
- value = args[3],
- mode = 'set',
+ source = ref,
+ key = guide.getKeyName(ref),
+ mode = 'get',
}
- end
- elseif name == 'rawget' then
- if args[1] == source and args[2] then
+ elseif ref.type == 'setglobal' then
callback {
- source = call,
- key = guide.getKeyName(args[2]),
- mode = 'get',
+ source = ref,
+ key = guide.getKeyName(ref),
+ mode = 'set',
}
end
- elseif name == 'setmetatable' then
- if args[1] == source and args[2] then
- vm.eachField(args[2], function (info)
- if info.key == 's|__index' and info.value then
- vm.eachField(info.value, callback)
- end
- end)
- end
end
end
-local function ofVar(source, callback)
- local parent = source.parent
- if not parent then
- return
- end
- if parent.type == 'getfield'
- or parent.type == 'getmethod'
- or parent.type == 'getindex' then
- callback {
- source = parent,
- key = guide.getKeyName(parent),
- mode = 'get',
- }
- return
- end
- if parent.type == 'setfield'
- or parent.type == 'setmethod'
- or parent.type == 'setindex' then
- callback {
- source = parent,
- key = guide.getKeyName(parent),
- value = parent.value,
- mode = 'set',
- }
- return
- end
- if parent.type == 'callargs' then
- ofSpecialArg(source, callback)
- end
-end
-
-local function eachField(source, callback)
- vm.eachRef(source, function (info)
- local src = info.source
- if src.tag == '_ENV' then
- if src.ref then
- for _, ref in ipairs(src.ref) do
- ofENV(ref, callback)
- end
- end
- for name, lib in pairs(library.global) do
- callback {
- source = lib,
- key = 's|' .. name,
- mode = 'value',
- }
- end
- elseif src.type == 'getlocal'
- or src.type == 'getglobal'
- or src.type == 'getfield'
- or src.type == 'getmethod'
- or src.type == 'getindex' then
- ofVar(src, callback)
- elseif src.type == 'field'
- or src.type == 'method' then
- ofVar(src.parent, callback)
- elseif src.type == 'table' then
- ofTabel(src, callback)
- end
- local lib = library.object[src.type]
- if lib then
- for k, v in pairs(lib.child) do
- callback {
- source = v,
- key = 's|' .. k,
- mode = 'value',
- }
+local function ofLocal(source, callback)
+ if source.tag == '_ENV' then
+ ofENV(source, callback)
+ else
+ vm.eachRef(source, function (info)
+ local src = info.source
+ local nextSrc, mode = checkNext(src)
+ if not nextSrc then
+ return
end
- end
- end)
+ callback {
+ source = nextSrc,
+ key = guide.getKeyName(nextSrc),
+ mode = mode,
+ }
+ end)
+ end
end
---- 获取所有的field
function vm.eachField(source, callback)
- local cache = vm.cache.eachField[source]
- if cache then
- await.delay(function ()
- return files.globalVersion
- end)
- for i = 1, #cache do
- local res = callback(cache[i])
- if res ~= nil then
- return res
- end
- end
- return
- end
- local unlock = vm.lock('eachField', source)
- if not unlock then
- return
- end
- cache = {}
- vm.cache.eachField[source] = cache
- local mark = {}
- eachField(source, function (info)
- local src = info.source
- if mark[src] then
- return
- end
- mark[src] = true
- cache[#cache+1] = info
- end)
- unlock()
- vm.eachRef(source, function (info)
- local src = info.source
- vm.cache.eachField[src] = cache
- end)
- await.delay(function ()
- return files.globalVersion
- end)
- for i = 1, #cache do
- local res = callback(cache[i])
- if res ~= nil then
- return res
- end
+ local stype = source.type
+ if stype == 'local' then
+ ofLocal(source, callback)
+ elseif stype == 'getlocal'
+ or stype == 'setlocal' then
+ ofLocal(source.node, callback)
+ elseif stype == 'getglobal' then
end
end