summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-08-08 20:24:54 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-08-08 20:24:54 +0800
commit9b5ac5353c6c63e09d7b8862fb9f5535d5f014fb (patch)
tree72b1aa863bd7d92a5ba5ba9ce95f78f170ebb1c1
parent35c3ffc8690b265e93b37575989206e15275b5a9 (diff)
downloadlua-language-server-9b5ac5353c6c63e09d7b8862fb9f5535d5f014fb.zip
fix #1409
-rw-r--r--changelog.md3
-rw-r--r--script/core/hover/return.lua32
-rw-r--r--script/vm/function.lua69
-rw-r--r--test/hover/init.lua33
4 files changed, 62 insertions, 75 deletions
diff --git a/changelog.md b/changelog.md
index 18d8569a..a3464247 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,8 @@
# changelog
+## 3.5.3
+* `FIX` [#1409](https://github.com/sumneko/lua-language-server/issues/1409)
+
## 3.5.2
`2022-8-1`
* `FIX` [#1395](https://github.com/sumneko/lua-language-server/issues/1395)
diff --git a/script/core/hover/return.lua b/script/core/hover/return.lua
index b496990b..b71b9e5d 100644
--- a/script/core/hover/return.lua
+++ b/script/core/hover/return.lua
@@ -2,36 +2,6 @@ local vm = require 'vm.vm'
local guide = require 'parser.guide'
---@param source parser.object
----@return integer
-local function countReturns(source)
- local n = 0
-
- local docs = source.bindDocs
- if docs then
- for _, doc in ipairs(docs) do
- if doc.type == 'doc.return' then
- for _, rtn in ipairs(doc.returns) do
- if rtn.returnIndex and rtn.returnIndex > n then
- n = rtn.returnIndex
- end
- end
- end
- end
- end
-
- local returns = source.returns
- if returns then
- for _, rtn in ipairs(returns) do
- if #rtn > n then
- n = #rtn
- end
- end
- end
-
- return n
-end
-
----@param source parser.object
---@return parser.object[]
local function getReturnDocs(source)
local returns = {}
@@ -51,7 +21,7 @@ local function getReturnDocs(source)
end
local function asFunction(source)
- local num = countReturns(source)
+ local _, _, num = vm.countReturnsOfFunction(source)
if num == 0 then
return nil
end
diff --git a/script/vm/function.lua b/script/vm/function.lua
index f64b2262..7cde6298 100644
--- a/script/vm/function.lua
+++ b/script/vm/function.lua
@@ -19,12 +19,15 @@ end
---@param func parser.object
---@return integer min
---@return number max
+---@return integer def
function vm.countParamsOfFunction(func)
local min = 0
local max = 0
+ local def = 0
if func.type == 'function' then
if func.args then
max = #func.args
+ def = max
for i = #func.args, 1, -1 do
local arg = func.args[i]
if arg.type == '...' then
@@ -44,6 +47,7 @@ function vm.countParamsOfFunction(func)
if func.type == 'doc.type.function' then
if func.args then
max = #func.args
+ def = max
for i = #func.args, 1, -1 do
local arg = func.args[i]
if arg.name and arg.name[1] =='...' then
@@ -55,28 +59,32 @@ function vm.countParamsOfFunction(func)
end
end
end
- return min, max
+ return min, max, def
end
---@param node vm.node
---@return integer min
---@return number max
+---@return integer def
function vm.countParamsOfNode(node)
- local min, max
+ local min, max, def
for n in node:eachObject() do
if n.type == 'function'
or n.type == 'doc.type.function' then
---@cast n parser.object
- local fmin, fmax = vm.countParamsOfFunction(n)
+ local fmin, fmax, fdef = vm.countParamsOfFunction(n)
if not min or fmin < min then
min = fmin
end
if not max or fmax > max then
max = fmax
end
+ if not def or fdef > def then
+ def = fdef
+ end
end
end
- return min or 0, max or math.huge
+ return min or 0, max or math.huge, def or 0
end
---@param func parser.object
@@ -84,20 +92,17 @@ end
---@param mark? table
---@return integer min
---@return number max
+---@return integer def
function vm.countReturnsOfFunction(func, onlyDoc, mark)
if func.type == 'function' then
- ---@type integer?
- local min
- ---@type number?
- local max
+ ---@type integer?, number?, integer?
+ local min, max, def
local hasDocReturn
if func.bindDocs then
local lastReturn
local n = 0
- ---@type integer?
- local dmin
- ---@type number?
- local dmax
+ ---@type integer?, number?, integer?
+ local dmin, dmax, ddef
for _, doc in ipairs(func.bindDocs) do
if doc.type == 'doc.return' then
hasDocReturn = true
@@ -105,6 +110,7 @@ function vm.countReturnsOfFunction(func, onlyDoc, mark)
n = n + 1
lastReturn = ret
dmax = n
+ ddef = n
if (not ret.name or ret.name[1] ~= '...')
and not vm.compileNode(ret):isNullable() then
dmin = n
@@ -123,19 +129,25 @@ function vm.countReturnsOfFunction(func, onlyDoc, mark)
if dmax and (not max or (dmax > max)) then
max = dmax
end
+ if ddef and (not def or (ddef > def)) then
+ def = ddef
+ end
end
if not onlyDoc and not hasDocReturn and func.returns then
for _, ret in ipairs(func.returns) do
- local rmin, rmax = vm.countList(ret, mark)
+ local rmin, rmax, ddef = vm.countList(ret, mark)
if not min or rmin < min then
min = rmin
end
if not max or rmax > max then
max = rmax
end
+ if not def or ddef > def then
+ def = ddef
+ end
end
end
- return min or 0, max or math.huge
+ return min or 0, max or math.huge, def or 0
end
if func.type == 'doc.type.function' then
return vm.countList(func.returns)
@@ -147,52 +159,55 @@ end
---@param mark? table
---@return integer min
---@return number max
+---@return integer def
function vm.countReturnsOfCall(func, args, mark)
local funcs = vm.getMatchedFunctions(func, args, mark)
- ---@type integer?
- local min
- ---@type number?
- local max
+ ---@type integer?, number?, integer?
+ local min, max, def
for _, f in ipairs(funcs) do
- local rmin, rmax = vm.countReturnsOfFunction(f, false, mark)
+ local rmin, rmax, rdef = vm.countReturnsOfFunction(f, false, mark)
if not min or rmin < min then
min = rmin
end
if not max or rmax > max then
max = rmax
end
+ if not def or rdef > def then
+ def = rdef
+ end
end
- return min or 0, max or math.huge
+ return min or 0, max or math.huge, def or 0
end
---@param list parser.object[]?
---@param mark? table
---@return integer min
---@return number max
+---@return integer def
function vm.countList(list, mark)
if not list then
- return 0, 0
+ return 0, 0, 0
end
local lastArg = list[#list]
if not lastArg then
- return 0, 0
+ return 0, 0, 0
end
if lastArg.type == '...'
or lastArg.type == 'varargs' then
- return #list - 1, math.huge
+ return #list - 1, math.huge, #list
end
if lastArg.type == 'call' then
if not mark then
mark = {}
end
if mark[lastArg] then
- return #list - 1, math.huge
+ return #list - 1, math.huge, #list
end
mark[lastArg] = true
- local rmin, rmax = vm.countReturnsOfCall(lastArg.node, lastArg.args, mark)
- return #list - 1 + rmin, #list - 1 + rmax
+ local rmin, rmax, rdef = vm.countReturnsOfCall(lastArg.node, lastArg.args, mark)
+ return #list - 1 + rmin, #list - 1 + rmax, #list - 1 + rdef
end
- return #list, #list
+ return #list, #list, #list
end
---@param func parser.object
diff --git a/test/hover/init.lua b/test/hover/init.lua
index 40474bf5..e720ffc2 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -5,22 +5,6 @@ local config = require 'config'
rawset(_G, 'TEST', true)
-local accept = {
- ['local'] = true,
- ['setlocal'] = true,
- ['getlocal'] = true,
- ['setglobal'] = true,
- ['getglobal'] = true,
- ['field'] = true,
- ['method'] = true,
- ['string'] = true,
- ['number'] = true,
- ['integer'] = true,
- ['doc.type.name'] = true,
- ['doc.class.name'] = true,
- ['function'] = true,
-}
-
---@diagnostic disable: await-in-sync
function TEST(script)
return function (expect)
@@ -312,7 +296,6 @@ end
]]
[[
function x()
- -> unknown
]]
TEST [[
@@ -2137,3 +2120,19 @@ local <?x?> = 1 << 2
[[
local x: integer = 4
]]
+
+TEST [[
+local function test1()
+ return 1, 2, 3
+end
+
+local function <?test2?>()
+ return test1()
+end
+]]
+[[
+function test2()
+ -> integer
+ 2. integer
+ 3. integer
+]]