summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Wetzlmaier <thomas.wetzlmaier@scch.at>2023-04-19 16:49:35 +0200
committerGitHub <noreply@github.com>2023-04-19 16:49:35 +0200
commitbe232fcf95aab66d751b5dbaff9ccaf06299cc8e (patch)
treeef5e5753a8d5021591b95c589088223608e83294
parent27cfa2e23648b015a94fab6e0938ec42a5a040e5 (diff)
downloadlua-language-server-be232fcf95aab66d751b5dbaff9ccaf06299cc8e.zip
Warn about missing '---comment', '@return' and '@param' annotations (#3)
All functions that have at least one such annotation should be fully annotated in that respect, because we find that partially annotating something leads to confusion. However, all global functions must always be fully annotated, because they should be avoided in the first place, but if necessary then only with the maximum amount of documentation/support for those who use them! We provide the following keys for the `diagnostics.disable` setting to specifically deactive these checks: _missing-global-doc_: global function definitions which are not fully annotated. _incomplete-signature-doc_: function definitions that have some annotations but are not fully annotated
-rw-r--r--doc/en-us/config.md22
-rw-r--r--doc/pt-br/config.md21
-rw-r--r--doc/zh-cn/config.md22
-rw-r--r--doc/zh-tw/config.md22
-rw-r--r--locale/en-us/script.lua10
-rw-r--r--locale/en-us/setting.lua4
-rw-r--r--locale/pt-br/script.lua12
-rw-r--r--locale/pt-br/setting.lua4
-rw-r--r--locale/zh-cn/script.lua10
-rw-r--r--locale/zh-cn/setting.lua4
-rw-r--r--locale/zh-tw/script.lua10
-rw-r--r--locale/zh-tw/setting.lua4
-rw-r--r--script/core/diagnostics/incomplete-signature-doc.lua91
-rw-r--r--script/core/diagnostics/missing-global-doc.lua98
-rw-r--r--script/proto/diagnostic.lua9
-rw-r--r--test/diagnostics/incomplete-signature-doc.lua331
-rw-r--r--test/diagnostics/init.lua3
-rw-r--r--test/diagnostics/missing-global-doc.lua333
18 files changed, 1009 insertions, 1 deletions
diff --git a/doc/en-us/config.md b/doc/en-us/config.md
index 9e6fa64c..4319901c 100644
--- a/doc/en-us/config.md
+++ b/doc/en-us/config.md
@@ -240,6 +240,7 @@ Array<string>
* ``"exp-in-action"``
* ``"global-element"``
* ``"global-in-nil-env"``
+* ``"incomplete-signature-doc"``
* ``"index-in-func-name"``
* ``"invisible"``
* ``"jump-local-scope"``
@@ -284,6 +285,7 @@ Array<string>
* ``"miss-sep-in-table"``
* ``"miss-space-between"``
* ``"miss-symbol"``
+* ``"missing-global-doc"``
* ``"missing-parameter"``
* ``"missing-return"``
* ``"missing-return-value"``
@@ -450,6 +452,8 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
+ * missing-global-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -574,6 +578,8 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
+ * missing-global-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -795,6 +801,10 @@ object<string, string>
*/
"global-in-nil-env": "Any",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "None",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Any",
@@ -803,6 +813,10 @@ object<string, string>
*/
"lowercase-global": "Any",
/*
+ Enable diagnostics for global function definitions which are not fully annotated.
+ */
+ "missing-global-doc": "None",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Any",
@@ -1051,6 +1065,10 @@ object<string, string>
*/
"global-in-nil-env": "Warning",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "Warning",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Warning",
@@ -1059,6 +1077,10 @@ object<string, string>
*/
"lowercase-global": "Information",
/*
+ Enable diagnostics for global function definitions which are not annotated.
+ */
+ "missing-global-doc": "Warning",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Warning",
diff --git a/doc/pt-br/config.md b/doc/pt-br/config.md
index 6e2f58a0..c3ab1107 100644
--- a/doc/pt-br/config.md
+++ b/doc/pt-br/config.md
@@ -240,6 +240,7 @@ Array<string>
* ``"exp-in-action"``
* ``"global-element"``
* ``"global-in-nil-env"``
+* ``"incomplete-signature-doc"``
* ``"index-in-func-name"``
* ``"invisible"``
* ``"jump-local-scope"``
@@ -284,6 +285,7 @@ Array<string>
* ``"miss-sep-in-table"``
* ``"miss-space-between"``
* ``"miss-symbol"``
+* ``"missing-global-doc"``
* ``"missing-parameter"``
* ``"missing-return"``
* ``"missing-return-value"``
@@ -450,6 +452,8 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
+ * missing-global-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -574,6 +578,7 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -795,6 +800,10 @@ object<string, string>
*/
"global-in-nil-env": "Any",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "None",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Any",
@@ -803,6 +812,10 @@ object<string, string>
*/
"lowercase-global": "Any",
/*
+ Enable diagnostics for global function definitions which are not fully annotated.
+ */
+ "missing-global-doc": "None",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Any",
@@ -1051,6 +1064,10 @@ object<string, string>
*/
"global-in-nil-env": "Warning",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "Warning",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Warning",
@@ -1059,6 +1076,10 @@ object<string, string>
*/
"lowercase-global": "Information",
/*
+ Enable diagnostics for global function definitions which are not annotated.
+ */
+ "missing-global-doc": "Warning",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Warning",
diff --git a/doc/zh-cn/config.md b/doc/zh-cn/config.md
index 1cacfed3..32a6db68 100644
--- a/doc/zh-cn/config.md
+++ b/doc/zh-cn/config.md
@@ -240,6 +240,7 @@ Array<string>
* ``"exp-in-action"``
* ``"global-element"``
* ``"global-in-nil-env"``
+* ``"incomplete-signature-doc"``
* ``"index-in-func-name"``
* ``"invisible"``
* ``"jump-local-scope"``
@@ -284,6 +285,7 @@ Array<string>
* ``"miss-sep-in-table"``
* ``"miss-space-between"``
* ``"miss-symbol"``
+* ``"missing-global-doc"``
* ``"missing-parameter"``
* ``"missing-return"``
* ``"missing-return-value"``
@@ -450,6 +452,8 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
+ * missing-global-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -574,6 +578,8 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
+ * missing-global-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -795,6 +801,10 @@ object<string, string>
*/
"global-in-nil-env": "Any",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "None",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Any",
@@ -803,6 +813,10 @@ object<string, string>
*/
"lowercase-global": "Any",
/*
+ Enable diagnostics for global function definitions which are not fully annotated.
+ */
+ "missing-global-doc": "None",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Any",
@@ -1050,6 +1064,10 @@ object<string, string>
*/
"global-in-nil-env": "Warning",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "Warning",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Warning",
@@ -1058,6 +1076,10 @@ object<string, string>
*/
"lowercase-global": "Information",
/*
+ Enable diagnostics for global function definitions which are not annotated.
+ */
+ "missing-global-doc": "Warning",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Warning",
diff --git a/doc/zh-tw/config.md b/doc/zh-tw/config.md
index 78e565f2..bc9dae01 100644
--- a/doc/zh-tw/config.md
+++ b/doc/zh-tw/config.md
@@ -240,6 +240,7 @@ Array<string>
* ``"exp-in-action"``
* ``"global-element"``
* ``"global-in-nil-env"``
+* ``"incomplete-signature-doc"``
* ``"index-in-func-name"``
* ``"invisible"``
* ``"jump-local-scope"``
@@ -284,6 +285,7 @@ Array<string>
* ``"miss-sep-in-table"``
* ``"miss-space-between"``
* ``"miss-symbol"``
+* ``"missing-global-doc"``
* ``"missing-parameter"``
* ``"missing-return"``
* ``"missing-return-value"``
@@ -450,6 +452,8 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
+ * missing-global-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -574,6 +578,8 @@ object<string, string>
* duplicate-doc-alias
* duplicate-doc-field
* duplicate-doc-param
+ * incomplete-signature-doc
+ * missing-global-doc
* undefined-doc-class
* undefined-doc-name
* undefined-doc-param
@@ -795,6 +801,10 @@ object<string, string>
*/
"global-in-nil-env": "Any",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "None",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Any",
@@ -803,6 +813,10 @@ object<string, string>
*/
"lowercase-global": "Any",
/*
+ Enable diagnostics for global function definitions which are not fully annotated.
+ */
+ "missing-global-doc": "None",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Any",
@@ -1050,6 +1064,10 @@ object<string, string>
*/
"global-in-nil-env": "Warning",
/*
+ Enable diagnostics for function definitions which are not fully annotated.
+ */
+ "incomplete-signature-doc": "Warning",
+ /*
Enable diagnostics for accesses to fields which are invisible.
*/
"invisible": "Warning",
@@ -1058,6 +1076,10 @@ object<string, string>
*/
"lowercase-global": "Information",
/*
+ Enable diagnostics for global function definitions which are not annotated.
+ */
+ "missing-global-doc": "Warning",
+ /*
Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.
*/
"missing-parameter": "Warning",
diff --git a/locale/en-us/script.lua b/locale/en-us/script.lua
index e7f4b98b..6742b784 100644
--- a/locale/en-us/script.lua
+++ b/locale/en-us/script.lua
@@ -114,6 +114,16 @@ DIAG_UNDEFINED_DOC_NAME =
'Undefined type or alias `{}`.'
DIAG_UNDEFINED_DOC_PARAM =
'Undefined param `{}`.'
+DIAG_MISSING_GLOBAL_DOC_COMMENT =
+'Missing comment for global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_PARAM =
+'Missing @param annotation for parameter `{}` in global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_RETURN =
+'Missing @return annotation at index `{}` in global function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_PARAM =
+'Incomplete signature. Missing @param annotation for parameter `{}` in function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_RETURN =
+'Incomplete signature. Missing @return annotation at index `{}` in function `{}`.'
DIAG_UNKNOWN_DIAG_CODE =
'Unknown diagnostic code `{}`.'
DIAG_CAST_LOCAL_TYPE =
diff --git a/locale/en-us/setting.lua b/locale/en-us/setting.lua
index b03e3e43..4b34042f 100644
--- a/locale/en-us/setting.lua
+++ b/locale/en-us/setting.lua
@@ -373,8 +373,12 @@ config.diagnostics['duplicate-doc-param'] =
'Enable diagnostics for a duplicated param annotation name.'
config.diagnostics['duplicate-set-field'] =
'Enable diagnostics for setting the same field in a class more than once.'
+config.diagnostics['incomplete-signature-doc'] =
+'Incomplete @param or @return annotations for functions.'
config.diagnostics['invisible'] =
'Enable diagnostics for accesses to fields which are invisible.'
+config.diagnostics['missing-global-doc'] =
+'Missing annotations for globals! Global functions must have a comment and annotations for all parameters and return values.'
config.diagnostics['missing-parameter'] =
'Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.'
config.diagnostics['missing-return'] =
diff --git a/locale/pt-br/script.lua b/locale/pt-br/script.lua
index 6497c520..be6de9b2 100644
--- a/locale/pt-br/script.lua
+++ b/locale/pt-br/script.lua
@@ -114,7 +114,17 @@ DIAG_UNDEFINED_DOC_NAME =
'Tipo ou alias indefinido `{}`.'
DIAG_UNDEFINED_DOC_PARAM =
'Parâmetro indefinido `{}`.'
-DIAG_UNKNOWN_DIAG_CODE =
+DIAG_MISSING_GLOBAL_DOC_COMMENT = -- TODO: need translate!
+'Missing comment for global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_PARAM = -- TODO: need translate!
+'Missing @param annotation for parameter `{}` in global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_RETURN = -- TODO: need translate!
+'Missing @return annotation at index `{}` in global function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_PARAM = -- TODO: need translate!
+'Incomplete signature. Missing @param annotation for parameter `{}` in function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_RETURN = -- TODO: need translate!
+'Incomplete signature. Missing @return annotation at index `{}` in function `{}`.'
+DIAG_UNKNOWN_DIAG_CODE = -- TODO: need translate!
'Código de diagnóstico desconhecido `{}`.'
DIAG_CAST_LOCAL_TYPE = -- TODO: need translate!
'This variable is defined as type `{def}`. Cannot convert its type to `{ref}`.'
diff --git a/locale/pt-br/setting.lua b/locale/pt-br/setting.lua
index ec94f575..5038a5da 100644
--- a/locale/pt-br/setting.lua
+++ b/locale/pt-br/setting.lua
@@ -373,8 +373,12 @@ config.diagnostics['duplicate-doc-param'] = -- TODO: need translate!
'Enable diagnostics for a duplicated param annotation name.'
config.diagnostics['duplicate-set-field'] = -- TODO: need translate!
'Enable diagnostics for setting the same field in a class more than once.'
+config.diagnostics['incomplete-signature-doc'] = -- TODO: need translate!
+'Incomplete @param or @return annotations for functions.'
config.diagnostics['invisible'] = -- TODO: need translate!
'Enable diagnostics for accesses to fields which are invisible.'
+config.diagnostics['missing-global-doc'] = -- TODO: need translate!
+'Missing annotations for globals! Global functions must have a comment and annotations for all parameters and return values.'
config.diagnostics['missing-parameter'] = -- TODO: need translate!
'Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.'
config.diagnostics['missing-return'] = -- TODO: need translate!
diff --git a/locale/zh-cn/script.lua b/locale/zh-cn/script.lua
index da817698..40a8d35d 100644
--- a/locale/zh-cn/script.lua
+++ b/locale/zh-cn/script.lua
@@ -114,6 +114,16 @@ DIAG_UNDEFINED_DOC_NAME =
'未定义的类型或别名 `{}`。'
DIAG_UNDEFINED_DOC_PARAM =
'指向了未定义的参数 `{}`。'
+DIAG_MISSING_GLOBAL_DOC_COMMENT = -- TODO: need translate!
+'Missing comment for global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_PARAM = -- TODO: need translate!
+'Missing @param annotation for parameter `{}` in global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_RETURN = -- TODO: need translate!
+'Missing @return annotation at index `{}` in global function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_PARAM = -- TODO: need translate!
+'Incomplete signature. Missing @param annotation for parameter `{}` in function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_RETURN = -- TODO: need translate!
+'Incomplete signature. Missing @return annotation at index `{}` in function `{}`.'
DIAG_UNKNOWN_DIAG_CODE =
'未知的诊断代号 `{}`。'
DIAG_CAST_LOCAL_TYPE =
diff --git a/locale/zh-cn/setting.lua b/locale/zh-cn/setting.lua
index e1eb7de9..bece9a80 100644
--- a/locale/zh-cn/setting.lua
+++ b/locale/zh-cn/setting.lua
@@ -372,8 +372,12 @@ config.diagnostics['duplicate-doc-param'] = -- TODO: need translate!
'Enable diagnostics for a duplicated param annotation name.'
config.diagnostics['duplicate-set-field'] = -- TODO: need translate!
'Enable diagnostics for setting the same field in a class more than once.'
+config.diagnostics['incomplete-signature-doc'] = -- TODO: need translate!
+'Incomplete @param or @return annotations for functions.'
config.diagnostics['invisible'] = -- TODO: need translate!
'Enable diagnostics for accesses to fields which are invisible.'
+config.diagnostics['missing-global-doc'] = -- TODO: need translate!
+'Missing annotations for globals! Global functions must have a comment and annotations for all parameters and return values.'
config.diagnostics['missing-parameter'] = -- TODO: need translate!
'Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.'
config.diagnostics['missing-return'] = -- TODO: need translate!
diff --git a/locale/zh-tw/script.lua b/locale/zh-tw/script.lua
index 77ff6fea..7bc9e8a4 100644
--- a/locale/zh-tw/script.lua
+++ b/locale/zh-tw/script.lua
@@ -114,6 +114,16 @@ DIAG_UNDEFINED_DOC_NAME =
'未定義的類型或別名 `{}`。'
DIAG_UNDEFINED_DOC_PARAM =
'指向了未定義的參數 `{}`。'
+DIAG_MISSING_GLOBAL_DOC_COMMENT = -- TODO: need translate!
+'Missing comment for global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_PARAM = -- TODO: need translate!
+'Missing @param annotation for parameter `{}` in global function `{}`.'
+DIAG_MISSING_GLOBAL_DOC_RETURN = -- TODO: need translate!
+'Missing @return annotation at index `{}` in global function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_PARAM = -- TODO: need translate!
+'Incomplete signature. Missing @param annotation for parameter `{}` in function `{}`.'
+DIAG_INCOMPLETE_SIGNATURE_DOC_RETURN = -- TODO: need translate!
+'Incomplete signature. Missing @return annotation at index `{}` in function `{}`.'
DIAG_UNKNOWN_DIAG_CODE =
'未知的診斷代碼 `{}`。'
DIAG_CAST_LOCAL_TYPE =
diff --git a/locale/zh-tw/setting.lua b/locale/zh-tw/setting.lua
index ebf615ac..26ddc932 100644
--- a/locale/zh-tw/setting.lua
+++ b/locale/zh-tw/setting.lua
@@ -372,8 +372,12 @@ config.diagnostics['duplicate-doc-param'] = -- TODO: need translate!
'Enable diagnostics for a duplicated param annotation name.'
config.diagnostics['duplicate-set-field'] = -- TODO: need translate!
'Enable diagnostics for setting the same field in a class more than once.'
+config.diagnostics['incomplete-signature-doc'] = -- TODO: need translate!
+'Incomplete @param or @return annotations for functions.'
config.diagnostics['invisible'] = -- TODO: need translate!
'Enable diagnostics for accesses to fields which are invisible.'
+config.diagnostics['missing-global-doc'] = -- TODO: need translate!
+'Missing annotations for globals! Global functions must have a comment and annotations for all parameters and return values.'
config.diagnostics['missing-parameter'] = -- TODO: need translate!
'Enable diagnostics for function calls where the number of arguments is less than the number of annotated function parameters.'
config.diagnostics['missing-return'] = -- TODO: need translate!
diff --git a/script/core/diagnostics/incomplete-signature-doc.lua b/script/core/diagnostics/incomplete-signature-doc.lua
new file mode 100644
index 00000000..91f2db74
--- /dev/null
+++ b/script/core/diagnostics/incomplete-signature-doc.lua
@@ -0,0 +1,91 @@
+-- incomplete-signature-doc
+local files = require 'files'
+local lang = require 'language'
+local guide = require "parser.guide"
+local await = require 'await'
+
+local function findParam(docs, param)
+ if not docs then
+ return false
+ end
+
+ for _, doc in ipairs(docs) do
+ if doc.type == 'doc.param' then
+ if doc.param[1] == param then
+ return true
+ end
+ end
+ end
+
+ return false
+end
+
+local function findReturn(docs, index)
+ if not docs then
+ return false
+ end
+
+ for _, doc in ipairs(docs) do
+ if doc.type == 'doc.return' then
+ for _, ret in ipairs(doc.returns) do
+ if ret.returnIndex == index 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
+
+ if not state.ast then
+ return
+ end
+
+ ---@async
+ guide.eachSourceType(state.ast, 'function', function (source)
+ await.delay()
+
+ if not source.bindDocs then
+ return
+ end
+
+ local functionName = source.parent[1]
+
+ if #source.args > 0 then
+ for _, arg in ipairs(source.args) do
+ local argName = arg[1]
+ if argName ~= 'self' then
+ if not findParam(source.bindDocs, argName) then
+ callback {
+ start = arg.start,
+ finish = arg.finish,
+ message = lang.script('DIAG_INCOMPLETE_SIGNATURE_DOC_PARAM', argName, functionName),
+ }
+ end
+ end
+ end
+ end
+
+ if source.returns then
+ for _, ret in ipairs(source.returns) do
+ for index, expr in ipairs(ret) do
+ if not findReturn(source.bindDocs, index) then
+ callback {
+ start = expr.start,
+ finish = expr.finish,
+ message = lang.script('DIAG_INCOMPLETE_SIGNATURE_DOC_RETURN', index, functionName),
+ }
+ end
+ end
+ end
+ end
+ end)
+end
diff --git a/script/core/diagnostics/missing-global-doc.lua b/script/core/diagnostics/missing-global-doc.lua
new file mode 100644
index 00000000..adcdf404
--- /dev/null
+++ b/script/core/diagnostics/missing-global-doc.lua
@@ -0,0 +1,98 @@
+local files = require 'files'
+local lang = require 'language'
+local guide = require "parser.guide"
+local await = require 'await'
+
+local function findParam(docs, param)
+ if not docs then
+ return false
+ end
+
+ for _, doc in ipairs(docs) do
+ if doc.type == 'doc.param' then
+ if doc.param[1] == param then
+ return true
+ end
+ end
+ end
+
+ return false
+end
+
+local function findReturn(docs, index)
+ if not docs then
+ return false
+ end
+
+ for _, doc in ipairs(docs) do
+ if doc.type == 'doc.return' then
+ for _, ret in ipairs(doc.returns) do
+ if ret.returnIndex == index 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
+
+ if not state.ast then
+ return
+ end
+
+ ---@async
+ guide.eachSourceType(state.ast, 'function', function (source)
+ await.delay()
+
+ if source.parent.type ~= 'setglobal' then
+ return
+ end
+
+ local functionName = source.parent[1]
+
+ if #source.args == 0 and not source.returns and not source.bindDocs then
+ callback {
+ start = source.start,
+ finish = source.finish,
+ message = lang.script('DIAG_MISSING_GLOBAL_DOC_COMMENT', functionName),
+ }
+ end
+
+ if #source.args > 0 then
+ for _, arg in ipairs(source.args) do
+ local argName = arg[1]
+ if argName ~= 'self' then
+ if not findParam(source.bindDocs, argName) then
+ callback {
+ start = arg.start,
+ finish = arg.finish,
+ message = lang.script('DIAG_MISSING_GLOBAL_DOC_PARAM', argName, functionName),
+ }
+ end
+ end
+ end
+ end
+
+ if source.returns then
+ for _, ret in ipairs(source.returns) do
+ for index, expr in ipairs(ret) do
+ if not findReturn(source.bindDocs, index) then
+ callback {
+ start = expr.start,
+ finish = expr.finish,
+ message = lang.script('DIAG_MISSING_GLOBAL_DOC_RETURN', index, functionName),
+ }
+ end
+ end
+ end
+ end
+ end)
+end
diff --git a/script/proto/diagnostic.lua b/script/proto/diagnostic.lua
index 48a9094c..7f76c435 100644
--- a/script/proto/diagnostic.lua
+++ b/script/proto/diagnostic.lua
@@ -101,6 +101,15 @@ m.register {
}
m.register {
+ 'incomplete-signature-doc',
+ 'missing-global-doc',
+} {
+ group = 'luadoc',
+ severity = 'Warning',
+ status = 'None',
+}
+
+m.register {
'codestyle-check'
} {
group = 'codestyle',
diff --git a/test/diagnostics/incomplete-signature-doc.lua b/test/diagnostics/incomplete-signature-doc.lua
new file mode 100644
index 00000000..c3099cd2
--- /dev/null
+++ b/test/diagnostics/incomplete-signature-doc.lua
@@ -0,0 +1,331 @@
+local config = require 'config'
+local util = require 'utility'
+
+-- disable all default groups to make isolated tests
+config.set(nil, 'Lua.diagnostics.groupFileStatus',
+{
+ ['ambiguity'] = 'None',
+ ['await'] = 'None',
+ ['codestyle'] = 'None',
+ ['conventions'] = 'None',
+ ['duplicate'] = 'None',
+ ['global'] = 'None',
+ ['luadoc'] = 'None',
+ ['redefined'] = 'None',
+ ['strict'] = 'None',
+ ['strong'] = 'None',
+ ['type-check'] = 'None',
+ ['unbalanced'] = 'None',
+ ['unused'] = 'None'
+})
+
+-- enable single diagnostic that is to be tested
+config.set(nil, 'Lua.diagnostics.neededFileStatus',
+{
+ ['incomplete-signature-doc'] = 'Any!' -- override groupFileStatus
+})
+
+-- check global functions
+TEST [[
+function FG0()
+end
+
+---comment
+function FG1()
+end
+]]
+
+TEST [[
+function FGP0(p)
+ print(p)
+end
+
+---comment
+function FGP1(<!p!>)
+ print(p)
+end
+
+---comment
+---@param p any
+function FGP2(p)
+ print(p)
+end
+]]
+
+TEST [[
+function FGPP0(p0, p1)
+ print(p0, p1)
+end
+
+---comment
+function FGPP1(<!p0!>, <!p1!>)
+ print(p0, p1)
+end
+
+---comment
+---@param p0 any
+function FGPP2(p0, <!p1!>)
+ print(p0, p1)
+end
+
+---comment
+---@param p0 any
+---@param p1 any
+function FGPP3(p0, p1)
+ print(p0, p1)
+end
+]]
+
+TEST [[
+function FGR0()
+ return 0
+end
+
+---comment
+function FGR1()
+ return <!0!>
+end
+
+---comment
+---@return integer
+function FGR2()
+ return 0
+end
+]]
+
+TEST [[
+function FGRR0()
+ return 0, 1
+end
+
+---comment
+function FGRR1()
+ return <!0!>, <!1!>
+end
+
+---comment
+---@return integer
+function FGRR2()
+ return 0, <!1!>
+end
+
+---comment
+---@return integer
+---@return integer
+function FGRR3()
+ return 0, 1
+end
+]]
+
+TEST [[
+function FGPR0(p)
+ print(p)
+ return 0
+end
+
+---comment
+function FGPR1(<!p!>)
+ print(p)
+ return <!0!>
+end
+
+---comment
+---@param p any
+function FGPR2(p)
+ print(p)
+ return <!0!>
+end
+
+---comment
+---@return integer
+function FGPR3(<!p!>)
+ print(p)
+ return 0
+end
+
+---comment
+---@param p any
+---@return integer
+function FGPR4(p)
+ print(p)
+ return 0
+end
+]]
+
+-- check local functions
+
+TEST [[
+local function FL0()
+end
+
+FL0()
+
+---comment
+local function FL1()
+end
+
+FL1()
+]]
+
+TEST [[
+local function FLP0(p)
+ print(p)
+end
+
+FLP0(0)
+
+---comment
+local function FLP1(<!p!>)
+ print(p)
+end
+
+FLP1(0)
+
+---comment
+---@param p any
+local function FLP2(p)
+ print(p)
+end
+
+FLP2(0)
+]]
+
+TEST [[
+local function FLPP0(p0, p1)
+ print(p0, p1)
+end
+
+FLPP0(0, 1)
+
+---comment
+local function FLPP1(<!p0!>, <!p1!>)
+ print(p0, p1)
+end
+
+FLPP1(0, 1)
+
+---comment
+---@param p0 any
+local function FLPP2(p0, <!p1!>)
+ print(p0, p1)
+end
+
+FLPP2(0, 1)
+
+---comment
+---@param p0 any
+---@param p1 any
+local function FLPP3(p0, p1)
+ print(p0, p1)
+end
+
+FLPP3(0, 1)
+]]
+
+TEST [[
+local function FLR0()
+ return 0
+end
+
+local vr0 = FLR0()
+
+---comment
+local function FLR1()
+ return <!0!>
+end
+
+local vr1 = FLR1()
+
+---comment
+---@return integer
+local function FLR2()
+ return 0
+end
+
+local vr2 = FLR2()
+]]
+
+TEST [[
+local function FLRR0()
+ return 0, 1
+end
+
+local vrr0, _ = FLRR0()
+
+---comment
+local function FLRR1()
+ return <!0!>, <!1!>
+end
+
+local vrr1, _ = FLRR1()
+
+---comment
+---@return integer
+local function FLRR2()
+ return 0, <!1!>
+end
+
+local vrr2, _ = FLRR2()
+
+---comment
+---@return integer
+---@return integer
+local function FLRR3()
+ return 0, 1
+end
+
+local vrr3, _ = FLRR3()
+]]
+
+TEST [[
+local function FLPR0(p)
+ print(p)
+ return 0
+end
+
+local vpr0 = FLPR0(0)
+
+---comment
+local function FLPR1(<!p!>)
+ print(p)
+ return <!0!>
+end
+
+local vpr1 = FLPR1(0)
+
+---comment
+---@param p any
+local function FLPR2(p)
+ print(p)
+ return <!0!>
+end
+
+local vpr2 = FLPR2(0)
+
+---comment
+---@return integer
+local function FLPR3(<!p!>)
+ print(p)
+ return 0
+end
+
+local vpr3 = FLPR3(0)
+
+---comment
+---@param p any
+---@return integer
+local function FLPR4(p)
+ print(p)
+ return 0
+end
+
+local vpr4 = FLPR4(0)
+]]
+
+-- reset configurations
+config.set(nil, 'Lua.diagnostics.groupFileStatus',
+{})
+config.set(nil, 'Lua.diagnostics.neededFileStatus',
+{})
+config.set(nil, 'Lua.diagnostics.globals',
+{}) \ No newline at end of file
diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua
index 5e8abf7d..821685f0 100644
--- a/test/diagnostics/init.lua
+++ b/test/diagnostics/init.lua
@@ -86,5 +86,8 @@ end
require 'diagnostics.common'
require 'diagnostics.type-check'
+require 'diagnostics.incomplete-signature-doc'
+require 'diagnostics.missing-global-doc'
require 'diagnostics.global-element'
require 'diagnostics.uppercase-local'
+
diff --git a/test/diagnostics/missing-global-doc.lua b/test/diagnostics/missing-global-doc.lua
new file mode 100644
index 00000000..2ebc237a
--- /dev/null
+++ b/test/diagnostics/missing-global-doc.lua
@@ -0,0 +1,333 @@
+local config = require 'config'
+local util = require 'utility'
+
+-- disable all default groups to make isolated tests
+config.set(nil, 'Lua.diagnostics.groupFileStatus',
+{
+ ['ambiguity'] = 'None',
+ ['await'] = 'None',
+ ['codestyle'] = 'None',
+ ['conventions'] = 'None',
+ ['duplicate'] = 'None',
+ ['global'] = 'None',
+ ['luadoc'] = 'None',
+ ['redefined'] = 'None',
+ ['strict'] = 'None',
+ ['strong'] = 'None',
+ ['type-check'] = 'None',
+ ['unbalanced'] = 'None',
+ ['unused'] = 'None'
+})
+
+-- enable single diagnostic that is to be tested
+config.set(nil, 'Lua.diagnostics.neededFileStatus',
+{
+ ['missing-global-doc'] = 'Any!' -- override groupFileStatus
+})
+
+
+-- check global functions
+TEST [[
+<!function FG0()
+end!>
+
+---comment
+function FG1()
+end
+]]
+
+TEST [[
+function FGP0(<!p!>)
+ print(p)
+end
+
+---comment
+function FGP1(<!p!>)
+ print(p)
+end
+
+---comment
+---@param p any
+function FGP2(p)
+ print(p)
+end
+]]
+
+TEST [[
+function FGPP0(<!p0!>, <!p1!>)
+ print(p0, p1)
+end
+
+---comment
+function FGPP1(<!p0!>, <!p1!>)
+ print(p0, p1)
+end
+
+---comment
+---@param p0 any
+function FGPP2(p0, <!p1!>)
+ print(p0, p1)
+end
+
+---comment
+---@param p0 any
+---@param p1 any
+function FGPP3(p0, p1)
+ print(p0, p1)
+end
+]]
+
+TEST [[
+function FGR0()
+ return <!0!>
+end
+
+---comment
+function FGR1()
+ return <!0!>
+end
+
+---comment
+---@return integer
+function FGR2()
+ return 0
+end
+]]
+
+TEST [[
+function FGRR0()
+ return <!0!>, <!1!>
+end
+
+---comment
+function FGRR1()
+ return <!0!>, <!1!>
+end
+
+---comment
+---@return integer
+function FGRR2()
+ return 0, <!1!>
+end
+
+---comment
+---@return integer
+---@return integer
+function FGRR3()
+ return 0, 1
+end
+]]
+
+
+TEST [[
+function FGPR0(<!p!>)
+ print(p)
+ return <!0!>
+end
+
+---comment
+function FGPR1(<!p!>)
+ print(p)
+ return <!0!>
+end
+
+---comment
+---@param p any
+function FGPR2(p)
+ print(p)
+ return <!0!>
+end
+
+---comment
+---@return integer
+function FGPR3(<!p!>)
+ print(p)
+ return 0
+end
+
+---comment
+---@param p any
+---@return integer
+function FGPR4(p)
+ print(p)
+ return 0
+end
+]]
+
+-- check local functions
+
+TEST [[
+local function FL0()
+end
+
+FL0()
+
+---comment
+local function FL1()
+end
+
+FL1()
+]]
+
+TEST [[
+local function FLP0(p)
+ print(p)
+end
+
+FLP0(0)
+
+---comment
+local function FLP1(p)
+ print(p)
+end
+
+FLP1(0)
+
+---comment
+---@param p any
+local function FLP2(p)
+ print(p)
+end
+
+FLP2(0)
+]]
+
+TEST [[
+local function FLPP0(p0, p1)
+ print(p0, p1)
+end
+
+FLPP0(0, 1)
+
+---comment
+local function FLPP1(p0, p1)
+ print(p0, p1)
+end
+
+FLPP1(0, 1)
+
+---comment
+---@param p0 any
+local function FLPP2(p0, p1)
+ print(p0, p1)
+end
+
+FLPP2(0, 1)
+
+---comment
+---@param p0 any
+---@param p1 any
+local function FLPP3(p0, p1)
+ print(p0, p1)
+end
+
+FLPP3(0, 1)
+]]
+
+TEST [[
+local function FLR0()
+ return 0
+end
+
+local vr0 = FLR0()
+
+---comment
+local function FLR1()
+ return 0
+end
+
+local vr1 = FLR1()
+
+---comment
+---@return integer
+local function FLR2()
+ return 0
+end
+
+local vr2 = FLR2()
+]]
+
+TEST [[
+local function FLRR0()
+ return 0, 1
+end
+
+local vrr0, _ = FLRR0()
+
+---comment
+local function FLRR1()
+ return 0, 1
+end
+
+local vrr1, _ = FLRR1()
+
+---comment
+---@return integer
+local function FLRR2()
+ return 0, 1
+end
+
+local vrr2, _ = FLRR2()
+
+---comment
+---@return integer
+---@return integer
+local function FLRR3()
+ return 0, 1
+end
+
+local vrr3, _ = FLRR3()
+]]
+
+TEST [[
+local function FLPR0(p)
+ print(p)
+ return 0
+end
+
+local vpr0 = FLPR0(0)
+
+---comment
+local function FLPR1(p)
+ print(p)
+ return 0
+end
+
+local vpr1 = FLPR1(0)
+
+---comment
+---@param p any
+local function FLPR2(p)
+ print(p)
+ return 0
+end
+
+local vpr2 = FLPR2(0)
+
+---comment
+---@return integer
+local function FLPR3(p)
+ print(p)
+ return 0
+end
+
+local vpr3 = FLPR3(0)
+
+---comment
+---@param p any
+---@return integer
+local function FLPR4(p)
+ print(p)
+ return 0
+end
+
+local vpr4 = FLPR4(0)
+]]
+
+-- reset configurations
+config.set(nil, 'Lua.diagnostics.groupFileStatus',
+{})
+config.set(nil, 'Lua.diagnostics.neededFileStatus',
+{})
+config.set(nil, 'Lua.diagnostics.globals',
+{}) \ No newline at end of file