diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2018-11-30 14:58:26 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2018-11-30 14:58:26 +0800 |
commit | b12c90d26fe0e99fb77f22ebbedc4411794133d2 (patch) | |
tree | 5cd7acebb2bb8785cc3f61e123cb98036892c916 /server/src/matcher/definition.lua | |
parent | bad3834c8f6f6b462e8ef968f28e2e49929fbe65 (diff) | |
download | lua-language-server-b12c90d26fe0e99fb77f22ebbedc4411794133d2.zip |
支持多返回值
Diffstat (limited to 'server/src/matcher/definition.lua')
-rw-r--r-- | server/src/matcher/definition.lua | 106 |
1 files changed, 64 insertions, 42 deletions
diff --git a/server/src/matcher/definition.lua b/server/src/matcher/definition.lua index 12139e62..6c2f64b4 100644 --- a/server/src/matcher/definition.lua +++ b/server/src/matcher/definition.lua @@ -6,13 +6,16 @@ function mt:isContainPos(obj) return obj.start <= self.pos and obj.finish + 1 >= self.pos end -function mt:getVar(key) +function mt:getVar(key, source) if key == nil then return nil end - return - self.env.var[key] or - self:getField(self.env.var._ENV, key) -- 这里不需要用getVar来递归获取_ENV + local var = self.env.var[key] + or self:getField(self.env.var._ENV, key, source) -- 这里不需要用getVar来递归获取_ENV + if not var then + var = self:addField(self:getVar '_ENV', key, source) + end + return var end function mt:addVarInfo(var, info) @@ -24,51 +27,49 @@ function mt:createLocal(key, source) if key == nil then return nil end - local var = self:addVarInfo({}, { - type = 'local', + local var = { + type = 'local', source = source, - }) + } self.env.var[key] = var return var end -function mt:createGlobal(key, source) - if key == nil then - return nil - end - local info = { - type = 'global', - source = source, - } - local var = self:addField(self:getVar '_ENV', key, info) - return var +function mt:bindLocal(key, other_key, source) + self.env.var[key] = self:getVar(other_key, source) end -function mt:addField(parent, key, info) +function mt:addField(parent, key, source) if parent == nil or key == nil then return nil end - assert(info) + assert(source) if not parent.childs then parent.childs = {} end local var = parent.childs[key] if not var then - var = {} + var = { + type = 'field', + source = source, + } parent.childs[key] = var end - self:addVarInfo(var, info) return var end -function mt:getField(parent, key) +function mt:getField(parent, key, source) if parent == nil or key == nil then return nil end if not parent.childs then return nil end - return parent.childs[key] + local var = parent.childs[key] + if not var then + var = self:addField(parent, key, source) + end + return var end function mt:checkVar(var, source) @@ -84,7 +85,7 @@ function mt:checkVar(var, source) end function mt:checkName(name) - local var = self:getVar(name[1]) + local var = self:getVar(name[1], name) self:checkVar(var, name) end @@ -110,24 +111,26 @@ end function mt:searchSimple(simple) local name = simple[1] - local var = self:getVar(name[1]) or self:createGlobal(name[1], name) + local var = self:getVar(name[1], name) self:checkVar(var, name) for i = 2, #simple do local obj = simple[i] local tp = obj.type if tp == 'call' then + var = nil self:searchCall(obj) + elseif tp == ':' then elseif tp == 'name' then if obj.index then var = nil self:searchExp(obj) else - var = self:getField(var, obj[1]) + var = self:getField(var, obj[1], obj) self:checkVar(var, obj) end else if obj.index then - var = self:getField(var, obj[1]) + var = self:getField(var, obj[1], obj) self:checkVar(var, obj) else var = nil @@ -185,27 +188,21 @@ end function mt:markSimple(simple) local name = simple[1] - local var = self:getVar(name[1]) or self:createGlobal(name[1], name) + local var = self:getVar(name[1], name) for i = 2, #simple do local obj = simple[i] local tp = obj.type if tp == ':' then - self:createLocal('self', obj) + self:bindLocal('self', simple[i-1][1], simple[i-1]) elseif tp == 'name' then if not obj.index then - var = self:addField(var, obj[1], { - type = 'field', - source = obj, - }) + var = self:addField(var, obj[1], obj) else var = nil end else if obj.index then - var = self:addField(var, obj[1], { - type = 'field', - source = obj, - }) + var = self:addField(var, obj[1], obj) else var = nil end @@ -215,7 +212,7 @@ end function mt:markSet(simple) if simple.type == 'name' then - local var = self:getVar(simple[1]) or self:createGlobal(simple[1], simple) + local var = self:getVar(simple[1], simple) self:addVarInfo(var, { type = 'set', source = simple, @@ -399,15 +396,40 @@ function mt:searchActions(actions) end local function parseResult(result) + local results = {} local tp = result.type if tp == 'var' then - local first = result.var[1] - local source = first.source - return true, source.start, source.finish + local var = result.var + if var.type == 'local' then + local source = var.source + if not source then + return false + end + results[1] = {source.start, source.finish} + elseif var.type == 'field' then + local source = var.source + if not source then + return false + end + if #var == 0 then + results[1] = {source.start, source.finish} + else + for i, info in ipairs(var) do + if info.type == 'set' then + results[i] = {info.source.start, info.source.finish} + end + end + end + else + error('unknow var.type:' .. var.type) + end elseif tp == 'dots' then local dots = result.dots - return true, dots.start, dots.finish + results[1] = {dots.start, dots.finish} + else + error('unknow result.type:' .. result.type) end + return true, results end return function (ast, pos) |