summaryrefslogtreecommitdiff
path: root/server-beta/src
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-10-11 17:06:51 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-10-11 17:06:51 +0800
commit48b2f21602b5c041843125a071e50dde94527fa9 (patch)
tree7dcb1dd231f424b9ef9cd4947045def0a3bc0fa9 /server-beta/src
parent7426f1c8b300afc0ac5f14686c6244f37b1b010c (diff)
downloadlua-language-server-48b2f21602b5c041843125a071e50dde94527fa9.zip
只在必要的时候向上搜索 __index
Diffstat (limited to 'server-beta/src')
-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
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