From 1ce9a93721c2475d6dc7b1b8bcbf0d01b8e4723a Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 17:21:41 +0300 Subject: [PATCH 01/10] test: update luacheckrc The patch updates luacheckrc to suppress warnings. Follows up the commit 49fa005dab08a1b206771e89e5231f779cccf914 ("test: add linting stage"). --- .luacheckrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.luacheckrc b/.luacheckrc index 57c02f0..7f11a70 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -2,3 +2,12 @@ include_files = {'**/*.lua', '*.luacheckrc', '*.rockspec'} exclude_files = {'.rocks/', 'tmp/', 'build/'} max_line_length = 120 redefined = false +globals = { + "box", +} +ignore = { + -- Accessing an undefined field of a global variable . + "143/table", + -- Unused variable with `_` prefix. + "212/_.*", +} From ab9b58776aae2b7738ea92aaa949809005d80913 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 12:49:22 +0300 Subject: [PATCH 02/10] doc: document public Lua functions with EmmyLua The patch adds comments for functions with descriptions and argument types in EmmyLua format. Needed for tarantool/tarantool#13020 --- checks.lua | 111 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/checks.lua b/checks.lua index 35060a8..434e1e4 100644 --- a/checks.lua +++ b/checks.lua @@ -1,3 +1,15 @@ +---The `checks` module provides the ability to check the types of arguments +---passed to a Lua function. It is designed to reveal mistakes in code, not to +---validate user input. +--- +---The module table itself is callable: `checks(type_1, ...)` is equivalent to +---`checks.checks(type_1, ...)`. +--- +---@alias checks.qualifier string|table +--- +---@class checks +---@field checks fun(...: checks.qualifier) Checks the arguments of the calling function. +---@field _VERSION string The module version. local ffi = require('ffi') ffi.cdef[[ @@ -18,14 +30,14 @@ local _qualifiers_cache = { -- }, } ---- Check that string (or substring) starts with given string --- Optionally restricting the matching with the given offsets --- @function startswith --- @string inp original string --- @string head the substring to check against --- @int[opt] _start start index of matching boundary --- @int[opt] _end end index of matching boundary --- @returns boolean +---Check that the given string (or substring) starts with the given string, +---optionally restricting the matching with the given offsets. +--- +---@param inp string The original string. +---@param head string The substring to check against. +---@param _start? integer Start index of the matching boundary (default: `1`). +---@param _end? integer End index of the matching boundary (default: `#inp`). +---@return boolean `true` if `inp` starts with `head`, `false` otherwise. local function startswith(inp, head, _start, _end) if type(inp) ~= 'string' then error(err_string_arg:format(1, 'string.startswith', 'string', @@ -69,6 +81,13 @@ local function startswith(inp, head, _start, _end) end +---Check that a value conforms to the given string type qualifier. +--- +---@param value any The value to check. +---@param expected_type string The string type qualifier, e.g. `'string'`, +--- `'?number|string'`, or `'?'` for any type. +---@return boolean? `true` if the value conforms to the type qualifier. +---@return string? error_message The formatted error message if the check fails. local function check_string_type(value, expected_type) -- 1. Check any value. if expected_type == '?' then @@ -123,6 +142,11 @@ local function check_string_type(value, expected_type) ) end +---Format a table key for an error message: `.key` for strings and `[n]` +---for numbers. +--- +---@param key any The table key. +---@return string The formatted key name. local function keyname_fmt(key) if type(key) == 'string' then return string.format('.%s', key) @@ -133,6 +157,12 @@ local function keyname_fmt(key) end end +---Check that a table conforms to the given table type qualifier. +--- +---@param tbl table? The table to check. +---@param expected_fields table The table type qualifier. +---@return boolean? `true` if the table conforms to the type qualifier. +---@return string? error_message The formatted error message if the check fails. local function check_table_type(tbl, expected_fields) if tbl == nil then tbl = nil @@ -187,6 +217,17 @@ local function check_table_type(tbl, expected_fields) return true end +---Checks that the arguments of the calling function conform to the specified +---types. Must be called at the top of the function being checked; each type +---qualifier corresponds to the argument at the same position. +--- +---String qualifiers check Lua types, Tarantool-specific types (`uint64`, +---`int64`, `decimal`, `uuid`, etc.), metatable `__type` values, and custom +---checker names; they can be combined into union types (`'number|string'`) and +---made optional (`'?string'`). Table qualifiers validate the values of a table +---argument. +--- +---@param ... checks.qualifier Type qualifiers, one per argument to check. local function checks(...) local skip = 0 @@ -249,15 +290,41 @@ local function checks(...) end end +---The `checks` function is also available as a global, so it can be used +---without loading the module (Tarantool 2.11.0 and later). rawset(_G, 'checks', checks) +---The `checkers` global table provides access to checkers for different types. +---It can be extended with custom checkers that perform arbitrary validations. +--- +---@class checks.checkers +---@field datetime fun(arg: any): boolean Check that the value is a datetime object. +---@field decimal fun(arg: any): boolean Check that the value has the decimal type. +---@field error fun(arg: any): boolean Check that the value is an error object. +---@field int64 fun(arg: any): boolean Check that the value is an int64 value. +---@field interval fun(arg: any): boolean Check that the value is an interval object. +---@field tuple fun(arg: any): boolean Check that the value is a tuple. +---@field uint64 fun(arg: any): boolean Check that the value is a uint64 value. +---@field uuid fun(arg: any): boolean Check that the value is a uuid object. +---@field uuid_bin fun(arg: any): boolean Check that the value is a uuid as a 16-byte binary string. +---@field uuid_str fun(arg: any): boolean Check that the value is a uuid as a 36-byte hexadecimal string. local checkers = rawget(_G, 'checkers') or {} rawset(_G, 'checkers', checkers) +---When set to `true`, substitutes `nil` table arguments with empty tables for +---backward compatibility with v2.1. +---@type boolean local _checks_v2_compatible = rawget(_G, '_checks_v2_compatible') or false rawset(_G, '_checks_v2_compatible', _checks_v2_compatible) local ffi = require('ffi') + +---Check whether the specified value is a `uint64` value: an integer Lua number +---in the range from 0 to 2^53-1 (inclusive), a cdata `ctype`, or a +---cdata `ctype` in the range from 0 to `LLONG_MAX`. +--- +---@param arg any The value to check. +---@return boolean `true` if the value is a `uint64` value, `false` otherwise. function checkers.uint64(arg) if type(arg) == 'number' then -- Double floating point format has 52 fraction bits @@ -277,6 +344,13 @@ function checkers.uint64(arg) return false end +---Check whether the specified value is an `int64` value: an integer Lua +---number in the range from -2^53+1 to 2^53-1 (inclusive), a cdata +---`ctype`, or a cdata `ctype` in the range from 0 to +---`LLONG_MAX`. +--- +---@param arg any The value to check. +---@return boolean `true` if the value is an `int64` value, `false` otherwise. function checkers.int64(arg) if type(arg) == 'number' then return (arg > -2^53) and (arg < 2^53) and (math.floor(arg) == arg) @@ -293,6 +367,7 @@ function checkers.int64(arg) return false end +---Check whether the specified value is a tuple. local has_box = rawget(_G, 'box') ~= nil if has_box and box.tuple ~= nil then checkers.tuple = box.tuple.is @@ -303,11 +378,19 @@ if has_decimal then -- There is a decimal.is_decimal check since 2.4, but we -- reimplement it here to support older versions which have decimal. local cdata_t = ffi.typeof(decimal.new(0)) + ---Check whether the specified value has the decimal type. + --- + ---@param arg any The value to check. + ---@return boolean `true` if the value has the decimal type, `false` otherwise. checkers.decimal = function(arg) return ffi.istype(cdata_t, arg) end end +---Register a checker for a cdata type checked via FFI. +--- +---@param checks_type string The name of the checker to register in `checkers`. +---@param c_type string The C type name, e.g. `'struct tt_uuid'`. local function add_ffi_type_checker(checks_type, c_type) local has_cdata_t, cdata_t = pcall(ffi.typeof, c_type) if has_cdata_t then @@ -322,6 +405,11 @@ end -- https://github.com/tarantool/tarantool/blob/7682d34162be34648172d91008e9185301bce8f6/src/lua/uuid.lua#L29 add_ffi_type_checker('uuid', 'struct tt_uuid') +---Check whether the specified value is a uuid represented by a 36-byte +---hexadecimal string. +--- +---@param arg any The value to check. +---@return boolean `true` if the value is a uuid string, `false` otherwise. function checkers.uuid_str(arg) if type(arg) == 'string' and #arg == 36 then local match = arg:match( @@ -339,6 +427,11 @@ function checkers.uuid_str(arg) end end +---Check whether the specified value is a uuid represented by a 16-byte binary +---string. +--- +---@param arg any The value to check. +---@return boolean `true` if the value is a uuid binary string, `false` otherwise. function checkers.uuid_bin(arg) if type(arg) == 'string' and #arg == 16 then return true @@ -349,6 +442,7 @@ end add_ffi_type_checker('error', 'struct error') +---Check whether the specified value is a datetime object. local has_datetime, datetime = pcall(require, 'datetime') if has_datetime then checkers.datetime = datetime.is_datetime @@ -356,6 +450,7 @@ end add_ffi_type_checker('interval', 'struct interval') +---@type checks return setmetatable( { checks = checks, From 3f5546ed215c5b7d1efcfc45c02358f6c5a1f5a9 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 12:54:11 +0300 Subject: [PATCH 03/10] emmyrc: initial config The patch introduces an initial configuration file .emmyrc for emmylua_check, it is a modern static analuzer for Lua. The configuration file has the same excluded directories as in .luacheckrc and config disables a number of rules. Most of them will be enabled back in the following commits except the following rules: - "unresolved-require" (7 warnings) is disabled because most modules are Tarantool builtins: `json`, `log`, `uuid`; no source code is included in the project. - "need-check-nil" (22 warnings) is disabled because these warnings are not critical and I don't want to add extra checks to the code. - "redefined-local" is disabled because it was disabled for luacheck in the commit 49fa005dab08a1b206771e89e5231f779cccf914 ("test: add linting stage"). --- .emmyrc.json | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .emmyrc.json diff --git a/.emmyrc.json b/.emmyrc.json new file mode 100644 index 0000000..b5b80ab --- /dev/null +++ b/.emmyrc.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json", + "workspace": { + "ignoreDir": [ + ".rocks", + "build", + "tmp" + ] + }, + "runtime": { + "version": "LuaJIT" + }, + "diagnostics": { + "disable": [ + "assign-type-mismatch", + "call-non-callable", + "duplicate-require", + "need-check-nil", + "param-type-mismatch", + "redefined-local", + "undefined-field", + "unnecessary-if", + "unresolved-require", + "unused" + ], + "globals": [ + "box" + ] + } +} From 1da8a03f96d9fc8f95dc6bfb6d48c920a3e0ab52 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 13:22:43 +0300 Subject: [PATCH 04/10] emmyrc: fix assign-type-mismatch The patch rule `assign-type-mismatch` in the .emmyrc and fixes three warnings: - @class checks moved to the module table - no longer sticks to local ffi. - `checks(...)`: vararg typed as `checks.qualifier|number`, level annotated with ---@type number, stack level retrieved via narrowed local first. - @field checks field consistent with type `fun(...: checks.qualifier|number)`. --- .emmyrc.json | 1 - checks.lua | 21 ++++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.emmyrc.json b/.emmyrc.json index b5b80ab..435cd6d 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -12,7 +12,6 @@ }, "diagnostics": { "disable": [ - "assign-type-mismatch", "call-non-callable", "duplicate-require", "need-check-nil", diff --git a/checks.lua b/checks.lua index 434e1e4..f4d07ff 100644 --- a/checks.lua +++ b/checks.lua @@ -6,10 +6,6 @@ ---`checks.checks(type_1, ...)`. --- ---@alias checks.qualifier string|table ---- ----@class checks ----@field checks fun(...: checks.qualifier) Checks the arguments of the calling function. ----@field _VERSION string The module version. local ffi = require('ffi') ffi.cdef[[ @@ -227,13 +223,16 @@ end ---made optional (`'?string'`). Table qualifiers validate the values of a table ---argument. --- ----@param ... checks.qualifier Type qualifiers, one per argument to check. +---@param ... checks.qualifier|number Type qualifiers, one per argument to +--- check. The first argument may also be a stack level (used internally). local function checks(...) local skip = 0 + ---@type number local level = 1 - if type(...) == 'number' then - level = ... + local first = ... + if type(first) == 'number' then + level = first skip = 1 end level = level + 1 -- escape the checks level @@ -450,8 +449,10 @@ end add_ffi_type_checker('interval', 'struct interval') ----@type checks -return setmetatable( +---@class checks +---@field checks fun(...: checks.qualifier|number) Checks the arguments of the calling function. +---@field _VERSION string The module version. +local M = setmetatable( { checks = checks, _VERSION = require('checks.version'), @@ -463,3 +464,5 @@ return setmetatable( end } ) + +return M From b5a588962a629fdf6b03e5dd65e22a07bca7d941 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 13:55:31 +0300 Subject: [PATCH 05/10] emmyrc: fix call-non-callable The patch enables rule `call-non-callable` and fixes warnings produced by this rule: removed class checks/@field from the modul table, now the `require('checks')` type is inferred from setmetatable (callable via variadic `__call`, checks/_VERSION fields are referenced). Field documentation has been moved to the module header. --- .emmyrc.json | 1 - checks.lua | 8 +++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.emmyrc.json b/.emmyrc.json index 435cd6d..36de642 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -12,7 +12,6 @@ }, "diagnostics": { "disable": [ - "call-non-callable", "duplicate-require", "need-check-nil", "param-type-mismatch", diff --git a/checks.lua b/checks.lua index f4d07ff..31fd1c8 100644 --- a/checks.lua +++ b/checks.lua @@ -2,8 +2,9 @@ ---passed to a Lua function. It is designed to reveal mistakes in code, not to ---validate user input. --- ----The module table itself is callable: `checks(type_1, ...)` is equivalent to ----`checks.checks(type_1, ...)`. +---The returned module table is callable: `checks(type_1, ...)` is equivalent +---to `checks.checks(type_1, ...)`. It exposes the `checks` function and the +---`_VERSION` string field. --- ---@alias checks.qualifier string|table local ffi = require('ffi') @@ -449,9 +450,6 @@ end add_ffi_type_checker('interval', 'struct interval') ----@class checks ----@field checks fun(...: checks.qualifier|number) Checks the arguments of the calling function. ----@field _VERSION string The module version. local M = setmetatable( { checks = checks, From a8e00dd6190fcf860651b6c883ce23d67bcc4fe7 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 13:59:04 +0300 Subject: [PATCH 06/10] emmyrc: fix duplicate-require The patch enables rule `duplicate-require` in the .emmyrc and removes duplicate require for `ffi` module. --- .emmyrc.json | 1 - checks.lua | 2 -- 2 files changed, 3 deletions(-) diff --git a/.emmyrc.json b/.emmyrc.json index 36de642..9ae76a2 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -12,7 +12,6 @@ }, "diagnostics": { "disable": [ - "duplicate-require", "need-check-nil", "param-type-mismatch", "redefined-local", diff --git a/checks.lua b/checks.lua index 31fd1c8..758cb04 100644 --- a/checks.lua +++ b/checks.lua @@ -317,8 +317,6 @@ rawset(_G, 'checkers', checkers) local _checks_v2_compatible = rawget(_G, '_checks_v2_compatible') or false rawset(_G, '_checks_v2_compatible', _checks_v2_compatible) -local ffi = require('ffi') - ---Check whether the specified value is a `uint64` value: an integer Lua number ---in the range from 0 to 2^53-1 (inclusive), a cdata `ctype`, or a ---cdata `ctype` in the range from 0 to `LLONG_MAX`. From ba618becba430fce826146e7db287b6fec6062b4 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 14:48:33 +0300 Subject: [PATCH 07/10] emmyrc: fix param-type-mismatch The patch enables rule `param-type-mismatch` in the .emmyrc and fixes 20 warnings produced by this rule. --- .emmyrc.json | 1 - checks.lua | 12 +++++++++++- test/test.lua | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.emmyrc.json b/.emmyrc.json index 9ae76a2..8553638 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -13,7 +13,6 @@ "diagnostics": { "disable": [ "need-check-nil", - "param-type-mismatch", "redefined-local", "undefined-field", "unnecessary-if", diff --git a/checks.lua b/checks.lua index 758cb04..f1e2a44 100644 --- a/checks.lua +++ b/checks.lua @@ -171,11 +171,13 @@ local function check_table_type(tbl, expected_fields) if type(expected_type) == 'string' then local ok, efmt = check_string_type(value, expected_type) if not ok then + ---@cast efmt string return nil, string.format(efmt, '%s'..keyname_fmt(expected_key), '%s') end elseif type(expected_type) == 'table' then local ok, efmt = check_string_type(value, '?table') if not ok then + ---@cast efmt string return nil, string.format(efmt, '%s'..keyname_fmt(expected_key), '%s') end @@ -186,6 +188,7 @@ local function check_table_type(tbl, expected_fields) local ok, efmt = check_table_type(value, expected_type) if not ok then + ---@cast efmt string return nil, string.format(efmt, '%s'..keyname_fmt(expected_key), '%s') end else @@ -229,10 +232,11 @@ end local function checks(...) local skip = 0 - ---@type number + ---@type integer local level = 1 local first = ... if type(first) == 'number' then + ---@cast first integer level = first skip = 1 end @@ -257,6 +261,7 @@ local function checks(...) local ok, efmt = check_string_type(value, expected_type) if not ok then local info = debug.getinfo(level, 'nl') + ---@cast efmt string local err = string.format(efmt, '#'..tostring(i), info.name) error(err, level) end @@ -265,18 +270,23 @@ local function checks(...) local ok, efmt = check_string_type(value, '?table') if not ok then local info = debug.getinfo(level, 'nl') + ---@cast efmt string local err = string.format(efmt, '#'..tostring(i), info.name) error(err, level) end if rawget(_G, '_checks_v2_compatible') and value == nil then value = {} + -- In emmylua-check 0.22.0 the debug.setlocal index + -- parameter is mistyped as `string`; it is an integer. + ---@diagnostic disable-next-line: param-type-mismatch debug.setlocal(level, i, value) end local ok, efmt = check_table_type(value, expected_type) if not ok then local info = debug.getinfo(level, 'nl') + ---@cast efmt string local err = string.format(efmt, argname, info.name) error(err, level) end diff --git a/test/test.lua b/test/test.lua index 1f55aa3..89ae5db 100755 --- a/test/test.lua +++ b/test/test.lua @@ -456,6 +456,7 @@ for _, case in pairs(err_cases) do g[name] = function(_) local fn = loadstring(case.code) + ---@cast fn function local ok, err = pcall(fn) if case.error == nil then @@ -1095,6 +1096,7 @@ for _, case in pairs(ret_cases) do t.skip_if(case.skip, "type unsupported") local fn = loadstring(case.code) + ---@cast fn function local ok, err = pcall(fn) t.assert_equals(case.ok, ok, err) end From ac7a785f7cfc26bf5091e67b913caf20c7c03841 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 15:04:29 +0300 Subject: [PATCH 08/10] emmyrc: fix undefined-field The patch enables rule `undefined-field` in the .emmyrc and fixes errors produced by this rule. The error is in using `table.deepcopy()` in test/test.lua because Tarantool API is unknown to the analyzer. The patch created a definition for `table.deepcopy()` in a file test/types.lua. --- .emmyrc.json | 1 - test/types.lua | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 test/types.lua diff --git a/.emmyrc.json b/.emmyrc.json index 8553638..089c271 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -14,7 +14,6 @@ "disable": [ "need-check-nil", "redefined-local", - "undefined-field", "unnecessary-if", "unresolved-require", "unused" diff --git a/test/types.lua b/test/types.lua new file mode 100644 index 0000000..07e6b2b --- /dev/null +++ b/test/types.lua @@ -0,0 +1,6 @@ +---@meta +--- +--- Tarantool extensions to the standard Lua `table` library. +--- +---@class tablelib +---@field deepcopy fun(t: table): table Deep-copies a table. From a5ad131980314094da5046275625beaac7f2dce0 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 15:13:37 +0300 Subject: [PATCH 09/10] emmyrc: fix unnecessary-if The patch enables `unnecessary-if` in the .emmyrc and fixes a warning produced by this rule. The reason of warning is an unknown type of variable `qualifier`. The analyzer infers the `optional` field as literal `false` and doesn't track the assignment `qualifier.optional = true` inside the `gmatch` loop, so `unnecessary-if` considers the condition is always `false`. This is a false positive - at runtime, the condition is reachable (e.g., '?string'). The patch adds the annotation to the local variable `qualifier` - the `optional` field is now typed as boolean, and the analyzer no longer considers the condition to always be false. --- .emmyrc.json | 1 - checks.lua | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.emmyrc.json b/.emmyrc.json index 089c271..c418dba 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -14,7 +14,6 @@ "disable": [ "need-check-nil", "redefined-local", - "unnecessary-if", "unresolved-require", "unused" ], diff --git a/checks.lua b/checks.lua index f1e2a44..c61997b 100644 --- a/checks.lua +++ b/checks.lua @@ -92,6 +92,7 @@ local function check_string_type(value, expected_type) end -- 2. Parse type qualifier + ---@type { [integer]: string, optional: boolean }? local qualifier = _qualifiers_cache[expected_type] if qualifier == nil then qualifier = { optional = false } From 507b1b7c0412756fa8b80f6a99d3f827ac55688b Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 7 Aug 2026 16:17:13 +0300 Subject: [PATCH 10/10] emmyrc: fix unused The patch enables rule `unused` and fixes a warnings produced by this rule by adding an underscore to the prefix of variables that are not used. --- .emmyrc.json | 3 +- test/perftest.lua | 2 +- test/test.lua | 84 +++++++++++++++++++++++------------------------ 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/.emmyrc.json b/.emmyrc.json index c418dba..0e12414 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -14,8 +14,7 @@ "disable": [ "need-check-nil", "redefined-local", - "unresolved-require", - "unused" + "unresolved-require" ], "globals": [ "box" diff --git a/test/perftest.lua b/test/perftest.lua index 13502e7..1a83176 100755 --- a/test/perftest.lua +++ b/test/perftest.lua @@ -134,7 +134,7 @@ for _, case in pairs(cases) do local name = ('test_%s_%s'):format(json.encode(case.check), case.argtype):gsub('%.', '_') g[name] = function(_) - local fn = function(arg) -- luacheck: no unused args + local fn = function(_arg) checks(case.check) end diff --git a/test/test.lua b/test/test.lua index 89ae5db..652d5b6 100755 --- a/test/test.lua +++ b/test/test.lua @@ -19,41 +19,41 @@ end local testdata = {} local _l_number_optstring = 2 + debug.getinfo(1).currentline -function testdata.fn_number_optstring(arg1, arg2) -- luacheck: no unused args +function testdata.fn_number_optstring(_arg1, _arg2) checks('number', '?string') end local _l_number_or_string = 2 + debug.getinfo(1).currentline -function testdata.fn_number_or_string(arg1) -- luacheck: no unused args +function testdata.fn_number_or_string(_arg1) checks('number|string') end local _l_positive_number = 2 + debug.getinfo(1).currentline -function testdata.fn_positive_number(arg1) -- luacheck: no unused args +function testdata.fn_positive_number(_arg1) checks('positive_number') end -function testdata.fn_anytype(arg1) -- luacheck: no unused args +function testdata.fn_anytype(_arg1) checks('?') end local _l_nil_or_number_or_string = 2 + debug.getinfo(1).currentline -function testdata.fn_nil_or_number_or_string(arg1) -- luacheck: no unused args +function testdata.fn_nil_or_number_or_string(_arg1) checks('nil|number|string') end local _l_optnumber_or_optstring = 2 + debug.getinfo(1).currentline -function testdata.fn_optnumber_or_optstring(arg1) -- luacheck: no unused args +function testdata.fn_optnumber_or_optstring(_arg1) checks('?number|?string') end local _l_varargs = 2 + debug.getinfo(1).currentline -function testdata.fn_varargs(arg1, ...) -- luacheck: no unused args +function testdata.fn_varargs(_arg1, ...) -- luacheck: ignore 212 checks('string') end local _l_options = 2 + debug.getinfo(1).currentline -function testdata.fn_options(options) -- luacheck: no unused args +function testdata.fn_options(_options) checks({ mystring = '?string', mynumber = '?number', @@ -61,17 +61,17 @@ function testdata.fn_options(options) -- luacheck: no unused args end local _l_array = 2 + debug.getinfo(1).currentline -function testdata.fn_array(array) -- luacheck: no unused args +function testdata.fn_array(_array) checks({'number', 'number'}) end local _l_table = 2 + debug.getinfo(1).currentline -function testdata.fn_table(table) -- luacheck: no unused args +function testdata.fn_table(_table) checks({mykey = 'number'}) end local _l_inception = 2 + debug.getinfo(1).currentline -function testdata.fn_inception(options) -- luacheck: no unused args +function testdata.fn_inception(_options) checks({ we = { need = { @@ -90,27 +90,27 @@ local function deepchecks() end local _l_deepcheck = 2 + debug.getinfo(1).currentline -function testdata.fn_deepcheck(arg1) -- luacheck: no unused args +function testdata.fn_deepcheck(_arg1) deepchecks() end local _l_excess_checks = 2 + debug.getinfo(1).currentline -function testdata.fn_excess_checks(arg1) -- luacheck: no unused args +function testdata.fn_excess_checks(_arg1) checks('?number', '?string') end local _l_missing_checks = 2 + debug.getinfo(1).currentline -function testdata.fn_missing_checks(arg1, arg2) -- luacheck: no unused args +function testdata.fn_missing_checks(_arg1, _arg2) checks('?number') end local _l_bad_check_type_1 = 2 + debug.getinfo(1).currentline -function testdata.bad_check_type_1(arg1, arg2) -- luacheck: no unused args +function testdata.bad_check_type_1(_arg1, _arg2) checks("?string", 5) end local _l_bad_check_type_2 = 2 + debug.getinfo(1).currentline -function testdata.bad_check_type_2(arg1, arg2) -- luacheck: no unused args +function testdata.bad_check_type_2(_arg1, _arg2) checks({param = 5}) end @@ -294,12 +294,12 @@ local err_cases = { { code = 'fn_options({mynumber = "bad"})', line = _l_options, - error = 'bad argument options.mynumber to fn_options (?number expected, got string)', + error = 'bad argument _options.mynumber to fn_options (?number expected, got string)', }, { code = 'fn_options({badfield = "bad"})', line = _l_options, - error = 'unexpected argument options.badfield to fn_options', + error = 'unexpected argument _options.badfield to fn_options', }, -- fn_array @@ -311,32 +311,32 @@ local err_cases = { { code = 'fn_array()', line = _l_array, - error = 'bad argument array[1] to fn_array (number expected, got nil)', + error = 'bad argument _array[1] to fn_array (number expected, got nil)', }, { code = 'fn_array(nil)', line = _l_array, - error = 'bad argument array[1] to fn_array (number expected, got nil)', + error = 'bad argument _array[1] to fn_array (number expected, got nil)', }, { code = 'fn_array(box.NULL)', line = _l_array, - error = 'bad argument array[1] to fn_array (number expected, got nil)', + error = 'bad argument _array[1] to fn_array (number expected, got nil)', }, { code = 'fn_array({})', line = _l_array, - error = 'bad argument array[1] to fn_array (number expected, got nil)', + error = 'bad argument _array[1] to fn_array (number expected, got nil)', }, { code = 'fn_array({"str1"})', line = _l_array, - error = 'bad argument array[1] to fn_array (number expected, got string)', + error = 'bad argument _array[1] to fn_array (number expected, got string)', }, { code = 'fn_array({1})', line = _l_array, - error = 'bad argument array[2] to fn_array (number expected, got nil)', + error = 'bad argument _array[2] to fn_array (number expected, got nil)', }, { code = 'fn_array({1, 2})', @@ -344,7 +344,7 @@ local err_cases = { { code = 'fn_array({1, 2, 3})', line = _l_array, - error = 'unexpected argument array[3] to fn_array', + error = 'unexpected argument _array[3] to fn_array', }, -- fn_table @@ -356,17 +356,17 @@ local err_cases = { { code = 'fn_table()', line = _l_table, - error = 'bad argument table.mykey to fn_table (number expected, got nil)', + error = 'bad argument _table.mykey to fn_table (number expected, got nil)', }, { code = 'fn_table({})', line = _l_table, - error = 'bad argument table.mykey to fn_table (number expected, got nil)', + error = 'bad argument _table.mykey to fn_table (number expected, got nil)', }, { code = 'fn_table({mykey = "str"})', line = _l_table, - error = 'bad argument table.mykey to fn_table (number expected, got string)', + error = 'bad argument _table.mykey to fn_table (number expected, got string)', }, { code = 'fn_table({mykey = 0})', @@ -374,7 +374,7 @@ local err_cases = { { code = 'fn_table({mykey = 0, excess = 1})', line = _l_table, - error = 'unexpected argument table.excess to fn_table', + error = 'unexpected argument _table.excess to fn_table', }, -- fn_inception @@ -387,7 +387,7 @@ local err_cases = { { code = 'fn_inception({we = false})', line = _l_inception, - error = 'bad argument options.we to fn_inception (?table expected, got boolean)', + error = 'bad argument _options.we to fn_inception (?table expected, got boolean)', }, { code = 'fn_inception({we = {}})', @@ -407,7 +407,7 @@ local err_cases = { { code = 'fn_inception({we = {need = {to = {go = {deeper = {}}}}}})', line = _l_inception, - error = 'bad argument options.we.need.to.go.deeper to fn_inception (?number expected, got table)', + error = 'bad argument _options.we.need.to.go.deeper to fn_inception (?number expected, got table)', }, -- fn_deepcheck @@ -429,7 +429,7 @@ local err_cases = { { code = 'fn_missing_checks()', line = _l_missing_checks, - error = 'checks: argument "arg2" is not checked', + error = 'checks: argument "_arg2" is not checked', }, { code = 'bad_check_type_1()', @@ -583,34 +583,34 @@ for _, case in pairs(options_v2_cases) do end ------------------------------------------------------------------------------ -function testdata.fn_int64(arg) -- luacheck: no unused args +function testdata.fn_int64(_arg) checks('int64') end -function testdata.fn_uint64(arg) -- luacheck: no unused args +function testdata.fn_uint64(_arg) checks('uint64') end local uuid = require('uuid') testdata.myid = uuid() -function testdata.fn_uuid(arg) -- luacheck: no unused args +function testdata.fn_uuid(_arg) checks('uuid') end -function testdata.fn_uuid_str(arg) -- luacheck: no unused args +function testdata.fn_uuid_str(_arg) checks('uuid_str') end -function testdata.fn_uuid_bin(arg) -- luacheck: no unused args +function testdata.fn_uuid_bin(_arg) checks('uuid_bin') end -function testdata.fn_tuple(arg) -- luacheck: no unused args +function testdata.fn_tuple(_arg) checks('tuple') end -function testdata.fn_decimal(arg) -- luacheck: no unused args +function testdata.fn_decimal(_arg) checks('decimal') end @@ -619,13 +619,13 @@ if has_decimal then testdata.decimal = decimal end -function testdata.fn_error(arg) -- luacheck: no unused args +function testdata.fn_error(_arg) checks('error') end local has_error = (box.error ~= nil) and (box.error.new ~= nil) -function testdata.fn_datetime(arg) -- luacheck: no unused args +function testdata.fn_datetime(_arg) checks('datetime') end @@ -634,7 +634,7 @@ if has_datetime then testdata.datetime = datetime end -function testdata.fn_interval(arg) -- luacheck: no unused args +function testdata.fn_interval(_arg) checks('interval') end