diff options
Diffstat (limited to 'server-beta/src/seacher')
-rw-r--r-- | server-beta/src/seacher/boolean.lua | 43 | ||||
-rw-r--r-- | server-beta/src/seacher/field.lua | 34 | ||||
-rw-r--r-- | server-beta/src/seacher/getfield.lua | 66 | ||||
-rw-r--r-- | server-beta/src/seacher/getglobal.lua | 109 | ||||
-rw-r--r-- | server-beta/src/seacher/getlocal.lua | 19 | ||||
-rw-r--r-- | server-beta/src/seacher/goto.lua | 13 | ||||
-rw-r--r-- | server-beta/src/seacher/index.lua | 13 | ||||
-rw-r--r-- | server-beta/src/seacher/init.lua | 345 | ||||
-rw-r--r-- | server-beta/src/seacher/label.lua | 3 | ||||
-rw-r--r-- | server-beta/src/seacher/local.lua | 126 | ||||
-rw-r--r-- | server-beta/src/seacher/method.lua | 33 | ||||
-rw-r--r-- | server-beta/src/seacher/methods.lua | 26 | ||||
-rw-r--r-- | server-beta/src/seacher/number.lua | 43 | ||||
-rw-r--r-- | server-beta/src/seacher/select.lua | 21 | ||||
-rw-r--r-- | server-beta/src/seacher/setmetatable.lua | 48 | ||||
-rw-r--r-- | server-beta/src/seacher/string.lua | 43 | ||||
-rw-r--r-- | server-beta/src/seacher/table.lua | 22 | ||||
-rw-r--r-- | server-beta/src/seacher/tablefield.lua | 15 |
18 files changed, 1022 insertions, 0 deletions
diff --git a/server-beta/src/seacher/boolean.lua b/server-beta/src/seacher/boolean.lua new file mode 100644 index 00000000..3f36ee59 --- /dev/null +++ b/server-beta/src/seacher/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 (src, mode) + if mode == 'set' then + callback(src, mode) + 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 (src, mode) + if mode == 'set' or mode == 'get' then + callback(src, mode) + end + end) +end + +function m:eachValue(source, callback) + callback(source) +end + +return m diff --git a/server-beta/src/seacher/field.lua b/server-beta/src/seacher/field.lua new file mode 100644 index 00000000..72e8ab59 --- /dev/null +++ b/server-beta/src/seacher/field.lua @@ -0,0 +1,34 @@ +local guide = require 'parser.guide' +local checkSMT = require 'seacher.setmetatable' + +local m = {} + +function m:eachDef(source, callback) + local parent = source.parent + local key = guide.getKeyName(source) + self:eachField(parent, key, function (src, mode) + if mode == 'set' then + callback(src, mode) + end + end) +end + +function m:eachRef(source, callback) + local parent = source.parent + local key = guide.getKeyName(source) + self:eachField(parent, key, function (src, mode) + if mode == 'set' or mode == 'set' then + callback(src, mode) + 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 + +return m diff --git a/server-beta/src/seacher/getfield.lua b/server-beta/src/seacher/getfield.lua new file mode 100644 index 00000000..7b9ac263 --- /dev/null +++ b/server-beta/src/seacher/getfield.lua @@ -0,0 +1,66 @@ +local guide = require 'parser.guide' +local checkSMT = require 'seacher.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 (src, mode) + if mode == 'set' or mode == 'get' then + callback(src, mode) + 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 (src) + used[src] = true + local child, mode, value = self:childMode(src) + if child then + if key == guide.getKeyName(child) then + callback(child, mode) + end + if value then + self:eachField(value, key, callback) + end + return + end + if src.type == 'getglobal' then + local parent = src.parent + child, mode = self:childMode(parent) + if child then + if key == guide.getKeyName(child) then + callback(child, mode) + end + end + elseif src.type == 'setglobal' then + self:eachField(src.value, key, callback) + else + self:eachField(src, key, callback) + end + end) + + checkSMT(self, key, used, found, callback) +end + +function m:eachValue(source, callback) + if source.value then + self:eachValue(source.value, callback) + end +end + +return m diff --git a/server-beta/src/seacher/getglobal.lua b/server-beta/src/seacher/getglobal.lua new file mode 100644 index 00000000..a6bee129 --- /dev/null +++ b/server-beta/src/seacher/getglobal.lua @@ -0,0 +1,109 @@ +local guide = require 'parser.guide' +local checkSMT = require 'seacher.setmetatable' + +local m = {} + +function m:eachDef(source, callback) + -- _ENV + local key = guide.getKeyName(source) + self:eachField(source.node, key, function (src, mode) + if mode == 'set' then + callback(src, mode) + end + end) + self:eachSpecial(function (name, src) + if name == '_G' then + local parent = src.parent + if guide.getKeyName(parent) == key then + callback(parent, '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(src.parent, 'set') + end + end + end) +end + +function m:eachRef(source, callback) + -- _ENV + local key = guide.getKeyName(source) + self:eachField(source.node, key, function (src, mode) + if mode == 'set' or mode == 'get' then + callback(src, mode) + 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(parent, 'set') + else + callback(parent, '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(src.parent, '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(src.parent, 'get') + end + end + end) +end + +function m:eachField(source, key, callback) + local used = {} + local found = false + used[source] = true + + self:eachRef(source, function (src) + used[src] = true + local child, mode, value = self:childMode(src) + if child then + if key == guide.getKeyName(child) then + callback(child, mode) + end + if value then + self:eachField(value, key, callback) + end + return + end + if src.type == 'getglobal' then + local parent = src.parent + child, mode, value = self:childMode(parent) + if child then + if key == guide.getKeyName(child) then + callback(child, mode) + end + if value then + self:eachField(value, key, callback) + end + end + elseif src.type == 'setglobal' then + self:eachField(src.value, key, callback) + else + self:eachField(src, key, callback) + end + end) + + checkSMT(self, key, used, found, callback) +end + +function m:eachValue(source, callback) + callback(source) + if source.value then + self:eachValue(source.value, callback) + end +end + +return m diff --git a/server-beta/src/seacher/getlocal.lua b/server-beta/src/seacher/getlocal.lua new file mode 100644 index 00000000..ca4e58c3 --- /dev/null +++ b/server-beta/src/seacher/getlocal.lua @@ -0,0 +1,19 @@ +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 + +return m diff --git a/server-beta/src/seacher/goto.lua b/server-beta/src/seacher/goto.lua new file mode 100644 index 00000000..36f373d2 --- /dev/null +++ b/server-beta/src/seacher/goto.lua @@ -0,0 +1,13 @@ +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(label) + end +end + +return m diff --git a/server-beta/src/seacher/index.lua b/server-beta/src/seacher/index.lua new file mode 100644 index 00000000..f96c2dcf --- /dev/null +++ b/server-beta/src/seacher/index.lua @@ -0,0 +1,13 @@ +local m = {} + +function m:eachValue(source, callback) + local parent = source.parent + if parent.type == 'setindex' + or parent.type == 'tableindex' then + if parent.value then + self:eachValue(parent.value, callback) + end + end +end + +return m diff --git a/server-beta/src/seacher/init.lua b/server-beta/src/seacher/init.lua new file mode 100644 index 00000000..5584c83f --- /dev/null +++ b/server-beta/src/seacher/init.lua @@ -0,0 +1,345 @@ +local guide = require 'parser.guide' +local files = require 'files' +local methods = require 'seacher.methods' +local tableUnpack = table.unpack +local error = error +local setmetatable = setmetatable + +_ENV = nil +local specials = { + ['_G'] = true, + ['rawset'] = true, + ['rawget'] = true, + ['setmetatable'] = true, + ['require'] = true, + ['dofile'] = true, + ['loadfile'] = true, +} + +---@class seacher +local mt = {} +mt.__index = mt +mt.__name = 'seacher' + +--- 获取特殊对象的名字 +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(src) + 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(field:table, mode:string) +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(tableUnpack(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 (src, ...) + if mark[src] then + return + end + mark[src] = true + cache[key][#cache[key]+1] = { src, ... } + end) + for i = 1, #cache[key] do + callback(tableUnpack(cache[key][i])) + end + self.step = self.step - 1 +end + +--- 遍历引用 +---@param source table +---@param callback fun(def:table, mode:string) +function mt:eachRef(source, callback) + local cache = self.cache.ref[source] + if cache then + for i = 1, #cache do + callback(tableUnpack(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 (src, ...) + if mark[src] then + return + end + mark[src] = true + cache[#cache+1] = {src, ...} + end) + for i = 1, #cache do + callback(tableUnpack(cache[i])) + end + self.step = self.step - 1 +end + +--- 遍历定义 +---@param source table +---@param callback fun(def:table, mode:string) +function mt:eachDef(source, callback) + local cache = self.cache.def[source] + if cache then + for i = 1, #cache do + callback(tableUnpack(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 (src, ...) + if mark[src] then + return + end + mark[src] = true + cache[#cache+1] = {src, ...} + end) + for i = 1, #cache do + callback(tableUnpack(cache[i])) + end + self.step = self.step - 1 +end + +--- 遍历value +---@param source table +---@param callback fun(value:table) +function mt:eachValue(source, callback) + local cache = self.cache.value[source] + if cache then + for i = 1, #cache do + callback(tableUnpack(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 (src, ...) + if mark[src] then + return + end + mark[src] = true + cache[#cache+1] = {src, ...} + end) + for i = 1, #cache do + callback(tableUnpack(cache[i])) + end + self.step = self.step - 1 +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 + +--- 获取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 +local m = {} + +--- 新建搜索器 +---@param uri string +---@return seacher +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/seacher/label.lua b/server-beta/src/seacher/label.lua new file mode 100644 index 00000000..f05a57e6 --- /dev/null +++ b/server-beta/src/seacher/label.lua @@ -0,0 +1,3 @@ +local m = {} + +return m diff --git a/server-beta/src/seacher/local.lua b/server-beta/src/seacher/local.lua new file mode 100644 index 00000000..302d49da --- /dev/null +++ b/server-beta/src/seacher/local.lua @@ -0,0 +1,126 @@ +local guide = require 'parser.guide' +local checkSMT = require 'seacher.setmetatable' + +local m = {} + +function m:eachDef(source, callback) + if source.tag ~= 'self' then + callback(source, 'local') + end + if source.ref then + for _, ref in ipairs(source.ref) do + if ref.type == 'setlocal' then + callback(ref, 'set') + end + end + end + if source.tag == 'self' then + local method = source.method + local node = method.node + self:eachDef(node, callback) + end +end + +function m:eachRef(source, callback) + if source.tag ~= 'self' then + callback(source, 'local') + end + if source.ref then + for _, ref in ipairs(source.ref) do + if ref.type == 'setlocal' then + callback(ref, 'set') + elseif ref.type == 'getlocal' then + callback(ref, '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(parent, 'set') + found = true + else + callback(parent, 'get') + end + end + elseif ref.type == 'getglobal' then + used[ref] = true + if key == guide.getKeyName(ref) then + -- _ENV.XXX + callback(ref, 'get') + end + elseif ref.type == 'setglobal' then + used[ref] = true + -- _ENV.XXX = XXX + if key == guide.getKeyName(ref) then + callback(ref, '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 (src, mode) + callback(src, mode) + if mode == 'set' then + found = true + end + end) + end + self:eachValue(source, function (src) + if source ~= src then + self:eachField(src, key, function (src, mode) + callback(src, mode) + if mode == 'set' then + found = true + end + end) + end + end) + checkSMT(self, key, used, found, callback) +end + +function m:eachValue(source, callback) + callback(source) + 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(func.locals[1]) + end + end + end + end + end + if source.value then + self:eachValue(source.value, callback) + end +end + +return m diff --git a/server-beta/src/seacher/method.lua b/server-beta/src/seacher/method.lua new file mode 100644 index 00000000..52c00358 --- /dev/null +++ b/server-beta/src/seacher/method.lua @@ -0,0 +1,33 @@ +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 (src, mode) + if mode == 'set' then + callback(src, mode) + end + end) +end + +function m:eachRef(source, callback) + local node = source.parent.node + local key = guide.getKeyName(source) + self:eachField(node, key, function (src, mode) + if mode == 'set' or mode == 'get' then + callback(src, mode) + 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 + +return m diff --git a/server-beta/src/seacher/methods.lua b/server-beta/src/seacher/methods.lua new file mode 100644 index 00000000..a23350bf --- /dev/null +++ b/server-beta/src/seacher/methods.lua @@ -0,0 +1,26 @@ +local methods = {} + +methods['local'] = require 'seacher.local' +methods['getlocal'] = require 'seacher.getlocal' +methods['setlocal'] = methods['getlocal'] +methods['getglobal'] = require 'seacher.getglobal' +methods['setglobal'] = methods['getglobal'] +methods['getfield'] = require 'seacher.getfield' +methods['setfield'] = methods['getfield'] +methods['tablefield'] = require 'seacher.tablefield' +methods['getmethod'] = methods['getfield'] +methods['setmethod'] = methods['getfield'] +methods['getindex'] = methods['getfield'] +methods['setindex'] = methods['getfield'] +methods['field'] = require 'seacher.field' +methods['method'] = require 'seacher.method' +methods['index'] = require 'seacher.index' +methods['number'] = require 'seacher.number' +methods['boolean'] = require 'seacher.boolean' +methods['string'] = require 'seacher.string' +methods['table'] = require 'seacher.table' +methods['select'] = require 'seacher.select' +methods['goto'] = require 'seacher.goto' +methods['label'] = require 'seacher.label' + +return methods diff --git a/server-beta/src/seacher/number.lua b/server-beta/src/seacher/number.lua new file mode 100644 index 00000000..3f36ee59 --- /dev/null +++ b/server-beta/src/seacher/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 (src, mode) + if mode == 'set' then + callback(src, mode) + 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 (src, mode) + if mode == 'set' or mode == 'get' then + callback(src, mode) + end + end) +end + +function m:eachValue(source, callback) + callback(source) +end + +return m diff --git a/server-beta/src/seacher/select.lua b/server-beta/src/seacher/select.lua new file mode 100644 index 00000000..bbdf1234 --- /dev/null +++ b/server-beta/src/seacher/select.lua @@ -0,0 +1,21 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:eachValue(source, callback) + local vararg = source.vararg + if vararg.type == 'call' then + local func = vararg.node + if self:getSpecialName(func) == 'setmetatable' then + local t, mt = self:callArgOf(vararg) + self:eachValue(t, callback) + self:eachField(mt, 's|__index', function (src, mode) + if mode == 'set' then + self:eachValue(src, callback) + end + end) + end + end +end + +return m diff --git a/server-beta/src/seacher/setmetatable.lua b/server-beta/src/seacher/setmetatable.lua new file mode 100644 index 00000000..978d165c --- /dev/null +++ b/server-beta/src/seacher/setmetatable.lua @@ -0,0 +1,48 @@ +local guide = require 'parser.guide' + +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(call, 'set') + end + elseif name == 'rawget' then + local t, k, v = self:callArgOf(call) + if used[t] and guide.getKeyName(k) == key then + callback(call, '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 (src, mode) + if mode == 'set' then + -- t.field -> mt.__index.field + if used[t] then + self:eachValue(src, function (mtvalue) + self:eachField(mtvalue, key, callback) + end) + end + -- mt.__index.field -> t.field + self:eachValue(src, function (src) + if used[src] then + self:eachValue(t, function (mtvalue) + self:eachField(mtvalue, key, callback) + end) + local obj = self:callReturnOf(call) + if obj then + self:eachValue(obj, function (mtvalue) + self:eachField(mtvalue, key, callback) + end) + end + end + end) + end + end) + end + end + end) +end diff --git a/server-beta/src/seacher/string.lua b/server-beta/src/seacher/string.lua new file mode 100644 index 00000000..3f36ee59 --- /dev/null +++ b/server-beta/src/seacher/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 (src, mode) + if mode == 'set' then + callback(src, mode) + 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 (src, mode) + if mode == 'set' or mode == 'get' then + callback(src, mode) + end + end) +end + +function m:eachValue(source, callback) + callback(source) +end + +return m diff --git a/server-beta/src/seacher/table.lua b/server-beta/src/seacher/table.lua new file mode 100644 index 00000000..851ee791 --- /dev/null +++ b/server-beta/src/seacher/table.lua @@ -0,0 +1,22 @@ +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(src, 'set') + elseif src.type == 'tableindex' then + callback(src, 'set') + end + end + end +end + +function m:eachValue(source, callback) + callback(source) +end + +return m diff --git a/server-beta/src/seacher/tablefield.lua b/server-beta/src/seacher/tablefield.lua new file mode 100644 index 00000000..219828d4 --- /dev/null +++ b/server-beta/src/seacher/tablefield.lua @@ -0,0 +1,15 @@ +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 + +return m |