summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
Diffstat (limited to 'script')
-rw-r--r--script/core/diagnostics/unreachable-code.lua68
-rw-r--r--script/proto/diagnostic.lua1
2 files changed, 69 insertions, 0 deletions
diff --git a/script/core/diagnostics/unreachable-code.lua b/script/core/diagnostics/unreachable-code.lua
new file mode 100644
index 00000000..28aee6ea
--- /dev/null
+++ b/script/core/diagnostics/unreachable-code.lua
@@ -0,0 +1,68 @@
+local files = require 'files'
+local guide = require 'parser.guide'
+local vm = require 'vm'
+local lang = require 'language'
+local await = require 'await'
+
+---@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
+
+---@async
+return function (uri, callback)
+ local state = files.getState(uri)
+ if not state then
+ return
+ end
+
+ ---@async
+ guide.eachSourceTypes(state.ast, {'main', 'function'}, function (source)
+ await.delay()
+ if not source.returns then
+ return
+ end
+ for i, action in ipairs(source) do
+ if guide.isBlockType(action)
+ and hasReturn(action) then
+ if i < #source then
+ callback {
+ start = source[i+1].start,
+ finish = source[#source].finish,
+ message = lang.script('DIAG_UNREACHABLE_CODE'),
+ }
+ end
+ return
+ end
+ end
+ end)
+end
diff --git a/script/proto/diagnostic.lua b/script/proto/diagnostic.lua
index d8312dfe..dc550fac 100644
--- a/script/proto/diagnostic.lua
+++ b/script/proto/diagnostic.lua
@@ -47,6 +47,7 @@ m.register {
'redundant-return',
'empty-block',
'code-after-break',
+ 'unreachable-code',
} {
group = 'unused',
severity = 'Hint',