diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-04-23 19:42:37 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-04-23 19:42:37 +0800 |
commit | 30570630339f3a3ce19329d045ac0eb42627d3b9 (patch) | |
tree | c1de514fdd573ac9c1401ff974e9c28ca9457a80 /script | |
parent | 5381bf4da77eb7903f8294d9cf177480f5590499 (diff) | |
download | lua-language-server-30570630339f3a3ce19329d045ac0eb42627d3b9.zip |
infer by `x == nil` and `x ~= nil`
Diffstat (limited to 'script')
-rw-r--r-- | script/vm/node.lua | 5 | ||||
-rw-r--r-- | script/vm/runner.lua | 65 |
2 files changed, 66 insertions, 4 deletions
diff --git a/script/vm/node.lua b/script/vm/node.lua index b759ed72..8dd0c7f7 100644 --- a/script/vm/node.lua +++ b/script/vm/node.lua @@ -71,7 +71,7 @@ function mt:addOptional() end function mt:removeOptional() - self.optional = false + self:remove 'nil' end ---@return boolean @@ -187,6 +187,9 @@ end ---@param name string function mt:remove(name) + if name == 'nil' and self.optional == true then + self.optional = nil + end local index = 0 while true do index = index + 1 diff --git a/script/vm/runner.lua b/script/vm/runner.lua index 7f22996d..026fd983 100644 --- a/script/vm/runner.lua +++ b/script/vm/runner.lua @@ -16,7 +16,7 @@ mt.index = 1 ---@field _hasSorted boolean ---@class vm.runner.step ----@field type 'truly' | 'falsy' | 'add' | 'remove' | 'object' | 'save' | 'load' | 'merge' +---@field type 'truly' | 'falsy' | 'as' | 'add' | 'remove' | 'object' | 'save' | 'load' | 'merge' ---@field pos integer ---@field order? integer ---@field node? vm.node @@ -39,9 +39,13 @@ function mt:_compileNarrowByFilter(filter, pos) return end if filter.type == 'unary' then - if filter.op and filter.op.type == 'not' then + if not filter.op + or not filter[1] then + return + end + if filter.op.type == 'not' then local exp = filter[1] - if exp and exp.type == 'getlocal' and exp.node == self.loc then + if exp.type == 'getlocal' and exp.node == self.loc then self.steps[#self.steps+1] = { type = 'truly', pos = pos, @@ -55,6 +59,59 @@ function mt:_compileNarrowByFilter(filter, pos) end end elseif filter.type == 'binary' then + if not filter.op + or not filter[1] + or not filter[2] then + return + end + if filter.op.type == 'and' then + self:_compileNarrowByFilter(filter[1], pos) + self:_compileNarrowByFilter(filter[2], pos) + end + if filter.op.type == '==' + or filter.op.type == '~=' then + local loc, exp + for i = 1, 2 do + loc = filter[i] + if loc.type == 'getlocal' and loc.node == self.loc then + exp = filter[i % 2 + 1] + break + end + end + if not loc then + return + end + if exp.type == 'nil' then + if filter.op.type == '==' then + self.steps[#self.steps+1] = { + type = 'remove', + name = 'nil', + pos = pos, + order = 2, + } + self.steps[#self.steps+1] = { + type = 'as', + name = 'nil', + pos = pos, + order = 4, + } + end + if filter.op.type == '~=' then + self.steps[#self.steps+1] = { + type = 'as', + name = 'nil', + pos = pos, + order = 2, + } + self.steps[#self.steps+1] = { + type = 'remove', + name = 'nil', + pos = pos, + order = 4, + } + end + end + end else if filter.type == 'getlocal' and filter.node == self.loc then self.steps[#self.steps+1] = { @@ -193,6 +250,8 @@ function mt:launch(callback) node:setTruly() elseif step.type == 'falsy' then node:setFalsy() + elseif step.type == 'as' then + node = vm.createNode(globalMgr.getGlobal('type', step.name)) elseif step.type == 'add' then node:merge(globalMgr.getGlobal('type', step.name)) elseif step.type == 'remove' then |