diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-08-08 20:24:54 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-08-08 20:24:54 +0800 |
commit | 9b5ac5353c6c63e09d7b8862fb9f5535d5f014fb (patch) | |
tree | 72b1aa863bd7d92a5ba5ba9ce95f78f170ebb1c1 /script/vm | |
parent | 35c3ffc8690b265e93b37575989206e15275b5a9 (diff) | |
download | lua-language-server-9b5ac5353c6c63e09d7b8862fb9f5535d5f014fb.zip |
fix #1409
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/function.lua | 69 |
1 files changed, 42 insertions, 27 deletions
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 |