diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2024-09-09 10:33:19 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-09 10:33:19 +0800 |
commit | d1320ae5e41086fd9f569c2504a88130447444b8 (patch) | |
tree | 26286c0fbed38d80d7c7b8efb36092c19b8544c7 /script | |
parent | c9d819305b6f88b53de294d54c820681518430c8 (diff) | |
parent | fe84a713afe4a37629cc95ca3d8a3e9c23be8eb8 (diff) | |
download | lua-language-server-d1320ae5e41086fd9f569c2504a88130447444b8.zip |
Merge pull request #2838 from tomlau10/fix/func_type_union_overload
Fix incorrect function params' type infer when there is only `@overload`
Diffstat (limited to 'script')
-rw-r--r-- | script/vm/compiler.lua | 10 | ||||
-rw-r--r-- | script/vm/function.lua | 31 |
2 files changed, 40 insertions, 1 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index 041d287e..50f260c2 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -1099,6 +1099,7 @@ local function compileFunctionParam(func, source) -- local call ---@type fun(f: fun(x: number));call(function (x) end) --> x -> number local funcNode = vm.compileNode(func) + local found = false for n in funcNode:eachObject() do if n.type == 'doc.type.function' and n.args[aindex] then local argNode = vm.compileNode(n.args[aindex]) @@ -1107,9 +1108,16 @@ local function compileFunctionParam(func, source) vm.setNode(source, an) end end - return true + -- NOTE: keep existing behavior for local call which only set type based on the 1st match + if func.parent.type == 'callargs' then + return true + end + found = true end end + if found then + return true + end local derviationParam = config.get(guide.getUri(func), 'Lua.type.inferParamType') if derviationParam and func.parent.type == 'local' and func.parent.ref then diff --git a/script/vm/function.lua b/script/vm/function.lua index 7a15ac5a..21a432c1 100644 --- a/script/vm/function.lua +++ b/script/vm/function.lua @@ -359,6 +359,7 @@ end ---@return number local function calcFunctionMatchScore(uri, args, func) if vm.isVarargFunctionWithOverloads(func) + or vm.isFunctionWithOnlyOverloads(func) or not isAllParamMatched(uri, args, func.args) then return -1 @@ -490,6 +491,36 @@ function vm.isVarargFunctionWithOverloads(func) return false end +---@param func table +---@return boolean +function vm.isFunctionWithOnlyOverloads(func) + if func.type ~= 'function' then + return false + end + if func._onlyOverloadFunction ~= nil then + return func._onlyOverloadFunction + end + + if not func.bindDocs then + func._onlyOverloadFunction = false + return false + end + local hasOverload = false + for _, doc in ipairs(func.bindDocs) do + if doc.type == 'doc.overload' then + hasOverload = true + elseif doc.type == 'doc.param' + or doc.type == 'doc.return' + then + -- has specified @param or @return, thus not only @overload + func._onlyOverloadFunction = false + return false + end + end + func._onlyOverloadFunction = hasOverload + return true +end + ---@param func parser.object ---@return boolean function vm.isEmptyFunction(func) |