diff options
-rw-r--r-- | server/src/matcher/compile.lua | 21 | ||||
-rw-r--r-- | server/src/matcher/definition.lua | 28 | ||||
-rw-r--r-- | server/test/definition/method.lua | 13 |
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 }) +]] |