diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-06-28 16:28:33 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-06-28 16:28:33 +0800 |
commit | df4fb9b5157cbf11f3fc5f6041afef657f0acfba (patch) | |
tree | 84f65cb0adff35c8e2563d321dc99530010c5a6b /script/core/diagnostics | |
parent | 7de3d6851a41d993b1f84eddd3331067a82e8878 (diff) | |
download | lua-language-server-df4fb9b5157cbf11f3fc5f6041afef657f0acfba.zip |
diag `missing-return`
Diffstat (limited to 'script/core/diagnostics')
-rw-r--r-- | script/core/diagnostics/missing-return.lua | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/script/core/diagnostics/missing-return.lua b/script/core/diagnostics/missing-return.lua new file mode 100644 index 00000000..08932c83 --- /dev/null +++ b/script/core/diagnostics/missing-return.lua @@ -0,0 +1,84 @@ +local files = require 'files' +local guide = require 'parser.guide' +local vm = require 'vm' +local lang = require 'language' + +---@param uri uri +---@param func parser.object +local function hasDocReturn(uri, func) + if not func.bindDocs then + return false + end + for _, doc in ipairs(func.bindDocs) do + if doc.type == 'doc.return' then + -- don't need return with only one `any` + local lastReturn = doc.returns[#doc.returns] + if lastReturn.returnIndex ~= 1 + or vm.getInfer(lastReturn):view(uri) ~= 'any' then + return true + end + end + end + return false +end + +---@param block parser.object +---@return boolean +local function hasReturn(block) + if block.hasReturn or block.hasError then + return true + end + if block.type == 'if' then + local hasElse + for _, subBlock in ipairs(block) do + if not hasReturn(subBlock) then + return false + end + if subBlock.type == 'elseblock' then + hasElse = true + end + end + return hasElse == true + else + if block.type == 'while' then + if vm.testCondition(block.filter) then + return true + end + end + for _, action in ipairs(block) do + if guide.isBlockType(action) then + if hasReturn(action) then + return true + end + end + 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) + -- check declare only + if #source == 0 then + return + end + if not hasDocReturn(uri, source) then + return + end + if hasReturn(source) then + return + end + local lastAction = source[#source] + local finish = lastAction.range or lastAction.finish + callback { + start = finish, + finish = finish, + message = lang.script('DIAG_MISSING_RETURN'), + } + end) +end |