summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/matcher/compile.lua21
-rw-r--r--server/src/matcher/definition.lua28
-rw-r--r--server/test/definition/method.lua13
3 files changed, 51 insertions, 11 deletions
diff --git a/server/src/matcher/compile.lua b/server/src/matcher/compile.lua
index ecfdbdd4..0e6bf7da 100644
--- a/server/src/matcher/compile.lua
+++ b/server/src/matcher/compile.lua
@@ -76,6 +76,7 @@ function mt:addField(parent, key, source)
if not var then
var = self:createVar('field', key, source)
parent.childs[key] = var
+ var.parent = parent
end
return var
end
@@ -121,7 +122,7 @@ function mt:searchCall(call, simple, i)
if metatable then
local index = self:getField(metatable, '__index')
if obj then
- self:setTable(obj, index, 'copy')
+ self:setMeta(obj, index)
return obj
else
return index
@@ -233,19 +234,17 @@ function mt:setTable(var, tbl, mode)
if not var or not tbl then
return
end
- if mode == 'copy' then
- for k, v in pairs(var.childs) do
- if tbl.childs[k] then
- for i, info in ipairs(v) do
- table.insert(tbl.childs[k], 1, info)
- end
- end
- tbl.childs[k] = v
- end
- end
var.childs = tbl.childs
end
+function mt:setMeta(var, meta)
+ if not var or not meta then
+ return
+ end
+ var.childs.meta = meta
+ meta.childs.meta = var
+end
+
function mt:markSimple(simple)
local name = simple[1]
local var = self:getVar(name[1], name)
diff --git a/server/src/matcher/definition.lua b/server/src/matcher/definition.lua
index 41556745..794788e8 100644
--- a/server/src/matcher/definition.lua
+++ b/server/src/matcher/definition.lua
@@ -37,6 +37,26 @@ local function findResult(results, pos)
return nil
end
+local function tryMeta(var)
+ local keys = {}
+ repeat
+ if var.childs.meta then
+ local metavar = var.childs.meta
+ for i = #keys, 1, -1 do
+ local key = keys[i]
+ metavar = metavar.childs[key]
+ if not metavar then
+ return nil
+ end
+ end
+ return metavar
+ end
+ keys[#keys+1] = var.key
+ var = var.parent
+ until not var
+ return nil
+end
+
local function parseResult(result)
local positions = {}
local tp = result.type
@@ -54,6 +74,14 @@ local function parseResult(result)
positions[#positions+1] = {info.source.start, info.source.finish}
end
end
+ local metavar = tryMeta(var)
+ if metavar then
+ for _, info in ipairs(metavar) do
+ if info.type == 'set' then
+ positions[#positions+1] = {info.source.start, info.source.finish}
+ end
+ end
+ end
else
error('unknow var.type:' .. var.type)
end
diff --git a/server/test/definition/method.lua b/server/test/definition/method.lua
index 24e3b3b8..ac9e95e7 100644
--- a/server/test/definition/method.lua
+++ b/server/test/definition/method.lua
@@ -87,3 +87,16 @@ end
local obj = setmetatable({ <!init!> = 1 }, { __index = mt })
]]
+
+TEST [[
+local mt
+function mt:x()
+ self.a.<?out?>()
+end
+
+local obj = setmetatable({
+ a = {
+ <!out!> = 1,
+ }
+}, { __index = mt })
+]]