summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-06-28 16:28:33 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-06-28 16:28:33 +0800
commitdf4fb9b5157cbf11f3fc5f6041afef657f0acfba (patch)
tree84f65cb0adff35c8e2563d321dc99530010c5a6b /script
parent7de3d6851a41d993b1f84eddd3331067a82e8878 (diff)
downloadlua-language-server-df4fb9b5157cbf11f3fc5f6041afef657f0acfba.zip
diag `missing-return`
Diffstat (limited to 'script')
-rw-r--r--script/config/config.lua2
-rw-r--r--script/core/completion/completion.lua1
-rw-r--r--script/core/diagnostics/missing-return.lua84
-rw-r--r--script/lclient.lua1
-rw-r--r--script/parser/compile.lua6
-rw-r--r--script/parser/guide.lua6
-rw-r--r--script/proto/diagnostic.lua1
-rw-r--r--script/pub/pub.lua2
-rw-r--r--script/vm/compiler.lua8
-rw-r--r--script/vm/value.lua2
-rw-r--r--script/workspace/scope.lua5
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