diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-06-27 19:07:46 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-06-27 19:07:46 +0800 |
commit | edc9797838506728ba65a50b94781ac99e3bdd86 (patch) | |
tree | 27aac9c1216cc2075621ad36da57183111cd6c22 /script | |
parent | cae348536cef3f2f5f96c5821c7e45539aeff1cf (diff) | |
download | lua-language-server-edc9797838506728ba65a50b94781ac99e3bdd86.zip |
diagnostic `missing-return-value`
Diffstat (limited to 'script')
-rw-r--r-- | script/core/diagnostics/missing-return-value.lua | 62 | ||||
-rw-r--r-- | script/parser/guide.lua | 2 | ||||
-rw-r--r-- | script/proto/diagnostic.lua | 1 | ||||
-rw-r--r-- | script/vm/function.lua | 26 |
4 files changed, 78 insertions, 13 deletions
diff --git a/script/core/diagnostics/missing-return-value.lua b/script/core/diagnostics/missing-return-value.lua new file mode 100644 index 00000000..491475c7 --- /dev/null +++ b/script/core/diagnostics/missing-return-value.lua @@ -0,0 +1,62 @@ +local files = require 'files' +local guide = require 'parser.guide' +local vm = require 'vm' +local lang = require 'language' + +local function hasDocReturn(func) + if not func.bindDocs then + return false + end + for _, doc in ipairs(func.bindDocs) do + if doc.type == 'doc.return' then + return true + end + end + return false +end + +return function (uri, callback) + local state = files.getState(uri) + if not state then + return + end + + guide.eachSourceType(state.ast, 'function', function (source) + if not hasDocReturn(source) then + return + end + local min = vm.countReturnsOfFunction(source) + if min == 0 then + return + end + local returns = source.returns + if not returns then + return + end + for _, ret in ipairs(returns) do + local rmin, rmax = vm.countList(ret) + if rmax < min then + if rmin == rmax then + callback { + start = ret.start, + finish = ret.start + #'return', + message = lang.script('DIAG_MISSING_RETURN_VALUE', { + min = min, + rmax = rmax, + }), + } + else + callback { + start = ret.start, + finish = ret.start + #'return', + message = lang.script('DIAG_MISSING_RETURN_VALUE', { + min = min, + rmin = rmin, + rmax = rmax, + }), + } + end + end + end + end) +end diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 56239fb1..a91a6f68 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -12,7 +12,7 @@ local type = type ---@field tag string ---@field args { [integer]: parser.object, start: integer, finish: integer } ---@field locals parser.object[] ----@field returns parser.object[] +---@field returns? parser.object[] ---@field exps parser.object[] ---@field keys parser.object[] ---@field uri uri diff --git a/script/proto/diagnostic.lua b/script/proto/diagnostic.lua index 59f33693..5972150c 100644 --- a/script/proto/diagnostic.lua +++ b/script/proto/diagnostic.lua @@ -58,6 +58,7 @@ m.register { 'unbalanced-assignments', 'redundant-parameter', 'missing-parameter', + 'missing-return-value', } { group = 'unbalanced', severity = 'Warning', diff --git a/script/vm/function.lua b/script/vm/function.lua index f992845f..8e3662e2 100644 --- a/script/vm/function.lua +++ b/script/vm/function.lua @@ -86,24 +86,15 @@ end function vm.countReturnsOfFunction(func, mark) if func.type == 'function' then local min, max - if func.returns then - for _, ret in ipairs(func.returns) do - local rmin, rmax = vm.countList(ret, mark) - if not min or rmin < min then - min = rmin - end - if not max or rmax > max then - max = rmax - end - end - end + local hasDocReturn if func.bindDocs then local lastReturn local n = 0 local dmin, dmax for _, doc in ipairs(func.bindDocs) do if doc.type == 'doc.return' then - for _, ret in ipairs(doc) do + hasDocReturn = true + for _, ret in ipairs(doc.returns) do n = n + 1 lastReturn = ret dmax = n @@ -128,6 +119,17 @@ function vm.countReturnsOfFunction(func, mark) max = dmax end end + if not hasDocReturn and func.returns then + for _, ret in ipairs(func.returns) do + local rmin, rmax = vm.countList(ret, mark) + if not min or rmin < min then + min = rmin + end + if not max or rmax > max then + max = rmax + end + end + end return min or 0, max or math.huge end if func.type == 'doc.type.function' then |