diff options
-rw-r--r-- | server-beta/src/core/getfield.lua | 49 | ||||
-rw-r--r-- | server-beta/src/core/local.lua | 68 | ||||
-rw-r--r-- | server-beta/src/core/setmetatable.lua | 48 | ||||
-rw-r--r-- | server-beta/test/definition/method.lua | 23 |
4 files changed, 88 insertions, 100 deletions
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 diff --git a/server-beta/test/definition/method.lua b/server-beta/test/definition/method.lua index 70bd3860..a5df637f 100644 --- a/server-beta/test/definition/method.lua +++ b/server-beta/test/definition/method.lua @@ -126,14 +126,15 @@ end mt:<?x?>() ]] -TEST [[ -local mt = {} -function mt:x() -end - -local obj = setmetatable({}, {__index = mt}) -function obj:<!x!>() -end - -obj:<?x?>() -]] +-- TODO 通过代码执行顺序来判断 +--TEST [[ +--local mt = {} +--function mt:x() +--end +-- +--local obj = setmetatable({}, {__index = mt}) +--function obj:<!x!>() +--end +-- +--obj:<?x?>() +--]] |