summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-12-15 16:46:59 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-12-15 16:46:59 +0800
commit244a19d365d8b3d3881492e08fefa9847bd11a2f (patch)
treeb71dfe508b14015690a824be3d0f7f57ff1fba16
parent0ab880ea3e3ef74c91dc56e449b4b7d60d654d8f (diff)
downloadlua-language-server-244a19d365d8b3d3881492e08fefa9847bd11a2f.zip
add supports for merging with `ifblock`
-rw-r--r--script/vm/node.lua7
-rw-r--r--script/vm/tracer.lua81
2 files changed, 68 insertions, 20 deletions
diff --git a/script/vm/node.lua b/script/vm/node.lua
index 2e408128..d0fd5ffb 100644
--- a/script/vm/node.lua
+++ b/script/vm/node.lua
@@ -188,9 +188,6 @@ end
---@return vm.node
function mt:setFalsy()
- if self.optional == false then
- self.optional = nil
- end
local hasBoolean
for index = #self, 1, -1 do
local c = self[index]
@@ -229,6 +226,10 @@ function mt:setFalsy()
if hasBoolean then
self:merge(vm.declareGlobal('type', 'false'))
end
+ if self.optional then
+ self.optional = nil
+ self:merge(vm.declareGlobal('type', 'nil'))
+ end
return self
end
diff --git a/script/vm/tracer.lua b/script/vm/tracer.lua
index 065a52da..0c5b6939 100644
--- a/script/vm/tracer.lua
+++ b/script/vm/tracer.lua
@@ -35,11 +35,12 @@ end
---@param mark table
function mt:collectBlock(obj, mark)
while true do
- obj = obj.parent
- if mark[obj] then
+ local block = guide.getParentBlock(obj)
+ if not block then
return
end
- if not guide.isBlockType(obj) then
+ obj = block
+ if mark[obj] then
return
end
if obj == self.main then
@@ -63,6 +64,9 @@ function mt:collectLocal()
self.assigns[#self.assigns+1] = obj
self:collectBlock(obj, mark)
end
+ if obj.type == 'getlocal' then
+ self:collectBlock(obj, mark)
+ end
end
local casts = self:getCasts()
@@ -112,10 +116,31 @@ function mt:narrow(source)
end
if source.type == 'getlocal' then
- node = node:copy():setTruthy()
- return node
+ node = node:copy()
+ node:setTruthy()
end
+ return node
+end
+
+---@param source parser.object
+---@return vm.node?
+function mt:calcGet(source)
+ local parent = source.parent
+ if parent.type == 'filter' then
+ return self:calcGet(parent)
+ end
+ if parent.type == 'ifblock' then
+ local parentBlock = guide.getParentBlock(parent.parent)
+ if parentBlock then
+ local lastAssign = self:getLastAssign(parentBlock, parent.start)
+ local node = self:getNode(lastAssign or parentBlock)
+ return node
+ end
+ end
+ if parent.type == 'unary' then
+ return self:calcGet(parent)
+ end
return nil
end
@@ -135,19 +160,10 @@ function mt:calcNode(source)
local node = self:getNode(lastAssign)
return node
end
- local parent = source.parent
- while true do
- if parent.type == 'filter'
- or parent.type == 'unary'
- or parent.type == 'ifblock'
- or parent.type == 'elseifblock' then
- parent = parent.parent
- else
- break
- end
+ local node = self:calcGet(source)
+ if node then
+ return node
end
- local node = self:getNode(parent)
- return node
end
if source.type == 'setlocal' then
if source.node ~= self.source then
@@ -180,6 +196,37 @@ function mt:calcNode(source)
return node
end
end
+ if source.type == 'if' then
+ local parentBlock = guide.getParentBlock(source)
+ if not parentBlock then
+ return nil
+ end
+ local lastAssign = self:getLastAssign(parentBlock, source.start)
+ local outNode = self:getNode(lastAssign or source.parent) or vm.createNode()
+ for _, block in ipairs(source) do
+ local blockNode = self:getNode(block)
+ if not blockNode then
+ goto CONTINUE
+ end
+ if block.hasReturn
+ or block.hasError
+ or block.hasBreak then
+ outNode:removeNode(blockNode)
+ goto CONTINUE
+ end
+ local blockAssign = self:getLastAssign(block, block.finish)
+ if not blockAssign then
+ goto CONTINUE
+ end
+ local blockAssignNode = self:getNode(blockAssign)
+ if not blockAssignNode then
+ goto CONTINUE
+ end
+ outNode:removeNode(blockNode)
+ outNode:merge(blockAssignNode)
+ ::CONTINUE::
+ end
+ end
if source.type == 'unary' then
if source.op.type == 'not' then
local node = self:getNode(source[1])