From 48b2f21602b5c041843125a071e50dde94527fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Fri, 11 Oct 2019 17:06:51 +0800 Subject: =?UTF-8?q?=E5=8F=AA=E5=9C=A8=E5=BF=85=E8=A6=81=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E5=80=99=E5=90=91=E4=B8=8A=E6=90=9C=E7=B4=A2=20=5F=5Findex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-beta/src/core/getfield.lua | 49 ++++--------------------- server-beta/src/core/local.lua | 68 ++++++++++++----------------------- server-beta/src/core/setmetatable.lua | 48 +++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 89 deletions(-) create mode 100644 server-beta/src/core/setmetatable.lua (limited to 'server-beta/src') diff --git a/server-beta/src/core/getfield.lua b/server-beta/src/core/getfield.lua index 8a1d2061..af16bdf5 100644 --- a/server-beta/src/core/getfield.lua +++ b/server-beta/src/core/getfield.lua @@ -1,10 +1,12 @@ local guide = require 'parser.guide' +local checkSMT = require 'core.setmetatable' local m = {} function m:field(source, key, callback) local used = {} used[source] = true + local found = false local node = source.node local myKey = guide.getKeyName(source) self:eachValue(node, function (src) @@ -15,55 +17,16 @@ function m:field(source, key, callback) if key == guide.getKeyName(src) then used[src] = true callback(src, mode) + if mode == 'set' then + found = true + end end end) end) end end) end) - 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' then - 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:eachDef(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) + checkSMT(self, key, used, found, callback) end return m diff --git a/server-beta/src/core/local.lua b/server-beta/src/core/local.lua index 0ad53e87..44e14596 100644 --- a/server-beta/src/core/local.lua +++ b/server-beta/src/core/local.lua @@ -1,4 +1,5 @@ local guide = require 'parser.guide' +local checkSMT = require 'core.setmetatable' local m = {} @@ -43,6 +44,7 @@ end function m:field(source, key, callback) local used = {} used[source] = true + local found = false local refs = source.ref if refs then for i = 1, #refs do @@ -51,7 +53,12 @@ function m:field(source, key, callback) used[ref] = true local parent = ref.parent if key == guide.getKeyName(parent) then - self:childRef(parent, callback) + self:childRef(parent, function (src, mode) + callback(src, mode) + if mode == 'set' then + found = true + end + end) end elseif ref.type == 'getglobal' then used[ref] = true @@ -64,6 +71,7 @@ function m:field(source, key, callback) -- _ENV.XXX = XXX if key == guide.getKeyName(ref) then callback(ref, 'set') + found = true end end end @@ -71,56 +79,24 @@ function m:field(source, key, callback) if source.tag == 'self' then local method = source.method local node = method.node - self:eachField(node, key, callback) + 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, callback) - end - end) - 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' then - 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:eachDef(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 + 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:value(source, callback) diff --git a/server-beta/src/core/setmetatable.lua b/server-beta/src/core/setmetatable.lua new file mode 100644 index 00000000..ecb1a98d --- /dev/null +++ b/server-beta/src/core/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:eachDef(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 -- cgit v1.2.3