summaryrefslogtreecommitdiff
path: root/script/vm/compiler.lua
diff options
context:
space:
mode:
authorfesily <fesil@foxmail.com>2024-01-10 11:03:21 +0800
committerGitHub <noreply@github.com>2024-01-10 11:03:21 +0800
commit1e7bb72ad3ff2b75a1c55ee4bc53004cb7fe30f7 (patch)
treedd94cf09b9e3a675a73a9f1d41248d1538165997 /script/vm/compiler.lua
parentbb6e172d6166190bd4edd3bb56230a7d60ebcb93 (diff)
parent37779f9b2493e51e59e1e4366bf7dcb8350e69bd (diff)
downloadlua-language-server-1e7bb72ad3ff2b75a1c55ee4bc53004cb7fe30f7.zip
Merge branch 'LuaLS:master' into plugin-add-OnTransformAst
Diffstat (limited to 'script/vm/compiler.lua')
-rw-r--r--script/vm/compiler.lua139
1 files changed, 99 insertions, 40 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 6b4636fc..8a1fa96a 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -7,10 +7,14 @@ local files = require 'files'
local vm = require 'vm.vm'
---@class parser.object
----@field _compiledNodes boolean
----@field _node vm.node
----@field cindex integer
----@field func parser.object
+---@field _compiledNodes boolean
+---@field _node vm.node
+---@field cindex integer
+---@field func parser.object
+---@field hideView boolean
+---@field package _returns? parser.object[]
+---@field package _callReturns? parser.object[]
+---@field package _asCache? parser.object[]
-- 该函数有副作用,会给source绑定node!
---@param source parser.object
@@ -28,6 +32,12 @@ function vm.bindDocs(source)
end
if doc.type == 'doc.class' then
vm.setNode(source, vm.compileNode(doc))
+ for j = i + 1, #docs do
+ local overload = docs[j]
+ if overload.type == 'doc.overload' then
+ overload.overload.hideView = true
+ end
+ end
return true
end
if doc.type == 'doc.param' then
@@ -55,6 +65,9 @@ function vm.bindDocs(source)
vm.setNode(source, vm.compileNode(ast))
return true
end
+ if doc.type == 'doc.overload' then
+ vm.setNode(source, vm.compileNode(doc))
+ end
end
return false
end
@@ -473,6 +486,7 @@ function vm.getReturnOfFunction(func, index)
func._returns = {}
end
if not func._returns[index] then
+ ---@diagnostic disable-next-line: missing-fields
func._returns[index] = {
type = 'function.return',
parent = func,
@@ -570,6 +584,7 @@ local function getReturn(func, index, args)
end
if not func._callReturns[index] then
local call = func.parent
+ ---@diagnostic disable-next-line: missing-fields
func._callReturns[index] = {
type = 'call.return',
parent = call,
@@ -756,6 +771,11 @@ function vm.selectNode(list, index)
if not exp then
return vm.createNode(vm.declareGlobal('type', 'nil')), nil
end
+
+ if vm.bindDocs(list) then
+ return vm.compileNode(list), exp
+ end
+
---@type vm.node?
local result
if exp.type == 'call' then
@@ -862,52 +882,69 @@ local function compileCallArgNode(arg, call, callNode, fixIndex, myIndex)
end
end
- for n in callNode:eachObject() do
- if n.type == 'function' then
- ---@cast n parser.object
- local sign = vm.getSign(n)
+ ---@param n parser.object
+ local function dealDocFunc(n)
+ local myEvent
+ if n.args[eventIndex] then
+ local argNode = vm.compileNode(n.args[eventIndex])
+ myEvent = argNode:get(1)
+ end
+ if not myEvent
+ or not eventMap
+ or myIndex <= eventIndex
+ or myEvent.type ~= 'doc.type.string'
+ or eventMap[myEvent[1]] then
local farg = getFuncArg(n, myIndex)
if farg then
for fn in vm.compileNode(farg):eachObject() do
if isValidCallArgNode(arg, fn) then
- if fn.type == 'doc.type.function' then
- ---@cast fn parser.object
- if sign then
- local generic = vm.createGeneric(fn, sign)
- local args = {}
- for i = fixIndex + 1, myIndex - 1 do
- args[#args+1] = call.args[i]
- end
- local resolvedNode = generic:resolve(guide.getUri(call), args)
- vm.setNode(arg, resolvedNode)
- goto CONTINUE
- end
- end
vm.setNode(arg, fn)
- ::CONTINUE::
end
end
end
end
- if n.type == 'doc.type.function' then
- ---@cast n parser.object
- local myEvent
- if n.args[eventIndex] then
- local argNode = vm.compileNode(n.args[eventIndex])
- myEvent = argNode:get(1)
- end
- if not myEvent
- or not eventMap
- or myIndex <= eventIndex
- or myEvent.type ~= 'doc.type.string'
- or eventMap[myEvent[1]] then
- local farg = getFuncArg(n, myIndex)
- if farg then
- for fn in vm.compileNode(farg):eachObject() do
- if isValidCallArgNode(arg, fn) then
- vm.setNode(arg, fn)
+ end
+
+ ---@param n parser.object
+ local function dealFunction(n)
+ local sign = vm.getSign(n)
+ local farg = getFuncArg(n, myIndex)
+ if farg then
+ for fn in vm.compileNode(farg):eachObject() do
+ if isValidCallArgNode(arg, fn) then
+ if fn.type == 'doc.type.function' then
+ ---@cast fn parser.object
+ if sign then
+ local generic = vm.createGeneric(fn, sign)
+ local args = {}
+ for i = fixIndex + 1, myIndex - 1 do
+ args[#args+1] = call.args[i]
+ end
+ local resolvedNode = generic:resolve(guide.getUri(call), args)
+ vm.setNode(arg, resolvedNode)
+ goto CONTINUE
end
end
+ vm.setNode(arg, fn)
+ ::CONTINUE::
+ end
+ end
+ end
+ end
+
+ for n in callNode:eachObject() do
+ if n.type == 'function' then
+ ---@cast n parser.object
+ dealFunction(n)
+ elseif n.type == 'doc.type.function' then
+ ---@cast n parser.object
+ dealDocFunc(n)
+ elseif n.type == 'global' and n.cate == 'type' then
+ ---@cast n vm.global
+ local overloads = vm.getOverloadsByTypeName(n.name, guide.getUri(arg))
+ if overloads then
+ for _, func in ipairs(overloads) do
+ dealDocFunc(func)
end
end
end
@@ -1020,6 +1057,7 @@ local function compileLocal(source)
vm.setNode(source, vm.compileNode(source.value))
end
end
+
-- function x.y(self, ...) --> function x:y(...)
if source[1] == 'self'
and not hasMarkDoc
@@ -1031,6 +1069,7 @@ local function compileLocal(source)
vm.setNode(source, vm.compileNode(setfield.node))
end
end
+
if source.parent.type == 'funcargs' and not hasMarkDoc and not hasMarkParam then
local func = source.parent.parent
-- local call ---@type fun(f: fun(x: number));call(function (x) end) --> x -> number
@@ -1055,6 +1094,7 @@ local function compileLocal(source)
vm.setNode(source, vm.declareGlobal('type', 'any'))
end
end
+
-- for x in ... do
if source.parent.type == 'in' then
compileForVars(source.parent, source)
@@ -1094,6 +1134,12 @@ local function compileLocal(source)
end
end
+ if source.value
+ and source.value.type == 'nil'
+ and not myNode:hasKnownType() then
+ vm.setNode(source, vm.compileNode(source.value))
+ end
+
myNode.hasDefined = hasMarkDoc or hasMarkParam or hasMarkValue
end
@@ -1140,6 +1186,9 @@ local compilerSwitch = util.switch()
end)
: case 'table'
: call(function (source)
+ if vm.bindAs(source) then
+ return
+ end
vm.setNode(source, source)
if source.parent.type == 'callargs' then
@@ -1147,6 +1196,16 @@ local compilerSwitch = util.switch()
vm.compileCallArg(source, call)
end
+ if source.parent.type == 'return' then
+ local myIndex = util.arrayIndexOf(source.parent, source)
+ ---@cast myIndex -?
+ local parentNode = vm.selectNode(source.parent, myIndex)
+ if not parentNode:isEmpty() then
+ vm.setNode(source, parentNode)
+ return
+ end
+ end
+
if source.parent.type == 'setglobal'
or source.parent.type == 'local'
or source.parent.type == 'setlocal'
@@ -1648,7 +1707,7 @@ local compilerSwitch = util.switch()
if state.type == 'doc.return'
or state.type == 'doc.param' then
local func = state.bindSource
- if func.type == 'function' then
+ if func and func.type == 'function' then
local node = guide.getFunctionSelfNode(func)
if node then
vm.setNode(source, vm.compileNode(node))