summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server-beta/src/core/getfield.lua49
-rw-r--r--server-beta/src/core/local.lua68
-rw-r--r--server-beta/src/core/setmetatable.lua48
-rw-r--r--server-beta/test/definition/method.lua23
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?>()
+--]]