diff options
-rw-r--r-- | changelog.md | 3 | ||||
-rw-r--r-- | script/core/hover/return.lua | 32 | ||||
-rw-r--r-- | script/vm/function.lua | 69 | ||||
-rw-r--r-- | test/hover/init.lua | 33 |
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 +]] |