diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-10-11 17:06:51 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-10-11 17:06:51 +0800 |
commit | 48b2f21602b5c041843125a071e50dde94527fa9 (patch) | |
tree | 7dcb1dd231f424b9ef9cd4947045def0a3bc0fa9 /server-beta/src | |
parent | 7426f1c8b300afc0ac5f14686c6244f37b1b010c (diff) | |
download | lua-language-server-48b2f21602b5c041843125a071e50dde94527fa9.zip |
只在必要的时候向上搜索 __index
Diffstat (limited to 'server-beta/src')
-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 |
3 files changed, 76 insertions, 89 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 |