summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/vm/tracer.lua38
-rw-r--r--test/type_inference/init.lua9
2 files changed, 39 insertions, 8 deletions
diff --git a/script/vm/tracer.lua b/script/vm/tracer.lua
index ba83fd5b..2e2fd084 100644
--- a/script/vm/tracer.lua
+++ b/script/vm/tracer.lua
@@ -9,7 +9,7 @@ local guide = require 'parser.guide'
---@class vm.tracer
---@field source parser.object
---@field assigns parser.object[]
----@field nodes table<parser.object, vm.node>
+---@field nodes table<parser.object, vm.node|false>
---@field main parser.object
---@field uri uri
local mt = {}
@@ -34,15 +34,20 @@ end
---@param mark table
function mt:collectBlock(obj, mark)
while true do
+ obj = obj.parent
if mark[obj] then
return
end
- mark[obj] = true
- self.assigns[#self.assigns+1] = obj
+ if not guide.isBlockType(obj) then
+ return
+ end
if obj == self.main then
return
end
- obj = obj.parent
+ mark[obj] = true
+ if obj.type ~= 'do' then
+ self.assigns[#self.assigns+1] = obj
+ end
end
end
@@ -78,11 +83,23 @@ end
---@return parser.object?
function mt:getLastAssign(source)
local assign = self.source
+ local block = guide.getParentBlock(source)
+ if not block then
+ return nil
+ end
for _, obj in ipairs(self.assigns) do
- if obj.start > source.start then
+ if obj.start >= source.start then
break
end
- assign = obj
+ local objBlock = guide.getParentBlock(obj)
+ if not objBlock then
+ break
+ end
+ if objBlock == block
+ or objBlock.type == 'do'
+ or objBlock.finish > block.finish then
+ assign = obj
+ end
end
return assign
end
@@ -90,17 +107,22 @@ end
---@param source parser.object
---@return vm.node?
function mt:getNode(source)
- if self.nodes[source] then
- return self.nodes[source]
+ if self.nodes[source] ~= nil then
+ return self.nodes[source] or nil
end
local lastAssign = self:getLastAssign(source)
if not lastAssign then
+ self.nodes[source] = false
return nil
end
if guide.isSet(lastAssign) then
local lastNode = vm.compileNode(lastAssign)
+ self.nodes[source] = lastNode
return lastNode
end
+ local lastNode = self:getNode(lastAssign)
+ self.nodes[source] = lastNode
+ return lastNode
end
---@param source parser.object
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 02b3da03..ab7404e2 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -1758,6 +1758,15 @@ x = '1'
x = 1
]]
+TEST 'integer' [[
+local x
+x = true
+do
+ x = 1
+end
+print(<?x?>)
+]]
+
TEST 'integer?' [[
---@type integer?
local <?x?>