summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-06-14 17:34:51 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-06-14 17:34:51 +0800
commitfd123ac1fd6d849d7ace9cc49dd3ab645da62544 (patch)
tree868ba45430499617b64c1e302791d37f0aa47ccd
parent99c391f9d16ee10a21297d1136b387f400736c48 (diff)
downloadlua-language-server-fd123ac1fd6d849d7ace9cc49dd3ab645da62544.zip
update runner
-rw-r--r--script/vm/runner.lua29
-rw-r--r--test/type_inference/init.lua9
2 files changed, 26 insertions, 12 deletions
diff --git a/script/vm/runner.lua b/script/vm/runner.lua
index bc4f5a02..8823486d 100644
--- a/script/vm/runner.lua
+++ b/script/vm/runner.lua
@@ -93,8 +93,17 @@ end
---@return vm.node
function mt:_lookInto(action, topNode, outNode)
action = vm.getObjectValue(action) or action
- if action.type == 'function' then
+ if action.type == 'function'
+ or action.type == 'loop'
+ or action.type == 'in'
+ or action.type == 'repeat'
+ or action.type == 'for' then
self:_launchBlock(action, topNode:copy())
+ elseif action.type == 'while' then
+ local blockNode, mainNode = self:_lookInto(action.filter, topNode:copy(), topNode:copy())
+ self:_fastWard(action.filter.finish, blockNode)
+ self:_launchBlock(action, blockNode:copy())
+ topNode = mainNode
elseif action.type == 'if' then
local mainNode = topNode:copy()
local blockNode = topNode:copy()
@@ -102,8 +111,10 @@ function mt:_lookInto(action, topNode, outNode)
if subBlock.type == 'ifblock' then
blockNode, mainNode = self:_lookInto(subBlock.filter, blockNode, mainNode)
self:_fastWard(subBlock.filter.finish, blockNode)
- local neverReturn
- blockNode, neverReturn = self:_launchBlock(subBlock, blockNode)
+ blockNode = self:_launchBlock(subBlock, blockNode:copy())
+ local neverReturn = subBlock.hasReturn
+ or subBlock.hasGoTo
+ or subBlock.hasBreak
if not neverReturn then
mainNode:merge(blockNode)
end
@@ -180,18 +191,12 @@ end
---@param block parser.object
---@param node vm.node
---@return vm.node
----@return boolean neverReturn
function mt:_launchBlock(block, node)
- local neverReturn = false
local topNode, top = self:_fastWard(block.start, node)
if not top then
- return topNode, neverReturn
+ return topNode
end
for _, action in ipairs(block) do
- if action.type == 'return'
- or action.type == 'goto' then
- neverReturn = true
- end
local finish = action.range or action.finish
if finish < top.start then
goto CONTINUE
@@ -199,12 +204,12 @@ function mt:_launchBlock(block, node)
topNode = self:_lookInto(action, topNode)
topNode, top = self:_fastWard(action.finish, topNode)
if not top then
- return topNode, neverReturn
+ return topNode
end
::CONTINUE::
end
topNode = self:_fastWard(block.finish, topNode)
- return topNode, neverReturn
+ return topNode
end
---@param loc parser.object
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 63b4bf88..7d0fec91 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -2164,6 +2164,15 @@ print(<?x?>)
]]
TEST 'integer' [[
+---@type integer?
+local x
+
+while x do
+ print(<?x?>)
+end
+]]
+
+TEST 'integer' [[
---@type fun():integer?
local iter