diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-10-11 16:00:11 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-10-11 16:00:11 +0800 |
commit | a8b970238486c28868d3199cd8bba2d07a421817 (patch) | |
tree | e0c621760f6265317f3e70ba54c97ae5f6db0410 /server-beta/src | |
parent | a54939cb662f8730a011cababf37b634e6344300 (diff) | |
download | lua-language-server-a8b970238486c28868d3199cd8bba2d07a421817.zip |
更新
Diffstat (limited to 'server-beta/src')
-rw-r--r-- | server-beta/src/core/engineer.lua | 50 | ||||
-rw-r--r-- | server-beta/src/core/getfield.lua | 69 | ||||
-rw-r--r-- | server-beta/src/core/local.lua | 40 |
3 files changed, 132 insertions, 27 deletions
diff --git a/server-beta/src/core/engineer.lua b/server-beta/src/core/engineer.lua index 675bd803..f11d6a9d 100644 --- a/server-beta/src/core/engineer.lua +++ b/server-beta/src/core/engineer.lua @@ -16,6 +16,7 @@ mt['getlocal'] = require 'core.getlocal' mt['setlocal'] = mt['getlocal'] mt['getglobal'] = require 'core.getglobal' mt['setglobal'] = mt['getglobal'] +mt['getfield'] = require 'core.getfield' mt['field'] = require 'core.field' mt['method'] = require 'core.method' mt['index'] = require 'core.index' @@ -25,17 +26,28 @@ mt['string'] = require 'core.string' mt['table'] = require 'core.table' mt['select'] = require 'core.select' +local specials = { + ['_G'] = true, + ['rawset'] = true, + ['rawget'] = true, + ['setmetatable'] = true, +} + function mt:getSpecialName(source) if source.type == 'getglobal' then local node = source.node if node.tag ~= '_ENV' then - return + return nil end local name = guide.getKeyName(source) if name:sub(1, 2) ~= 's|' then return nil end - return name:sub(3) + local spName = name:sub(3) + if not specials[spName] then + return nil + end + return spName elseif source.type == 'local' then if source.tag == '_ENV' then return '_G' @@ -47,9 +59,17 @@ function mt:getSpecialName(source) return '_G' end end + return nil end 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 local env = guide.getENV(self.ast) if not env then return @@ -58,12 +78,18 @@ function mt:eachSpecial(callback) if not refs then return end + cache = {} + self.cache.special = cache for i = 1, #refs do local ref = refs[i] - if ref.type == 'getglobal' then - callback(ref[1], ref) + local name = self:getSpecialName(ref) + if name then + cache[#cache+1] = {name, ref} end end + for i = 1, #cache do + callback(cache[i][1], cache[i][2]) + end end function mt:eachField(source, key, callback) @@ -100,8 +126,10 @@ function mt:eachField(source, key, callback) end mark[src] = true cache[key][#cache[key]+1] = { src, ... } - callback(src, ...) end) + for i = 1, #cache[key] do + callback(tableUnpack(cache[key][i])) + end self.step = self.step - 1 end @@ -136,8 +164,10 @@ function mt:eachRef(source, callback) end mark[src] = true cache[#cache+1] = {src, ...} - callback(src, ...) end) + for i = 1, #cache do + callback(tableUnpack(cache[i])) + end self.step = self.step - 1 end @@ -172,8 +202,10 @@ function mt:eachDef(source, callback) end mark[src] = true cache[#cache+1] = {src, ...} - callback(src, ...) end) + for i = 1, #cache do + callback(tableUnpack(cache[i])) + end self.step = self.step - 1 end @@ -208,8 +240,10 @@ function mt:eachValue(source, callback) end mark[src] = true cache[#cache+1] = {src, ...} - callback(src, ...) end) + for i = 1, #cache do + callback(tableUnpack(cache[i])) + end self.step = self.step - 1 end diff --git a/server-beta/src/core/getfield.lua b/server-beta/src/core/getfield.lua new file mode 100644 index 00000000..8a1d2061 --- /dev/null +++ b/server-beta/src/core/getfield.lua @@ -0,0 +1,69 @@ +local guide = require 'parser.guide' + +local m = {} + +function m:field(source, key, callback) + local used = {} + used[source] = true + local node = source.node + local myKey = guide.getKeyName(source) + self:eachValue(node, function (src) + self:eachField(src, myKey, function (src, mode) + if mode == 'set' then + self:eachValue(src, function (src) + self:eachField(src, key, function (src, mode) + if key == guide.getKeyName(src) then + used[src] = true + callback(src, mode) + 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) +end + +return m diff --git a/server-beta/src/core/local.lua b/server-beta/src/core/local.lua index adbb9138..0ad53e87 100644 --- a/server-beta/src/core/local.lua +++ b/server-beta/src/core/local.lua @@ -93,30 +93,32 @@ function m:field(source, key, callback) end elseif name == 'setmetatable' then local t, mt = self:callArgOf(call) - 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) + 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) - local obj = self:callReturnOf(call) - if obj then - self:eachValue(obj, function (mtvalue) + 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) + end end end) end |