summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2018-11-30 18:30:56 +0800
committer最萌小汐 <sumneko@hotmail.com>2018-11-30 18:30:56 +0800
commit0c6436f78d48c6b4d6494ad9c3d573b6aa7baf06 (patch)
treead58b44118c6c531a2d849f68c3b4157b04e099c
parent56303121277f5ebf9668ca9f3fc886392df83a16 (diff)
downloadlua-language-server-0c6436f78d48c6b4d6494ad9c3d573b6aa7baf06.zip
可以穿透大部分meta表了
-rw-r--r--server/src/lsp.lua10
-rw-r--r--server/src/matcher/definition.lua41
-rw-r--r--server/test/definition/method.lua48
3 files changed, 70 insertions, 29 deletions
diff --git a/server/src/lsp.lua b/server/src/lsp.lua
index 37bf17c1..b2d2f959 100644
--- a/server/src/lsp.lua
+++ b/server/src/lsp.lua
@@ -115,9 +115,7 @@ function mt:_buildTextCache()
local clock = os.clock()
for _, uri in ipairs(list) do
local obj = self:compileText(uri)
- if obj then
- size = size + #obj.text
- end
+ size = size + #obj.text
end
local passed = os.clock() - clock
log.debug(('\n\z
@@ -186,11 +184,7 @@ function mt:compileText(uri)
return nil
end
self._need_compile[uri] = nil
- local ast, err = parser:ast(obj.text)
- if not ast then
- return nil
- end
- obj.ast = ast
+ obj.ast = parser:ast(obj.text)
obj.lines = parser:lines(obj.text)
return obj
end
diff --git a/server/src/matcher/definition.lua b/server/src/matcher/definition.lua
index 096647e5..a00337d1 100644
--- a/server/src/matcher/definition.lua
+++ b/server/src/matcher/definition.lua
@@ -29,35 +29,32 @@ function mt:addVarInfo(var, info)
return var
end
-function mt:createLocal(key, source)
+function mt:createLocal(key, source, var)
if key == nil then
return nil
end
- local var = {
- type = 'local',
- source = source,
- }
+ if not var then
+ var = {
+ type = 'local',
+ source = source,
+ childs = {},
+ }
+ end
self.env.var[key] = var
return var
end
-function mt:setMeta(var, meta_var)
- var.meta = meta_var
-end
-
function mt:addField(parent, key, source)
if parent == nil or key == nil then
return nil
end
assert(source)
- if not parent.childs then
- parent.childs = {}
- end
local var = parent.childs[key]
if not var then
var = {
type = 'field',
source = source,
+ childs = {},
}
parent.childs[key] = var
end
@@ -121,10 +118,14 @@ function mt:searchCall(call, simple, i)
if metatable then
local index = self:getField(metatable, '__index')
if obj then
- obj.meta = index
+ self:setTable(obj, index)
+ return obj
+ else
+ return index
end
+ else
+ return obj
end
- return obj
end
return nil
end
@@ -174,6 +175,7 @@ end
function mt:searchTable(exp)
local tbl = {
type = 'table',
+ childs = {},
}
for _, obj in ipairs(exp) do
if obj.type == 'pair' then
@@ -226,9 +228,6 @@ function mt:setTable(var, tbl)
if not var or not tbl then
return
end
- if tbl.type ~= 'table' then
- return
- end
var.childs = tbl.childs
end
@@ -239,9 +238,7 @@ function mt:markSimple(simple)
local obj = simple[i]
local tp = obj.type
if tp == ':' then
- local var = self:createLocal('self', simple[i-1])
- local meta_var = self:getVar(simple[i-1][1])
- self:setMeta(var, meta_var)
+ var = self:createLocal('self', simple[i-1], self:getVar(simple[i-1][1]))
elseif tp == 'name' then
if not obj.index then
var = self:addField(var, obj[1], obj)
@@ -268,6 +265,7 @@ function mt:markSimple(simple)
end
end
end
+ return var
end
function mt:markSet(simple, tbl)
@@ -281,7 +279,8 @@ function mt:markSet(simple, tbl)
self:setTable(var, tbl)
else
self:searchSimple(simple)
- self:markSimple(simple)
+ local var = self:markSimple(simple)
+ self:setTable(var, tbl)
end
end
diff --git a/server/test/definition/method.lua b/server/test/definition/method.lua
index 2829f5b7..24e3b3b8 100644
--- a/server/test/definition/method.lua
+++ b/server/test/definition/method.lua
@@ -39,3 +39,51 @@ end
local obj = setmetatable({}, mt)
obj:<?method1?>()
]]
+
+TEST [[
+local mt
+mt.__index = mt
+function mt:<!method1!>()
+end
+
+local obj = setmetatable(1, mt)
+obj:<?method1?>()
+]]
+
+TEST [[
+local mt
+function mt:<!method1!>()
+end
+
+local obj = setmetatable(1, { __index = mt })
+obj:<?method1?>()
+]]
+
+TEST [[
+local mt
+local api
+function mt:<!method1!>()
+end
+
+setmetatable(api, { __index = mt })
+api:<?method1?>()
+]]
+
+TEST [[
+local mt
+function mt:x()
+ self.<?init?>()
+end
+
+local obj = setmetatable({}, { __index = mt })
+obj.<!init!> = 1
+]]
+
+TEST [[
+local mt
+function mt:x()
+ self.<?init?>()
+end
+
+local obj = setmetatable({ <!init!> = 1 }, { __index = mt })
+]]