summaryrefslogtreecommitdiff
path: root/server-beta/src
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-10-11 16:00:11 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-10-11 16:00:11 +0800
commita8b970238486c28868d3199cd8bba2d07a421817 (patch)
treee0c621760f6265317f3e70ba54c97ae5f6db0410 /server-beta/src
parenta54939cb662f8730a011cababf37b634e6344300 (diff)
downloadlua-language-server-a8b970238486c28868d3199cd8bba2d07a421817.zip
更新
Diffstat (limited to 'server-beta/src')
-rw-r--r--server-beta/src/core/engineer.lua50
-rw-r--r--server-beta/src/core/getfield.lua69
-rw-r--r--server-beta/src/core/local.lua40
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