diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2023-01-11 22:03:43 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2023-01-11 22:03:43 +0800 |
commit | 390474caca77ea5e745f3a3ae2ca7168e7165573 (patch) | |
tree | 97bdcf92bf6ec60d802f795f47e59bb8e33f3c61 /script/vm/tracer.lua | |
parent | d74c85c8517b9f3b7591cc337fa387f2805ebb40 (diff) | |
download | lua-language-server-390474caca77ea5e745f3a3ae2ca7168e7165573.zip |
stash
Diffstat (limited to 'script/vm/tracer.lua')
-rw-r--r-- | script/vm/tracer.lua | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/script/vm/tracer.lua b/script/vm/tracer.lua index 1ec29a1e..de787625 100644 --- a/script/vm/tracer.lua +++ b/script/vm/tracer.lua @@ -12,9 +12,8 @@ local util = require 'utility' ---@class vm.tracer ---@field mode tracer.mode ---@field name string ----@field source parser.object ----@field variable vm.variable ----@field assigns parser.object[] +---@field source parser.object | vm.variable +---@field assigns (parser.object | vm.variable)[] ---@field assignMap table<parser.object, true> ---@field getMap table<parser.object, true> ---@field careMap table<parser.object, true> @@ -30,7 +29,7 @@ mt.fastCalc = true ---@return parser.object[] function mt:getCasts() - local root = guide.getRoot(self.source) + local root = guide.getRoot(self.main) if not root._casts then root._casts = {} local docs = root.docs @@ -92,12 +91,16 @@ function mt:collectCare(obj) end function mt:collectLocal() - local startPos = self.source.start + local startPos = self.source.base.start local finishPos = 0 - local variable = self.variable + local variable = self.source - assert(variable) + if variable.base.type ~= 'local' + and variable.base.type ~= 'self' then + self.assigns[#self.assigns+1] = variable + self.assignMap[self.source] = true + end for _, set in ipairs(variable.sets) do self.assigns[#self.assigns+1] = set @@ -121,7 +124,7 @@ function mt:collectLocal() if cast.name[1] == self.name and cast.start > startPos and cast.finish < finishPos - and vm.getCastTargetHead(cast) == self.source then + and vm.getCastTargetHead(cast) == variable.base then self.casts[#self.casts+1] = cast end end @@ -129,10 +132,6 @@ function mt:collectLocal() if #self.casts > 0 then self.fastCalc = false end - - if variable ~= vm.getVariable(self.source) then - self.fastCalc = false - end end function mt:collectGlobal() @@ -173,17 +172,20 @@ end ---@param finish integer ---@return parser.object? function mt:getLastAssign(start, finish) - local assign - for _, obj in ipairs(self.assigns) do - if obj.type == 'local' - or obj.type == 'self' then - assign = obj - break + local lastAssign + for _, assign in ipairs(self.assigns) do + local obj + if assign.type == 'variable' then + ---@cast assign vm.variable + obj = assign.base + else + ---@cast assign parser.object + obj = assign end if obj.start < start then goto CONTINUE end - if (obj.range or obj.start) >= finish then + if (obj.effect or obj.range or obj.start) >= finish then break end local objBlock = guide.getTopBlock(obj) @@ -192,11 +194,11 @@ function mt:getLastAssign(start, finish) end if objBlock.start <= finish and objBlock.finish >= finish then - assign = obj + lastAssign = obj end ::CONTINUE:: end - return assign + return lastAssign end ---@param pos integer @@ -656,9 +658,7 @@ local lookIntoChild = util.switch() and call.type == 'call' and call.node.special == 'type' and call.args - and call.args[1] - and call.args[1].type == 'getlocal' - and call.args[1].node == tracer.source then + and tracer.getMap[call.args[1]] then if action.op.type == '==' then topNode:narrow(tracer.uri, checker[1]) if outNode then @@ -790,23 +790,28 @@ end ---@field package _tracer vm.tracer ---@param mode tracer.mode ----@param source parser.object +---@param source parser.object | vm.variable ---@param name string ----@param variable vm.variable? ---@return vm.tracer? -local function createTracer(mode, source, name, variable) - local node = vm.compileNode(variable or source) +local function createTracer(mode, source, name) + local node = vm.compileNode(source) local tracer = node._tracer if tracer then return tracer end - local main = guide.getParentBlock(source) + local main + if source.type == 'variable' then + ---@cast source vm.variable + main = guide.getParentBlock(source.base) + else + ---@cast source parser.object + main = guide.getParentBlock(source) + end if not main then return nil end tracer = setmetatable({ source = source, - variable = variable, mode = mode, name = name, assigns = {}, @@ -833,7 +838,7 @@ end ---@param source parser.object ---@return vm.node? function vm.traceNode(source) - local mode, base, name, variable + local mode, base, name if vm.getGlobalNode(source) then base = vm.getGlobalBase(source) if not base then @@ -842,15 +847,14 @@ function vm.traceNode(source) mode = 'global' name = base.global:getCodeName() else - variable = vm.getVariable(source) - if not variable then + base = vm.getVariable(source) + if not base then return nil end - base = variable:getBase() - name = variable:getCodeName() + name = base:getCodeName() mode = 'local' end - local tracer = createTracer(mode, base, name, variable) + local tracer = createTracer(mode, base, name) if not tracer then return nil end |