summaryrefslogtreecommitdiff
path: root/script/vm/runner.lua
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-04-24 00:05:42 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-04-24 00:05:42 +0800
commit999c5dd79a772d039b384ab856023942935592fb (patch)
treea2443b479f8663d474eae469ec6eacf796f46011 /script/vm/runner.lua
parent3cadbfc7419542a8b56f0996bfbfbda146a30ea5 (diff)
downloadlua-language-server-999c5dd79a772d039b384ab856023942935592fb.zip
infer by `assert(x)`
Diffstat (limited to 'script/vm/runner.lua')
-rw-r--r--script/vm/runner.lua49
1 files changed, 44 insertions, 5 deletions
diff --git a/script/vm/runner.lua b/script/vm/runner.lua
index 5c92dcbe..721e8c7f 100644
--- a/script/vm/runner.lua
+++ b/script/vm/runner.lua
@@ -81,17 +81,17 @@ function mt:_compileNarrowByFilter(filter, pos)
if not loc or not exp then
return
end
- if exp.type == 'nil' then
+ if guide.isLiteral(exp) then
if filter.op.type == '==' then
self.steps[#self.steps+1] = {
type = 'remove',
- name = 'nil',
+ name = exp.type,
pos = pos,
order = 2,
}
self.steps[#self.steps+1] = {
type = 'as',
- name = 'nil',
+ name = exp.type,
pos = pos,
order = 4,
}
@@ -99,13 +99,13 @@ function mt:_compileNarrowByFilter(filter, pos)
if filter.op.type == '~=' then
self.steps[#self.steps+1] = {
type = 'as',
- name = 'nil',
+ name = exp.type,
pos = pos,
order = 2,
}
self.steps[#self.steps+1] = {
type = 'remove',
- name = 'nil',
+ name = exp.type,
pos = pos,
order = 4,
}
@@ -248,6 +248,42 @@ function mt:_preCompile()
end)
end
+---@param loc parser.object
+---@param node vm.node
+---@return vm.node
+local function checkAssert(loc, node)
+ local parent = loc.parent
+ if parent.type == 'binary' then
+ if parent.op and (parent.op.type == '~=' or parent.op.type == '==') then
+ local exp
+ for i = 1, 2 do
+ if parent[i] == loc then
+ exp = parent[i % 2 + 1]
+ end
+ end
+ if exp and guide.isLiteral(exp) then
+ local callargs = parent.parent
+ if callargs.type == 'callargs'
+ and callargs.parent.node.special == 'assert'
+ and callargs[1] == parent then
+ if parent.op.type == '~=' then
+ node:remove(exp.type)
+ end
+ if parent.op.type == '==' then
+ node = vm.compileNode(exp)
+ end
+ end
+ end
+ end
+ end
+ if parent.type == 'callargs'
+ and parent.parent.node.special == 'assert'
+ and parent[1] == loc then
+ node:setTruly()
+ end
+ return node
+end
+
---@param callback fun(src: parser.object, node: vm.node)
function mt:launch(callback)
local node = vm.getNode(self.loc):copy()
@@ -267,6 +303,9 @@ function mt:launch(callback)
node:remove(step.name)
elseif step.type == 'object' then
node = callback(step.object, node) or node
+ if step.object.type == 'getlocal' then
+ node = checkAssert(step.object, node)
+ end
elseif step.type == 'save' then
-- nothing to do
elseif step.type == 'load' then