summaryrefslogtreecommitdiff
path: root/script/vm/compiler.lua
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-04-06 04:16:40 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-04-06 04:16:40 +0800
commitc4c0009ef28de6cd4bfe01c497cbb718f3c2dff8 (patch)
tree7524eb0f7370f256cb74934fe731464f9884b874 /script/vm/compiler.lua
parentbf3f97e05082f2a529621a70c3fde516513076b1 (diff)
downloadlua-language-server-c4c0009ef28de6cd4bfe01c497cbb718f3c2dff8.zip
update
Diffstat (limited to 'script/vm/compiler.lua')
-rw-r--r--script/vm/compiler.lua106
1 files changed, 71 insertions, 35 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 61a6076f..d5d65dfb 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -483,16 +483,38 @@ local function isValidCallArgNode(source, node)
return node.type == 'doc.type.table'
or (node.type == 'global' and node.cate == 'type' and not guide.isBasicType(node.name))
end
+ if source.type == 'dummy' then
+ return true
+ end
return false
end
-local function setCallArgNode(source, call, callNode, fixIndex)
+---@param func parser.object
+---@param index integer
+---@return parser.object?
+local function getFuncArg(func, index)
+ local args = func.args
+ if not args then
+ return nil
+ end
+ if args[index] then
+ return args[index]
+ end
+ local lastArg = args[#args]
+ if lastArg.type == '...' then
+ return lastArg
+ end
+ return nil
+end
+
+local function compileCallArgNode(arg, call, callNode, fixIndex, myIndex)
local valueMgr = require 'vm.value'
- local myIndex
- for i, arg in ipairs(call.args) do
- if arg == source then
- myIndex = i - fixIndex
- break
+ if not myIndex then
+ for i, carg in ipairs(call.args) do
+ if carg == arg then
+ myIndex = i - fixIndex
+ break
+ end
end
end
@@ -508,10 +530,10 @@ local function setCallArgNode(source, call, callNode, fixIndex)
for n in nodeMgr.eachNode(callNode) do
if n.type == 'function' then
- local arg = n.args[myIndex]
- for fn in nodeMgr.eachNode(m.compileNode(arg)) do
- if isValidCallArgNode(source, fn) then
- nodeMgr.setNode(source, fn)
+ local farg = getFuncArg(n, myIndex)
+ for fn in nodeMgr.eachNode(m.compileNode(farg)) do
+ if isValidCallArgNode(arg, fn) then
+ nodeMgr.setNode(arg, fn)
end
end
end
@@ -521,10 +543,10 @@ local function setCallArgNode(source, call, callNode, fixIndex)
or not eventMap
or event.type ~= 'doc.type.string'
or eventMap[event[1]] then
- local arg = n.args[myIndex]
- for fn in nodeMgr.eachNode(m.compileNode(arg)) do
- if isValidCallArgNode(source, fn) then
- nodeMgr.setNode(source, fn)
+ local farg = getFuncArg(n, myIndex)
+ for fn in nodeMgr.eachNode(m.compileNode(farg)) do
+ if isValidCallArgNode(arg, fn) then
+ nodeMgr.setNode(arg, fn)
end
end
end
@@ -532,6 +554,18 @@ local function setCallArgNode(source, call, callNode, fixIndex)
end
end
+function m.compileCallArg(arg, call, index)
+ local callNode = m.compileNode(call.node)
+ compileCallArgNode(arg, call, callNode, 0, index)
+
+ if call.node.special == 'pcall'
+ or call.node.special == 'xpcall' then
+ local fixIndex = call.node.special == 'pcall' and 1 or 2
+ callNode = m.compileNode(call.args[1])
+ compileCallArgNode(arg, call, callNode, fixIndex, index)
+ end
+end
+
local compilerSwitch = util.switch()
: case 'nil'
: case 'boolean'
@@ -551,18 +585,11 @@ local compilerSwitch = util.switch()
if source.parent.type == 'callargs' then
local call = source.parent.parent
- local callNode = m.compileNode(call.node)
- setCallArgNode(source, call, callNode, 0)
-
- if call.node.special == 'pcall'
- or call.node.special == 'xpcall' then
- local fixIndex = call.node.special == 'pcall' and 1 or 2
- callNode = m.compileNode(call.args[1])
- setCallArgNode(source, call, callNode, fixIndex)
- end
+ m.compileCallArg(source, call)
end
if source.parent.type == 'setglobal'
+ or source.parent.type == 'local'
or source.parent.type == 'setlocal'
or source.parent.type == 'tablefield'
or source.parent.type == 'tableindex'
@@ -586,15 +613,7 @@ local compilerSwitch = util.switch()
-- table.sort(string[], function (<?x?>) end)
if source.parent.type == 'callargs' then
local call = source.parent.parent
- local callNode = m.compileNode(call.node)
- setCallArgNode(source, call, callNode, 0)
-
- if call.node.special == 'pcall'
- or call.node.special == 'xpcall' then
- local fixIndex = call.node.special == 'pcall' and 1 or 2
- callNode = m.compileNode(call.args[1])
- setCallArgNode(source, call, callNode, fixIndex)
- end
+ m.compileCallArg(source, call)
end
end)
: case 'paren'
@@ -612,7 +631,11 @@ local compilerSwitch = util.switch()
if source.ref and not hasMarkDoc then
for _, ref in ipairs(source.ref) do
if ref.type == 'setlocal' then
- nodeMgr.setNode(source, m.compileNode(ref.value))
+ if ref.value.type == 'table' then
+ nodeMgr.setNode(source, ref.value)
+ else
+ nodeMgr.setNode(source, m.compileNode(ref.value))
+ end
end
end
end
@@ -623,7 +646,11 @@ local compilerSwitch = util.switch()
end
if source.value then
if not hasMarkDoc or guide.isLiteral(source.value) then
- nodeMgr.setNode(source, m.compileNode(source.value))
+ if source.value.type == 'table' then
+ nodeMgr.setNode(source, source.value)
+ else
+ nodeMgr.setNode(source, m.compileNode(source.value))
+ end
end
end
-- function x.y(self, ...) --> function x:y(...)
@@ -675,6 +702,11 @@ local compilerSwitch = util.switch()
: case 'setindex'
: call(function (source)
compileByLocalID(source)
+ m.compileByParentNode(source.node, guide.getKeyName(source), function (src)
+ if src.type == 'doc.type.field' then
+ nodeMgr.setNode(source, m.compileNode(src))
+ end
+ end)
end)
: case 'getfield'
: case 'getmethod'
@@ -695,7 +727,11 @@ local compilerSwitch = util.switch()
if source.value then
if not hasMarkDoc or guide.isLiteral(source.value) then
- nodeMgr.setNode(source, m.compileNode(source.value))
+ if source.value.type == 'table' then
+ nodeMgr.setNode(source, source.value)
+ else
+ nodeMgr.setNode(source, m.compileNode(source.value))
+ end
end
end