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 | |
parent | 7de3d6851a41d993b1f84eddd3331067a82e8878 (diff) | |
download | lua-language-server-df4fb9b5157cbf11f3fc5f6041afef657f0acfba.zip |
diag `missing-return`
Diffstat (limited to 'script')
-rw-r--r-- | script/config/config.lua | 2 | ||||
-rw-r--r-- | script/core/completion/completion.lua | 1 | ||||
-rw-r--r-- | script/core/diagnostics/missing-return.lua | 84 | ||||
-rw-r--r-- | script/lclient.lua | 1 | ||||
-rw-r--r-- | script/parser/compile.lua | 6 | ||||
-rw-r--r-- | script/parser/guide.lua | 6 | ||||
-rw-r--r-- | script/proto/diagnostic.lua | 1 | ||||
-rw-r--r-- | script/pub/pub.lua | 2 | ||||
-rw-r--r-- | script/vm/compiler.lua | 8 | ||||
-rw-r--r-- | script/vm/value.lua | 2 | ||||
-rw-r--r-- | script/workspace/scope.lua | 5 |
11 files changed, 104 insertions, 14 deletions
diff --git a/script/config/config.lua b/script/config/config.lua index df998990..fb72e7c9 100644 --- a/script/config/config.lua +++ b/script/config/config.lua @@ -38,7 +38,7 @@ local function getScope(uri, key) end end if uri then - ---@type scope + ---@type scope? local scp = scope.getFolder(uri) or scope.getLinkedScope(uri) if scp then if not key diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index 6b63809e..c9359e9a 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -1133,7 +1133,6 @@ local function cleanEnums(enums, source) return enums end ----@return boolean local function insertEnum(state, src, enums, isInArray) if src.type == 'doc.type.string' or src.type == 'doc.type.integer' 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 diff --git a/script/lclient.lua b/script/lclient.lua index 680012db..e1504e61 100644 --- a/script/lclient.lua +++ b/script/lclient.lua @@ -80,7 +80,6 @@ function mt:reportHangs() end ---@param callback async fun(client: languageClient) ----@return languageClient function mt:start(callback) CLI = true diff --git a/script/parser/compile.lua b/script/parser/compile.lua index 83153614..8c5979f7 100644 --- a/script/parser/compile.lua +++ b/script/parser/compile.lua @@ -2833,7 +2833,8 @@ local function compileExpAsAction(exp) local block = Chunk[i] if block.type == 'ifblock' or block.type == 'elseifblock' - or block.type == 'else' then + or block.type == 'elseblock' + or block.type == 'function' then block.hasError = true break end @@ -2986,7 +2987,8 @@ local function parseReturn() local block = Chunk[i] if block.type == 'ifblock' or block.type == 'elseifblock' - or block.type == 'else' then + or block.type == 'elseblock' + or block.type == 'function' then block.hasReturn = true break end diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 1ba28d4d..83c84964 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -1276,4 +1276,10 @@ function m.isBasicType(str) return basicTypeMap[str] == true end +---@param source parser.object +---@return boolean +function m.isBlockType(source) + return blockTypes[source.type] == true +end + return m diff --git a/script/proto/diagnostic.lua b/script/proto/diagnostic.lua index e449d864..25f187db 100644 --- a/script/proto/diagnostic.lua +++ b/script/proto/diagnostic.lua @@ -60,6 +60,7 @@ m.register { 'missing-parameter', 'missing-return-value', 'redundant-return-value', + 'missing-return', } { group = 'unbalanced', severity = 'Warning', diff --git a/script/pub/pub.lua b/script/pub/pub.lua index 47591ee6..1e9b6c8f 100644 --- a/script/pub/pub.lua +++ b/script/pub/pub.lua @@ -136,8 +136,6 @@ function m.task(name, params, callback) end --- 接收反馈 ---- 返回接收到的反馈数量 ----@return integer function m.recieve(block) if block then local id, name, result = waiter:bpop() diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index b2cdb1be..f42a4768 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -492,6 +492,7 @@ function vm.getReturnOfFunction(func, index) end return vm.createGeneric(rtn, sign) end + return nil end ---@return vm.node @@ -976,7 +977,6 @@ local function compileForVars(source) end ---@param source parser.object ----@return vm.node local function compileLocal(source) vm.setNode(source, source) @@ -1077,7 +1077,7 @@ local binarySwich = util.switch() : call(function (source) local node1 = vm.compileNode(source[1]) local node2 = vm.compileNode(source[2]) - local r1 = vm.test(source[1]) + local r1 = vm.testCondition(source[1]) if r1 == true then vm.setNode(source, node2) elseif r1 == false then @@ -1090,7 +1090,7 @@ local binarySwich = util.switch() : call(function (source) local node1 = vm.compileNode(source[1]) local node2 = vm.compileNode(source[2]) - local r1 = vm.test(source[1]) + local r1 = vm.testCondition(source[1]) if r1 == true then vm.setNode(source, node1) elseif r1 == false then @@ -1784,7 +1784,7 @@ local compilerSwitch = util.switch() return end if source.op.type == 'not' then - local result = vm.test(source[1]) + local result = vm.testCondition(source[1]) if result == nil then vm.setNode(source, vm.declareGlobal('type', 'boolean')) return diff --git a/script/vm/value.lua b/script/vm/value.lua index 0ebf5d08..d826d908 100644 --- a/script/vm/value.lua +++ b/script/vm/value.lua @@ -4,7 +4,7 @@ local vm = require 'vm.vm' ---@param source parser.object? ---@return boolean|nil -function vm.test(source) +function vm.testCondition(source) if not source then return nil end diff --git a/script/workspace/scope.lua b/script/workspace/scope.lua index a0f4fbf7..85053612 100644 --- a/script/workspace/scope.lua +++ b/script/workspace/scope.lua @@ -164,7 +164,7 @@ function m.createFolder(uri) end ---@param uri uri ----@return scope +---@return scope? function m.getFolder(uri) for _, scope in ipairs(m.folders) do if scope:isChildUri(uri) then @@ -175,7 +175,7 @@ function m.getFolder(uri) end ---@param uri uri ----@return scope +---@return scope? function m.getLinkedScope(uri) if m.override and m.override:isLinkedUri(uri) then return m.override @@ -188,6 +188,7 @@ function m.getLinkedScope(uri) if m.fallback:isLinkedUri(uri) then return m.fallback end + return nil end ---@param uri uri |