diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-12-13 21:00:38 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-12-13 21:00:38 +0800 |
commit | eb05f7ac0f85d034c20e29f68b12d84fa7436601 (patch) | |
tree | 1f93744bf103c861bfe2252f3b7d2eb37ef741d7 /script/vm/tracer.lua | |
parent | ed97a9e8905fdbb3b23694896c813cfdb73cd91f (diff) | |
download | lua-language-server-eb05f7ac0f85d034c20e29f68b12d84fa7436601.zip |
stash
Diffstat (limited to 'script/vm/tracer.lua')
-rw-r--r-- | script/vm/tracer.lua | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/script/vm/tracer.lua b/script/vm/tracer.lua index e304bbd1..61ad89ee 100644 --- a/script/vm/tracer.lua +++ b/script/vm/tracer.lua @@ -102,21 +102,80 @@ function mt:getLastAssign(block, pos) return assign end +---@param filter parser.object +---@param node vm.node? +---@return vm.node +function mt:narrowByFilter(filter, node) + if not node then + node = vm.createNode() + end + if filter.type == 'filter' then + node = self:narrowByFilter(filter.exp, node) + return node + end + if filter.type == 'getlocal' then + if filter.node == self.source then + node = node:copy() + node:removeOptional() + end + return node + end + return node +end + ---@param source parser.object ---@return vm.node? function mt:calcNode(source) + if source.type == 'getlocal' then + return nil + end + if source.type == 'local' then + if source ~= self.source then + return nil + end + end + if source.type == 'setlocal' then + if source.node ~= self.source then + return nil + end + end if guide.isSet(source) then local node = vm.compileNode(source) return node end if source.type == 'do' then local lastAssign = self:getLastAssign(source, source.finish) - if lastAssign then - return self:getNode(lastAssign) - else - return nil + return self:getNode(lastAssign or source.parent) + end + if source.type == 'ifblock' then + local currentNode = self:getNode(source.parent) + local narrowedNode = self:narrowByFilter(source.filter, currentNode) + return narrowedNode + end + if source.type == 'filter' then + local parent = source.parent + ---@type parser.object + local outBlock + if parent.type == 'ifblock' then + outBlock = parent.parent.parent + local lastAssign = self:getLastAssign(outBlock, parent.start) + return self:getNode(lastAssign or source.parent) + elseif parent.type == 'elseifblock' then + outBlock = parent.parent.parent + local lastAssign = self:getLastAssign(outBlock, parent.start) + return self:getNode(lastAssign or source.parent) + elseif parent.type == 'while' then + outBlock = parent.parent + local lastAssign = self:getLastAssign(outBlock, parent.start) + return self:getNode(lastAssign or source.parent) + elseif parent.type == 'repeat' then + outBlock = parent.parent + local lastAssign = self:getLastAssign(outBlock, parent.start) + return self:getNode(lastAssign or source.parent) end + assert(outBlock, parent.type) end + return nil end ---@param source parser.object @@ -140,7 +199,7 @@ function mt:getNode(source) return node end local lastAssign = self:getLastAssign(parentBlock, source.start) - local parentNode = self:getNode(lastAssign or parentBlock) + local parentNode = self:getNode(lastAssign or source.parent) self.nodes[source] = parentNode or false return parentNode end |