diff options
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | doc/en-us/config.md | 53 | ||||
-rw-r--r-- | doc/pt-br/config.md | 53 | ||||
-rw-r--r-- | doc/zh-cn/config.md | 53 | ||||
-rw-r--r-- | doc/zh-tw/config.md | 53 | ||||
-rw-r--r-- | locale/en-us/script.lua | 2 | ||||
-rw-r--r-- | locale/pt-br/script.lua | 2 | ||||
-rw-r--r-- | locale/zh-cn/script.lua | 2 | ||||
-rw-r--r-- | locale/zh-tw/script.lua | 2 | ||||
-rw-r--r-- | script/core/diagnostics/unreachable-code.lua | 68 | ||||
-rw-r--r-- | script/proto/diagnostic.lua | 1 | ||||
-rw-r--r-- | test/diagnostics/common.lua | 28 | ||||
-rw-r--r-- | test/type_inference/init.lua | 1 |
13 files changed, 227 insertions, 92 deletions
diff --git a/changelog.md b/changelog.md index 702b06f6..758eb61a 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ ``` * `NEW` diagnostics: * `unknown-operator` + * `unreachable-code` * `NEW` settings: * `diagnostics.unusedLocalExclude` * `CHG` support multi-type: diff --git a/doc/en-us/config.md b/doc/en-us/config.md index 3f483650..137793cc 100644 --- a/doc/en-us/config.md +++ b/doc/en-us/config.md @@ -205,9 +205,9 @@ Array<string> * ``"newfield-call"`` * ``"err-assign-as-eq"`` * ``"undefined-doc-param"`` -* ``"param-type-mismatch"`` +* ``"undefined-global"`` * ``"global-in-nil-env"`` -* ``"unused-vararg"`` +* ``"redundant-return-value"`` * ``"miss-sep-in-table"`` * ``"unknown-cast-variable"`` * ``"unknown-operator"`` @@ -222,66 +222,67 @@ Array<string> * ``"redundant-value"`` * ``"duplicate-doc-alias"`` * ``"doc-field-no-class"`` -* ``"no-visible-label"`` * ``"miss-loop-min"`` -* ``"miss-exp"`` +* ``"no-visible-label"`` * ``"miss-loop-max"`` +* ``"miss-exp"`` +* ``"unicode-name"`` * ``"miss-name"`` * ``"empty-block"`` -* ``"unused-local"`` * ``"err-then-as-do"`` -* ``"duplicate-doc-field"`` * ``"redefined-label"`` +* ``"duplicate-doc-field"`` * ``"exp-in-action"`` * ``"set-const"`` -* ``"circle-doc-class"`` * ``"unexpect-lfunc-name"`` -* ``"unsupport-symbol"`` -* ``"unused-label"`` +* ``"circle-doc-class"`` * ``"action-after-return"`` +* ``"miss-space-between"`` +* ``"unused-label"`` * ``"unexpect-dots"`` -* ``"redundant-return-value"`` +* ``"duplicate-index"`` +* ``"miss-field"`` * ``"jump-local-scope"`` * ``"close-non-object"`` -* ``"miss-field"`` +* ``"unexpect-symbol"`` * ``"count-down-loop"`` * ``"cast-type-mismatch"`` * ``"newline-call"`` -* ``"unexpect-symbol"`` +* ``"missing-parameter"`` * ``"block-after-else"`` -* ``"unicode-name"`` * ``"miss-exponent"`` * ``"err-esc"`` * ``"local-limit"`` +* ``"unsupport-symbol"`` * ``"trailing-space"`` * ``"err-c-long-comment"`` -* ``"undefined-global"`` -* ``"undefined-doc-name"`` +* ``"unbalanced-assignments"`` +* ``"duplicate-doc-param"`` * ``"ambiguity-1"`` * ``"deprecated"`` * ``"codestyle-check"`` * ``"missing-return"`` -* ``"missing-parameter"`` +* ``"code-after-break"`` * ``"unused-function"`` * ``"cast-local-type"`` * ``"assign-type-mismatch"`` * ``"duplicate-set-field"`` -* ``"no-unknown"`` +* ``"unused-vararg"`` * ``"need-check-nil"`` * ``"keyword"`` +* ``"unused-local"`` * ``"unknown-diag-code"`` -* ``"return-type-mismatch"`` * ``"err-comment-prefix"`` * ``"lowercase-global"`` -* ``"unbalanced-assignments"`` * ``"redefined-local"`` -* ``"code-after-break"`` -* ``"duplicate-index"`` -* ``"duplicate-doc-param"`` +* ``"undefined-doc-name"`` +* ``"no-unknown"`` +* ``"unreachable-code"`` +* ``"param-type-mismatch"`` * ``"index-in-func-name"`` * ``"miss-symbol"`` * ``"undefined-field"`` -* ``"miss-space-between"`` +* ``"return-type-mismatch"`` ## default @@ -450,6 +451,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -568,6 +570,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -737,6 +740,7 @@ object<string, string> "unknown-cast-variable": "Any", "unknown-diag-code": "Any", "unknown-operator": "Any", + "unreachable-code": "Opened", /* Enable unused function diagnostics. */ @@ -872,6 +876,7 @@ object<string, string> "unknown-cast-variable": "Warning", "unknown-diag-code": "Warning", "unknown-operator": "Warning", + "unreachable-code": "Hint", /* Enable unused function diagnostics. */ @@ -1271,6 +1276,8 @@ object<string, string> "package": "default", "string": "default", "table": "default", + "table.clear": "default", + "table.new": "default", "utf8": "default" } ``` diff --git a/doc/pt-br/config.md b/doc/pt-br/config.md index f888efea..97a01630 100644 --- a/doc/pt-br/config.md +++ b/doc/pt-br/config.md @@ -205,9 +205,9 @@ Array<string> * ``"newfield-call"`` * ``"err-assign-as-eq"`` * ``"undefined-doc-param"`` -* ``"param-type-mismatch"`` +* ``"undefined-global"`` * ``"global-in-nil-env"`` -* ``"unused-vararg"`` +* ``"redundant-return-value"`` * ``"miss-sep-in-table"`` * ``"unknown-cast-variable"`` * ``"unknown-operator"`` @@ -222,66 +222,67 @@ Array<string> * ``"redundant-value"`` * ``"duplicate-doc-alias"`` * ``"doc-field-no-class"`` -* ``"no-visible-label"`` * ``"miss-loop-min"`` -* ``"miss-exp"`` +* ``"no-visible-label"`` * ``"miss-loop-max"`` +* ``"miss-exp"`` +* ``"unicode-name"`` * ``"miss-name"`` * ``"empty-block"`` -* ``"unused-local"`` * ``"err-then-as-do"`` -* ``"duplicate-doc-field"`` * ``"redefined-label"`` +* ``"duplicate-doc-field"`` * ``"exp-in-action"`` * ``"set-const"`` -* ``"circle-doc-class"`` * ``"unexpect-lfunc-name"`` -* ``"unsupport-symbol"`` -* ``"unused-label"`` +* ``"circle-doc-class"`` * ``"action-after-return"`` +* ``"miss-space-between"`` +* ``"unused-label"`` * ``"unexpect-dots"`` -* ``"redundant-return-value"`` +* ``"duplicate-index"`` +* ``"miss-field"`` * ``"jump-local-scope"`` * ``"close-non-object"`` -* ``"miss-field"`` +* ``"unexpect-symbol"`` * ``"count-down-loop"`` * ``"cast-type-mismatch"`` * ``"newline-call"`` -* ``"unexpect-symbol"`` +* ``"missing-parameter"`` * ``"block-after-else"`` -* ``"unicode-name"`` * ``"miss-exponent"`` * ``"err-esc"`` * ``"local-limit"`` +* ``"unsupport-symbol"`` * ``"trailing-space"`` * ``"err-c-long-comment"`` -* ``"undefined-global"`` -* ``"undefined-doc-name"`` +* ``"unbalanced-assignments"`` +* ``"duplicate-doc-param"`` * ``"ambiguity-1"`` * ``"deprecated"`` * ``"codestyle-check"`` * ``"missing-return"`` -* ``"missing-parameter"`` +* ``"code-after-break"`` * ``"unused-function"`` * ``"cast-local-type"`` * ``"assign-type-mismatch"`` * ``"duplicate-set-field"`` -* ``"no-unknown"`` +* ``"unused-vararg"`` * ``"need-check-nil"`` * ``"keyword"`` +* ``"unused-local"`` * ``"unknown-diag-code"`` -* ``"return-type-mismatch"`` * ``"err-comment-prefix"`` * ``"lowercase-global"`` -* ``"unbalanced-assignments"`` * ``"redefined-local"`` -* ``"code-after-break"`` -* ``"duplicate-index"`` -* ``"duplicate-doc-param"`` +* ``"undefined-doc-name"`` +* ``"no-unknown"`` +* ``"unreachable-code"`` +* ``"param-type-mismatch"`` * ``"index-in-func-name"`` * ``"miss-symbol"`` * ``"undefined-field"`` -* ``"miss-space-between"`` +* ``"return-type-mismatch"`` ## default @@ -450,6 +451,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -568,6 +570,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -737,6 +740,7 @@ object<string, string> "unknown-cast-variable": "Any", "unknown-diag-code": "Any", "unknown-operator": "Any", + "unreachable-code": "Opened", /* 未使用的函数 */ @@ -872,6 +876,7 @@ object<string, string> "unknown-cast-variable": "Warning", "unknown-diag-code": "Warning", "unknown-operator": "Warning", + "unreachable-code": "Hint", /* 未使用的函数 */ @@ -1271,6 +1276,8 @@ object<string, string> "package": "default", "string": "default", "table": "default", + "table.clear": "default", + "table.new": "default", "utf8": "default" } ``` diff --git a/doc/zh-cn/config.md b/doc/zh-cn/config.md index 3e2b1246..888cb25e 100644 --- a/doc/zh-cn/config.md +++ b/doc/zh-cn/config.md @@ -205,9 +205,9 @@ Array<string> * ``"newfield-call"`` * ``"err-assign-as-eq"`` * ``"undefined-doc-param"`` -* ``"param-type-mismatch"`` +* ``"undefined-global"`` * ``"global-in-nil-env"`` -* ``"unused-vararg"`` +* ``"redundant-return-value"`` * ``"miss-sep-in-table"`` * ``"unknown-cast-variable"`` * ``"unknown-operator"`` @@ -222,66 +222,67 @@ Array<string> * ``"redundant-value"`` * ``"duplicate-doc-alias"`` * ``"doc-field-no-class"`` -* ``"no-visible-label"`` * ``"miss-loop-min"`` -* ``"miss-exp"`` +* ``"no-visible-label"`` * ``"miss-loop-max"`` +* ``"miss-exp"`` +* ``"unicode-name"`` * ``"miss-name"`` * ``"empty-block"`` -* ``"unused-local"`` * ``"err-then-as-do"`` -* ``"duplicate-doc-field"`` * ``"redefined-label"`` +* ``"duplicate-doc-field"`` * ``"exp-in-action"`` * ``"set-const"`` -* ``"circle-doc-class"`` * ``"unexpect-lfunc-name"`` -* ``"unsupport-symbol"`` -* ``"unused-label"`` +* ``"circle-doc-class"`` * ``"action-after-return"`` +* ``"miss-space-between"`` +* ``"unused-label"`` * ``"unexpect-dots"`` -* ``"redundant-return-value"`` +* ``"duplicate-index"`` +* ``"miss-field"`` * ``"jump-local-scope"`` * ``"close-non-object"`` -* ``"miss-field"`` +* ``"unexpect-symbol"`` * ``"count-down-loop"`` * ``"cast-type-mismatch"`` * ``"newline-call"`` -* ``"unexpect-symbol"`` +* ``"missing-parameter"`` * ``"block-after-else"`` -* ``"unicode-name"`` * ``"miss-exponent"`` * ``"err-esc"`` * ``"local-limit"`` +* ``"unsupport-symbol"`` * ``"trailing-space"`` * ``"err-c-long-comment"`` -* ``"undefined-global"`` -* ``"undefined-doc-name"`` +* ``"unbalanced-assignments"`` +* ``"duplicate-doc-param"`` * ``"ambiguity-1"`` * ``"deprecated"`` * ``"codestyle-check"`` * ``"missing-return"`` -* ``"missing-parameter"`` +* ``"code-after-break"`` * ``"unused-function"`` * ``"cast-local-type"`` * ``"assign-type-mismatch"`` * ``"duplicate-set-field"`` -* ``"no-unknown"`` +* ``"unused-vararg"`` * ``"need-check-nil"`` * ``"keyword"`` +* ``"unused-local"`` * ``"unknown-diag-code"`` -* ``"return-type-mismatch"`` * ``"err-comment-prefix"`` * ``"lowercase-global"`` -* ``"unbalanced-assignments"`` * ``"redefined-local"`` -* ``"code-after-break"`` -* ``"duplicate-index"`` -* ``"duplicate-doc-param"`` +* ``"undefined-doc-name"`` +* ``"no-unknown"`` +* ``"unreachable-code"`` +* ``"param-type-mismatch"`` * ``"index-in-func-name"`` * ``"miss-symbol"`` * ``"undefined-field"`` -* ``"miss-space-between"`` +* ``"return-type-mismatch"`` ## default @@ -450,6 +451,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -568,6 +570,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -737,6 +740,7 @@ object<string, string> "unknown-cast-variable": "Any", "unknown-diag-code": "Any", "unknown-operator": "Any", + "unreachable-code": "Opened", /* 未使用的函数 */ @@ -871,6 +875,7 @@ object<string, string> "unknown-cast-variable": "Warning", "unknown-diag-code": "Warning", "unknown-operator": "Warning", + "unreachable-code": "Hint", /* 未使用的函数 */ @@ -1270,6 +1275,8 @@ object<string, string> "package": "default", "string": "default", "table": "default", + "table.clear": "default", + "table.new": "default", "utf8": "default" } ``` diff --git a/doc/zh-tw/config.md b/doc/zh-tw/config.md index dcd44d63..adf09ae6 100644 --- a/doc/zh-tw/config.md +++ b/doc/zh-tw/config.md @@ -205,9 +205,9 @@ Array<string> * ``"newfield-call"`` * ``"err-assign-as-eq"`` * ``"undefined-doc-param"`` -* ``"param-type-mismatch"`` +* ``"undefined-global"`` * ``"global-in-nil-env"`` -* ``"unused-vararg"`` +* ``"redundant-return-value"`` * ``"miss-sep-in-table"`` * ``"unknown-cast-variable"`` * ``"unknown-operator"`` @@ -222,66 +222,67 @@ Array<string> * ``"redundant-value"`` * ``"duplicate-doc-alias"`` * ``"doc-field-no-class"`` -* ``"no-visible-label"`` * ``"miss-loop-min"`` -* ``"miss-exp"`` +* ``"no-visible-label"`` * ``"miss-loop-max"`` +* ``"miss-exp"`` +* ``"unicode-name"`` * ``"miss-name"`` * ``"empty-block"`` -* ``"unused-local"`` * ``"err-then-as-do"`` -* ``"duplicate-doc-field"`` * ``"redefined-label"`` +* ``"duplicate-doc-field"`` * ``"exp-in-action"`` * ``"set-const"`` -* ``"circle-doc-class"`` * ``"unexpect-lfunc-name"`` -* ``"unsupport-symbol"`` -* ``"unused-label"`` +* ``"circle-doc-class"`` * ``"action-after-return"`` +* ``"miss-space-between"`` +* ``"unused-label"`` * ``"unexpect-dots"`` -* ``"redundant-return-value"`` +* ``"duplicate-index"`` +* ``"miss-field"`` * ``"jump-local-scope"`` * ``"close-non-object"`` -* ``"miss-field"`` +* ``"unexpect-symbol"`` * ``"count-down-loop"`` * ``"cast-type-mismatch"`` * ``"newline-call"`` -* ``"unexpect-symbol"`` +* ``"missing-parameter"`` * ``"block-after-else"`` -* ``"unicode-name"`` * ``"miss-exponent"`` * ``"err-esc"`` * ``"local-limit"`` +* ``"unsupport-symbol"`` * ``"trailing-space"`` * ``"err-c-long-comment"`` -* ``"undefined-global"`` -* ``"undefined-doc-name"`` +* ``"unbalanced-assignments"`` +* ``"duplicate-doc-param"`` * ``"ambiguity-1"`` * ``"deprecated"`` * ``"codestyle-check"`` * ``"missing-return"`` -* ``"missing-parameter"`` +* ``"code-after-break"`` * ``"unused-function"`` * ``"cast-local-type"`` * ``"assign-type-mismatch"`` * ``"duplicate-set-field"`` -* ``"no-unknown"`` +* ``"unused-vararg"`` * ``"need-check-nil"`` * ``"keyword"`` +* ``"unused-local"`` * ``"unknown-diag-code"`` -* ``"return-type-mismatch"`` * ``"err-comment-prefix"`` * ``"lowercase-global"`` -* ``"unbalanced-assignments"`` * ``"redefined-local"`` -* ``"code-after-break"`` -* ``"duplicate-index"`` -* ``"duplicate-doc-param"`` +* ``"undefined-doc-name"`` +* ``"no-unknown"`` +* ``"unreachable-code"`` +* ``"param-type-mismatch"`` * ``"index-in-func-name"`` * ``"miss-symbol"`` * ``"undefined-field"`` -* ``"miss-space-between"`` +* ``"return-type-mismatch"`` ## default @@ -450,6 +451,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -568,6 +570,7 @@ object<string, string> * empty-block * redundant-return * trailing-space + * unreachable-code * unused-function * unused-label * unused-local @@ -737,6 +740,7 @@ object<string, string> "unknown-cast-variable": "Any", "unknown-diag-code": "Any", "unknown-operator": "Any", + "unreachable-code": "Opened", /* 未使用的函式 */ @@ -871,6 +875,7 @@ object<string, string> "unknown-cast-variable": "Warning", "unknown-diag-code": "Warning", "unknown-operator": "Warning", + "unreachable-code": "Hint", /* 未使用的函式 */ @@ -1270,6 +1275,8 @@ object<string, string> "package": "default", "string": "default", "table": "default", + "table.clear": "default", + "table.new": "default", "utf8": "default" } ``` diff --git a/locale/en-us/script.lua b/locale/en-us/script.lua index c46c83c8..fdaa1428 100644 --- a/locale/en-us/script.lua +++ b/locale/en-us/script.lua @@ -142,6 +142,8 @@ DIAG_RETURN_TYPE_MISMATCH = 'The type of the {index} return value is `{def}`, but the actual return is `{ref}`.' DIAG_UNKNOWN_OPERATOR = 'Unknown operator `{}`.' +DIAG_UNREACHABLE_CODE = +'Unreachable code.' MWS_NOT_SUPPORT = '{} does not support multi workspace for now, I may need to restart to support the new workspace ...' diff --git a/locale/pt-br/script.lua b/locale/pt-br/script.lua index 908ba8cc..f7ac6d3d 100644 --- a/locale/pt-br/script.lua +++ b/locale/pt-br/script.lua @@ -142,6 +142,8 @@ DIAG_RETURN_TYPE_MISMATCH = -- TODO: need translate! 'The type of the {index} return value is `{def}`, but the actual return is `{ref}`.' DIAG_UNKNOWN_OPERATOR = -- TODO: need translate! 'Unknown operator `{}`.' +DIAG_UNREACHABLE_CODE = -- TODO: need translate! +'Unreachable code.' MWS_NOT_SUPPORT = '{} não é suportado múltiplos espaços de trabalho por enquanto, posso precisar reiniciar para estabelecer um novo espaço de trabalho ...' diff --git a/locale/zh-cn/script.lua b/locale/zh-cn/script.lua index 02596c04..f50d4b7b 100644 --- a/locale/zh-cn/script.lua +++ b/locale/zh-cn/script.lua @@ -142,6 +142,8 @@ DIAG_RETURN_TYPE_MISMATCH = '第 {index} 个返回值的类型为 `{def}` ,但实际返回的是 `{ref}`。' DIAG_UNKNOWN_OPERATOR = '未知的运算符 `{}`。' +DIAG_UNREACHABLE_CODE = +'不可达的代码。' MWS_NOT_SUPPORT = '{} 目前还不支持多工作目录,我可能需要重启才能支持新的工作目录...' diff --git a/locale/zh-tw/script.lua b/locale/zh-tw/script.lua index 7cf5134d..80733139 100644 --- a/locale/zh-tw/script.lua +++ b/locale/zh-tw/script.lua @@ -142,6 +142,8 @@ DIAG_RETURN_TYPE_MISMATCH = '第 {index} 個回傳值的類型為 `{def}` ,但實際回傳的是 `{ref}`。' DIAG_UNKNOWN_OPERATOR = -- TODO: need translate! 'Unknown operator `{}`.' +DIAG_UNREACHABLE_CODE = -- TODO: need translate! +'Unreachable code.' MWS_NOT_SUPPORT = '{} 目前還不支援多工作目錄,我可能需要重新啟動才能支援新的工作目錄...' 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', diff --git a/test/diagnostics/common.lua b/test/diagnostics/common.lua index fab02caf..1ab6ec5c 100644 --- a/test/diagnostics/common.lua +++ b/test/diagnostics/common.lua @@ -1958,3 +1958,31 @@ local <!ll!> ]] config.remove(nil, 'Lua.diagnostics.unusedLocalExclude', 'll_*') + +TEST [[ +---@diagnostic disable: undefined-global + +if X then + return false +elseif X then + return false +else + return false +end +<!return true!> +]] + +TEST [[ +---@diagnostic disable: undefined-global + +function X() + if X then + return false + elseif X then + return false + else + return false + end + <!return true!> +end +]] diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua index 91182af8..30f47900 100644 --- a/test/type_inference/init.lua +++ b/test/type_inference/init.lua @@ -3714,3 +3714,4 @@ A.B.C = 1 print(A.B.<?C?>) ]] + |