diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-10-23 17:31:02 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-10-23 17:31:02 +0800 |
commit | 4248038716c6c2281a10af9c0a3f04c6468b1946 (patch) | |
tree | 79361f8df2cf46ab99843e84bba175ea60147da2 /server-beta/src/searcher-old | |
parent | 68541432820dfff4554375c4c424a537943a938d (diff) | |
download | lua-language-server-4248038716c6c2281a10af9c0a3f04c6468b1946.zip |
准备换一个写法试试
Diffstat (limited to 'server-beta/src/searcher-old')
-rw-r--r-- | server-beta/src/searcher-old/boolean.lua | 43 | ||||
-rw-r--r-- | server-beta/src/searcher-old/field.lua | 38 | ||||
-rw-r--r-- | server-beta/src/searcher-old/getfield.lua | 77 | ||||
-rw-r--r-- | server-beta/src/searcher-old/getglobal.lua | 157 | ||||
-rw-r--r-- | server-beta/src/searcher-old/getlocal.lua | 23 | ||||
-rw-r--r-- | server-beta/src/searcher-old/goto.lua | 16 | ||||
-rw-r--r-- | server-beta/src/searcher-old/index.lua | 3 | ||||
-rw-r--r-- | server-beta/src/searcher-old/init.lua | 400 | ||||
-rw-r--r-- | server-beta/src/searcher-old/label.lua | 3 | ||||
-rw-r--r-- | server-beta/src/searcher-old/local.lua | 179 | ||||
-rw-r--r-- | server-beta/src/searcher-old/method.lua | 37 | ||||
-rw-r--r-- | server-beta/src/searcher-old/methods.lua | 26 | ||||
-rw-r--r-- | server-beta/src/searcher-old/number.lua | 43 | ||||
-rw-r--r-- | server-beta/src/searcher-old/select.lua | 34 | ||||
-rw-r--r-- | server-beta/src/searcher-old/setmetatable.lua | 63 | ||||
-rw-r--r-- | server-beta/src/searcher-old/string.lua | 43 | ||||
-rw-r--r-- | server-beta/src/searcher-old/table.lua | 30 | ||||
-rw-r--r-- | server-beta/src/searcher-old/tablefield.lua | 19 |
18 files changed, 1234 insertions, 0 deletions
diff --git a/server-beta/src/searcher-old/boolean.lua b/server-beta/src/searcher-old/boolean.lua new file mode 100644 index 00000000..f92670e1 --- /dev/null +++ b/server-beta/src/searcher-old/boolean.lua @@ -0,0 +1,43 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachDef(source, callback) + local parent = source.parent + if not parent then + return + end + if parent.type ~= 'setindex' and parent.type ~= 'getindex' then + return + end + local node = parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' then + callback(info) + end + end) +end + +function m:eachRef(source, callback) + local parent = source.parent + if not parent then + return + end + if parent.type ~= 'setindex' and parent.type ~= 'getindex' then + return + end + local node = parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' or info.mode == 'get' then + callback(info) + end + end) +end + +function m:getValue(source) + return source +end + +return m diff --git a/server-beta/src/searcher-old/field.lua b/server-beta/src/searcher-old/field.lua new file mode 100644 index 00000000..c5667b04 --- /dev/null +++ b/server-beta/src/searcher-old/field.lua @@ -0,0 +1,38 @@ +local guide = require 'parser.guide' +local checkSMT = require 'searcher.setmetatable' + +local m = {} + +function m:eachDef(source, callback) + local parent = source.parent + local key = guide.getKeyName(source) + self:eachField(parent, key, function (info) + if info.mode == 'set' then + callback(info) + end + end) +end + +function m:eachRef(source, callback) + local parent = source.parent + local key = guide.getKeyName(source) + self:eachField(parent, key, function (info) + if info.mode == 'set' or info.mode == 'set' then + callback(info) + end + end) +end + +function m:eachField(source, key, callback) + self:eachField(source.parent, key, callback) +end + +function m:eachValue(source, callback) + self:eachValue(source.parent, callback) +end + +function m:getValue(source) + return self:getValue(source.parent) +end + +return m diff --git a/server-beta/src/searcher-old/getfield.lua b/server-beta/src/searcher-old/getfield.lua new file mode 100644 index 00000000..2fcd2d4b --- /dev/null +++ b/server-beta/src/searcher-old/getfield.lua @@ -0,0 +1,77 @@ +local guide = require 'parser.guide' +local checkSMT = require 'searcher.setmetatable' + +local m = {} + +function m:eachRef(source, callback) + local node = source.node + if node.type == 'setfield' + or node.type == 'getfield' + or node.type == 'setmethod' + or node.type == 'getmethod' + or node.type == 'setindex' + or node.type == 'getindex' then + local key = guide.getKeyName(node) + self:eachField(node.node, key, function (info) + if info.mode == 'set' or info.mode == 'get' then + callback(info) + end + end) + else + self:eachRef(node, callback) + end +end + +function m:eachField(source, key, callback) + local used = {} + local found = false + used[source] = true + + self:eachRef(source, function (info) + local src = info.source + used[src] = true + local child, mode, value = self:childMode(src) + if child then + if key == guide.getKeyName(child) then + callback { + uri = self.uri, + source = child, + mode = mode, + } + end + if value then + info.searcher:eachField(value, key, callback) + end + return + end + if src.type == 'getglobal' then + local parent = src.parent + child, mode = info.searcher:childMode(parent) + if child then + if key == guide.getKeyName(child) then + callback { + uri = self.uri, + source = child, + mode = mode, + } + end + end + elseif src.type == 'setglobal' then + info.searcher:eachField(src.value, key, callback) + else + info.searcher:eachField(src, key, callback) + end + end) + + checkSMT(self, key, used, found, callback) +end + +function m:getValue(source) + if source.type == 'setfield' + or source.type == 'setmethod' + or source.type == 'setindex' then + return source.value and self:getValue(source.value) + end +end + +return m diff --git a/server-beta/src/searcher-old/getglobal.lua b/server-beta/src/searcher-old/getglobal.lua new file mode 100644 index 00000000..1295d769 --- /dev/null +++ b/server-beta/src/searcher-old/getglobal.lua @@ -0,0 +1,157 @@ +local guide = require 'parser.guide' +local checkSMT = require 'searcher.setmetatable' + +local m = {} + +function m:eachDef(source, callback) + -- _ENV + local key = guide.getKeyName(source) + self:eachField(source.node, key, function (info) + if info.mode == 'set' then + callback(info) + end + end) + self:eachSpecial(function (name, src) + if name == '_G' then + local parent = src.parent + if guide.getKeyName(parent) == key then + callback { + source = parent, + uri = self.uri, + mode = 'set', + } + end + elseif name == 'rawset' then + local t, k = self:callArgOf(src.parent) + if self:getSpecialName(t) == '_G' + and guide.getKeyName(k) == key then + callback { + source = src.parent, + uri = self.uri, + mode = 'set', + } + end + end + end) +end + +function m:eachRef(source, callback) + -- _ENV + local key = guide.getKeyName(source) + self:eachField(source.node, key, function (info) + if info.mode == 'set' or info.mode == 'get' then + callback(info) + end + end) + self:eachSpecial(function (name, src) + if name == '_G' then + local parent = src.parent + if guide.getKeyName(parent) == key then + if parent.type:sub(1, 3) == 'set' then + callback { + source = parent, + uri = self.uri, + mode = 'set', + } + else + callback { + source = parent, + uri = self.uri, + mode = 'get', + } + end + end + elseif name == 'rawset' then + local t, k = self:callArgOf(src.parent) + if self:getSpecialName(t) == '_G' + and guide.getKeyName(k) == key then + callback { + source = src.parent, + uri = self.uri, + mode = 'set', + } + end + elseif name == 'rawget' then + local t, k = self:callArgOf(src.parent) + if self:getSpecialName(t) == '_G' + and guide.getKeyName(k) == key then + callback { + source = src.parent, + uri = self.uri, + mode = 'set', + } + end + end + end) +end + +function m:eachField(source, key, callback) + local used = {} + local found = false + used[source] = true + + self:eachRef(source, function (info) + local src = info.source + used[src] = true + local child, mode, value = info.searcher:childMode(src) + if child then + if key == guide.getKeyName(child) then + callback { + source = child, + uri = info.uri, + mode = mode, + } + end + if value then + info.searcher:eachField(value, key, callback) + end + return + end + if src.type == 'getglobal' then + local parent = src.parent + child, mode, value = info.searcher:childMode(parent) + if child then + if key == guide.getKeyName(child) then + callback { + source = child, + uri = info.uri, + mode = mode, + } + end + if value then + info.searcher:eachField(value, key, callback) + end + end + elseif src.type == 'setglobal' then + info.searcher:eachField(src.value, key, callback) + else + info.searcher:eachField(src, key, callback) + end + end) + + checkSMT(self, key, used, found, callback) +end + +function m:eachValue(source, callback) + callback { + source = source, + uri = self.uri, + } + self:eachDef(source, function (info) + local src = info.source + if src.value then + callback { + source = src.value, + uri = info.uri, + } + end + end) +end + +function m:getValue(source) + if source.type == 'setglobal' then + return source.value and self:getValue(source.value) + end +end + +return m diff --git a/server-beta/src/searcher-old/getlocal.lua b/server-beta/src/searcher-old/getlocal.lua new file mode 100644 index 00000000..4ffc871f --- /dev/null +++ b/server-beta/src/searcher-old/getlocal.lua @@ -0,0 +1,23 @@ +local m = {} + +function m:eachDef(source, callback) + self:eachDef(source.loc, callback) +end + +function m:eachRef(source, callback) + self:eachRef(source.loc, callback) +end + +function m:eachField(source, key, callback) + self:eachField(source.loc, key, callback) +end + +function m:eachValue(source, callback) + self:eachValue(source.loc, callback) +end + +function m:getValue(source) + return self:getValue(source.loc) +end + +return m diff --git a/server-beta/src/searcher-old/goto.lua b/server-beta/src/searcher-old/goto.lua new file mode 100644 index 00000000..8698eef1 --- /dev/null +++ b/server-beta/src/searcher-old/goto.lua @@ -0,0 +1,16 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachDef(source, callback) + local name = source[1] + local label = guide.getLabel(source, name) + if label then + callback { + source = label, + uri = self.uri, + } + end +end + +return m diff --git a/server-beta/src/searcher-old/index.lua b/server-beta/src/searcher-old/index.lua new file mode 100644 index 00000000..f05a57e6 --- /dev/null +++ b/server-beta/src/searcher-old/index.lua @@ -0,0 +1,3 @@ +local m = {} + +return m diff --git a/server-beta/src/searcher-old/init.lua b/server-beta/src/searcher-old/init.lua new file mode 100644 index 00000000..b5f0a3f8 --- /dev/null +++ b/server-beta/src/searcher-old/init.lua @@ -0,0 +1,400 @@ +local guide = require 'parser.guide' +local files = require 'files' +local methods = require 'searcher.methods' +local tableUnpack = table.unpack +local error = error +local setmetatable = setmetatable +local assert = assert + +_ENV = nil +local specials = { + ['_G'] = true, + ['rawset'] = true, + ['rawget'] = true, + ['setmetatable'] = true, + ['require'] = true, + ['dofile'] = true, + ['loadfile'] = true, +} + +---@class searcher_old +local mt = {} +mt.__index = mt +mt.__name = 'searcher' + +--- 获取特殊对象的名字 +function mt:getSpecialName(source) + local spName = self.cache.specialName[source] + if spName ~= nil then + if spName then + return spName + end + return nil + end + local function getName(info) + local src = info.source + if src.type == 'getglobal' then + local node = src.node + if node.tag ~= '_ENV' then + return nil + end + local name = guide.getKeyName(src) + if name:sub(1, 2) ~= 's|' then + return nil + end + spName = name:sub(3) + if not specials[spName] then + spName = nil + end + elseif src.type == 'local' then + if src.tag == '_ENV' then + spName = '_G' + end + elseif src.type == 'getlocal' then + local loc = src.loc + if loc.tag == '_ENV' then + spName = '_G' + end + end + end + self:eachValue(source, getName) + self.cache.specialName[source] = spName or false + return spName +end + +--- 遍历特殊对象 +---@param callback fun(name:string, source:table) +function mt:eachSpecial(callback) + local cache = self.cache.special + if cache then + for i = 1, #cache do + callback(cache[i][1], cache[i][2]) + end + return + end + cache = {} + self.cache.special = cache + guide.eachSource(self.ast, function (source) + if source.type == 'getlocal' + or source.type == 'getglobal' + or source.type == 'local' + or source.type == 'field' + or source.type == 'string' then + local name = self:getSpecialName(source) + if name then + cache[#cache+1] = { name, source } + end + end + end) + for i = 1, #cache do + callback(cache[i][1], cache[i][2]) + end +end + +--- 遍历元素 +---@param source table +---@param key string +---@param callback fun(info:table) +function mt:eachField(source, key, callback) + local cache = self.cache.field[source] + if cache and cache[key] then + for i = 1, #cache[key] do + callback(cache[key][i]) + end + return + end + local tp = source.type + local d = methods[tp] + if not d then + return + end + local f = d.eachField + if not f then + return + end + if self.step >= 100 then + error('Stack overflow!') + return + end + self.step = self.step + 1 + local mark = {} + if not cache then + cache = {} + self.cache.field[source] = cache + end + cache[key] = {} + f(self, source, key, function (info) + local src = info.source + local uri = info.uri + assert(src and uri) + if mark[src] then + return + end + mark[src] = true + info.searcher = files.getSearcher(uri) + cache[key][#cache[key]+1] = info + end) + for i = 1, #cache[key] do + callback(cache[key][i]) + end + self.step = self.step - 1 +end + +--- 遍历引用 +---@param source table +---@param callback fun(info:table) +function mt:eachRef(source, callback) + local cache = self.cache.ref[source] + if cache then + for i = 1, #cache do + callback(cache[i]) + end + return + end + local tp = source.type + local d = methods[tp] + if not d then + return + end + local f = d.eachRef + if not f then + return + end + if self.step >= 100 then + error('Stack overflow!') + return + end + self.step = self.step + 1 + cache = {} + self.cache.ref[source] = cache + local mark = {} + f(self, source, function (info) + local src = info.source + local uri = info.uri + assert(src and uri) + if mark[src] then + return + end + mark[src] = true + info.searcher = files.getSearcher(uri) + cache[#cache+1] = info + end) + for i = 1, #cache do + callback(cache[i]) + end + self.step = self.step - 1 +end + +--- 遍历定义 +---@param source table +---@param callback fun(info:table) +function mt:eachDef(source, callback) + local cache = self.cache.def[source] + if cache then + for i = 1, #cache do + callback(cache[i]) + end + return + end + local tp = source.type + local d = methods[tp] + if not d then + return + end + local f = d.eachDef + if not f then + return + end + if self.step >= 100 then + error('Stack overflow!') + return + end + self.step = self.step + 1 + cache = {} + self.cache.def[source] = cache + local mark = {} + f(self, source, function (info) + local src = info.source + local uri = info.uri + assert(src and uri) + if mark[src] then + return + end + mark[src] = true + info.searcher = files.getSearcher(uri) + cache[#cache+1] = info + end) + for i = 1, #cache do + callback(cache[i]) + end + self.step = self.step - 1 +end + +--- 遍历value +---@param source table +---@param callback fun(info:table) +function mt:eachValue(source, callback) + local cache = self.cache.value[source] + if cache then + for i = 1, #cache do + callback(cache[i]) + end + return + end + local tp = source.type + local d = methods[tp] + if not d then + return + end + local f = d.eachValue + if not f then + return + end + if self.step >= 100 then + error('Stack overflow!') + return + end + self.step = self.step + 1 + cache = {} + self.cache.value[source] = cache + local mark = {} + f(self, source, function (info) + local src = info.source + local uri = info.uri + assert(src and uri) + if mark[src] then + return + end + mark[src] = true + info.searcher = files.getSearcher(uri) + cache[#cache+1] = info + end) + for i = 1, #cache do + callback(cache[i]) + end + self.step = self.step - 1 +end + +--- 获取value +---@param source table +---@return value table +function mt:getValue(source) + local tp = source.type + local d = methods[tp] + if not d then + return + end + local f = d.getValue + if not f then + return + end + if self.step >= 100 then + error('Stack overflow!') + return + end + self.step = self.step + 1 + local value = f(self, source) + self.step = self.step - 1 + return value +end + +--- 获取函数的参数 +---@param source table +---@return table arg1 +---@return table arg2 +function mt:callArgOf(source) + if not source or source.type ~= 'call' then + return + end + local args = source.args + if not args then + return + end + return tableUnpack(args) +end + +--- 获取调用函数的返回值 +---@param source table +---@return table return1 +---@return table return2 +function mt:callReturnOf(source) + if not source or source.type ~= 'call' then + return + end + local parent = source.parent + local extParent = source.extParent + if extParent then + local returns = {parent.parent} + for i = 1, #extParent do + returns[i+1] = extParent[i].parent + end + return tableUnpack(returns) + elseif parent then + return parent.parent + end +end + +--- 获取函数定义的返回值 +---@param source table +---@param callback fun(source:table) +function mt:functionReturnOf(source, callback) + if not source or source.type ~= 'function' then + return + end + local returns = guide.getReturns(source) + for i = 1, #returns do + local src = returns[i] + callback() + end +end + +--- 获取source的索引,模式与值 +---@param source table +---@return table field +---@return string mode +---@return table value +function mt:childMode(source) + if source.type == 'getfield' then + return source.field, 'get' + elseif source.type == 'setfield' then + return source.field, 'set', source.value + elseif source.type == 'getmethod' then + return source.method, 'get' + elseif source.type == 'setmethod' then + return source.method, 'set', source.value + elseif source.type == 'getindex' then + return source.index, 'get' + elseif source.type == 'setindex' then + return source.index, 'set', source.value + elseif source.type == 'field' then + return self:childMode(source.parent) + elseif source.type == 'method' then + return self:childMode(source.parent) + end + return nil, nil +end + +---@class engineer_old +local m = {} + +--- 新建搜索器 +---@param uri string +---@return searcher_old +function m.create(uri) + local ast = files.getAst(uri) + local searcher = setmetatable({ + step = 0, + ast = ast.ast, + uri = uri, + cache = { + def = {}, + ref = {}, + field = {}, + value = {}, + specialName = {}, + }, + }, mt) + return searcher +end + +return m diff --git a/server-beta/src/searcher-old/label.lua b/server-beta/src/searcher-old/label.lua new file mode 100644 index 00000000..f05a57e6 --- /dev/null +++ b/server-beta/src/searcher-old/label.lua @@ -0,0 +1,3 @@ +local m = {} + +return m diff --git a/server-beta/src/searcher-old/local.lua b/server-beta/src/searcher-old/local.lua new file mode 100644 index 00000000..0213ee58 --- /dev/null +++ b/server-beta/src/searcher-old/local.lua @@ -0,0 +1,179 @@ +local guide = require 'parser.guide' +local checkSMT = require 'searcher.setmetatable' + +local m = {} + +function m:eachDef(source, callback) + if source.tag ~= 'self' then + callback { + source = source, + uri = self.uri, + mode = 'local', + } + end + if source.ref then + for _, ref in ipairs(source.ref) do + if ref.type == 'setlocal' then + callback { + source = ref, + uri = self.uri, + mode = 'set', + } + end + end + end + if source.tag == 'self' then + local method = source.method + local node = method.node + self:eachDef(node, callback) + end + if source.value then + self:eachDef(source.value, callback) + end +end + +function m:eachRef(source, callback) + if source.tag ~= 'self' then + callback { + source = source, + uri = self.uri, + mode = 'local', + } + end + if source.ref then + for _, ref in ipairs(source.ref) do + if ref.type == 'setlocal' then + callback { + source = ref, + uri = self.uri, + mode = 'set', + } + elseif ref.type == 'getlocal' then + callback { + source = ref, + uri = self.uri, + mode = 'get', + } + end + end + end + if source.tag == 'self' then + local method = source.method + local node = method.node + self:eachRef(node, callback) + end +end + +function m:eachField(source, key, callback) + local used = {} + used[source] = true + local found = false + local refs = source.ref + if refs then + for i = 1, #refs do + local ref = refs[i] + if ref.type == 'getlocal' then + used[ref] = true + local parent = ref.parent + if key == guide.getKeyName(parent) then + if parent.type:sub(1, 3) == 'set' then + callback { + source = parent, + uri = self.uri, + mode = 'set', + } + found = true + else + callback { + source = parent, + uri = self.uri, + mode = 'get', + } + end + end + elseif ref.type == 'getglobal' then + used[ref] = true + if key == guide.getKeyName(ref) then + -- _ENV.XXX + callback { + source = ref, + uri = self.uri, + mode = 'get', + } + end + elseif ref.type == 'setglobal' then + used[ref] = true + -- _ENV.XXX = XXX + if key == guide.getKeyName(ref) then + callback { + source = ref, + uri = self.uri, + mode = 'set', + } + found = true + end + end + end + end + if source.tag == 'self' then + local method = source.method + local node = method.node + self:eachField(node, key, function (info) + callback(info) + if info.mode == 'set' then + found = true + end + end) + end + self:eachValue(source, function (info) + local src = info.source + if source ~= src then + info.searcher:eachField(src, key, function (info) + callback(info) + if info.mode == 'set' then + found = true + end + end) + end + end) + checkSMT(self, key, used, found, callback) +end + +function m:eachValue(source, callback) + callback { + source = source, + uri = self.uri, + } + local refs = source.ref + if refs then + for i = 1, #refs do + local ref = refs[i] + if ref.type == 'setlocal' then + self:eachValue(ref.value, callback) + elseif ref.type == 'getlocal' then + local parent = ref.parent + if parent.type == 'setmethod' then + local func = parent.value + if func and func.locals then + callback { + source = func.locals[1], + uri = self.uri, + } + end + end + end + end + end + if source.value then + self:eachValue(source.value, callback) + end +end + +function m:getValue(source) + if source.type == 'local' + or source.type == 'setlocal' then + return source.value or source + end +end + +return m diff --git a/server-beta/src/searcher-old/method.lua b/server-beta/src/searcher-old/method.lua new file mode 100644 index 00000000..c05fba76 --- /dev/null +++ b/server-beta/src/searcher-old/method.lua @@ -0,0 +1,37 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachDef(source, callback) + local node = source.parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' then + callback(info) + end + end) +end + +function m:eachRef(source, callback) + local node = source.parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' or info.mode == 'get' then + callback(info) + end + end) +end + +function m:eachField(source, key, callback) + self:eachField(source.parent, key, callback) +end + +function m:eachValue(source, callback) + self:eachValue(source.parent, callback) +end + +function m:getValue(source) + return self:getValue(source.parent) +end + +return m diff --git a/server-beta/src/searcher-old/methods.lua b/server-beta/src/searcher-old/methods.lua new file mode 100644 index 00000000..498978dd --- /dev/null +++ b/server-beta/src/searcher-old/methods.lua @@ -0,0 +1,26 @@ +local methods = {} + +methods['local'] = require 'searcher.local' +methods['getlocal'] = require 'searcher.getlocal' +methods['setlocal'] = methods['getlocal'] +methods['getglobal'] = require 'searcher.getglobal' +methods['setglobal'] = methods['getglobal'] +methods['getfield'] = require 'searcher.getfield' +methods['setfield'] = methods['getfield'] +methods['tablefield'] = require 'searcher.tablefield' +methods['getmethod'] = methods['getfield'] +methods['setmethod'] = methods['getfield'] +methods['getindex'] = methods['getfield'] +methods['setindex'] = methods['getfield'] +methods['field'] = require 'searcher.field' +methods['method'] = require 'searcher.method' +methods['index'] = require 'searcher.index' +methods['number'] = require 'searcher.number' +methods['boolean'] = require 'searcher.boolean' +methods['string'] = require 'searcher.string' +methods['table'] = require 'searcher.table' +methods['select'] = require 'searcher.select' +methods['goto'] = require 'searcher.goto' +methods['label'] = require 'searcher.label' + +return methods diff --git a/server-beta/src/searcher-old/number.lua b/server-beta/src/searcher-old/number.lua new file mode 100644 index 00000000..f92670e1 --- /dev/null +++ b/server-beta/src/searcher-old/number.lua @@ -0,0 +1,43 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachDef(source, callback) + local parent = source.parent + if not parent then + return + end + if parent.type ~= 'setindex' and parent.type ~= 'getindex' then + return + end + local node = parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' then + callback(info) + end + end) +end + +function m:eachRef(source, callback) + local parent = source.parent + if not parent then + return + end + if parent.type ~= 'setindex' and parent.type ~= 'getindex' then + return + end + local node = parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' or info.mode == 'get' then + callback(info) + end + end) +end + +function m:getValue(source) + return source +end + +return m diff --git a/server-beta/src/searcher-old/select.lua b/server-beta/src/searcher-old/select.lua new file mode 100644 index 00000000..f7da7bfc --- /dev/null +++ b/server-beta/src/searcher-old/select.lua @@ -0,0 +1,34 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachDef(source, callback) + local vararg = source.vararg + if vararg.type == 'call' then + local func = vararg.node + self:eachValue(func, function (info) + self:functionReturnOf(info.source, function () + + end) + end) + end +end + +function m:eachValue(source, callback) + local vararg = source.vararg + if vararg.type == 'call' then + local func = vararg.node + if self:getSpecialName(func) == 'setmetatable' + and source.index == 1 then + local t, mt = self:callArgOf(vararg) + self:eachValue(t, callback) + self:eachField(mt, 's|__index', function (info) + if info.mode == 'set' then + info.searcher:eachValue(info.source, callback) + end + end) + end + end +end + +return m diff --git a/server-beta/src/searcher-old/setmetatable.lua b/server-beta/src/searcher-old/setmetatable.lua new file mode 100644 index 00000000..7489bf6f --- /dev/null +++ b/server-beta/src/searcher-old/setmetatable.lua @@ -0,0 +1,63 @@ +local guide = require 'parser.guide' + +local function checkIndex(info, key, t, used, call, callback) + if info.mode ~= 'set' then + return + end + local src = info.source + -- t.field -> mt.__index.field + if used[t] then + info.searcher:eachValue(src, function (info) + info.searcher:eachField(info.source, key, callback) + end) + end + -- mt.__index.field -> t.field + info.searcher:eachValue(src, function (info) + local value = info.source + if used[value] then + info.searcher:eachValue(t, function (info) + info.searcher:eachField(info.source, key, callback) + end) + local obj = info.searcher:callReturnOf(call) + if obj then + info.searcher:eachValue(obj, function (info) + info.searcher:eachField(info.source, key, callback) + end) + end + end + end) +end + +return function (self, key, used, found, callback) + self:eachSpecial(function (name, src) + local call = src.parent + if name == 'rawset' then + local t, k = self:callArgOf(call) + if used[t] and guide.getKeyName(k) == key then + callback { + source = call, + uri = self.uri, + mode = 'set', + } + end + elseif name == 'rawget' then + local t, k, v = self:callArgOf(call) + if used[t] and guide.getKeyName(k) == key then + callback { + source = call, + uri = self.uri, + mode = 'get', + } + self:eachField(v, key, callback) + end + elseif name == 'setmetatable' and not found then + -- 如果已经找到值,则不检查meta表 + local t, mt = self:callArgOf(call) + if mt then + self:eachField(mt, 's|__index', function (info) + checkIndex(info, key, t, used, call, callback) + end) + end + end + end) +end diff --git a/server-beta/src/searcher-old/string.lua b/server-beta/src/searcher-old/string.lua new file mode 100644 index 00000000..94907116 --- /dev/null +++ b/server-beta/src/searcher-old/string.lua @@ -0,0 +1,43 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachDef(source, callback) + local parent = source.parent + if not parent then + return + end + if parent.type ~= 'setindex' and parent.type ~= 'getindex' then + return + end + local node = parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' then + callback(info) + end + end) +end + +function m:eachRef(source, callback) + local parent = source.parent + if not parent then + return + end + if parent.type ~= 'setindex' and parent.type ~= 'getindex' then + return + end + local node = parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (info) + if info.mode == 'set' or info.mode == 'get' then + callback(info) + end + end) +end + +function m:getValue(source, callback) + return source +end + +return m diff --git a/server-beta/src/searcher-old/table.lua b/server-beta/src/searcher-old/table.lua new file mode 100644 index 00000000..fa9a064a --- /dev/null +++ b/server-beta/src/searcher-old/table.lua @@ -0,0 +1,30 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachField(source, key, callback) + for i = 1, #source do + local src = source[i] + if key == guide.getKeyName(src) then + if src.type == 'tablefield' then + callback { + source = src, + uri = self.uri, + mode = 'set', + } + elseif src.type == 'tableindex' then + callback { + source = src, + uri = self.uri, + mode = 'set', + } + end + end + end +end + +function m:getValue(source) + return source +end + +return m diff --git a/server-beta/src/searcher-old/tablefield.lua b/server-beta/src/searcher-old/tablefield.lua new file mode 100644 index 00000000..09456029 --- /dev/null +++ b/server-beta/src/searcher-old/tablefield.lua @@ -0,0 +1,19 @@ +local m = {} + +function m:eachField(source, key, callback) + if source.value then + self:eachField(source.value, key, callback) + end +end + +function m:eachValue(source, callback) + if source.value then + self:eachValue(source.value, callback) + end +end + +function m:getValue(source) + return source.value and self:getValue(source.value) or source +end + +return m |