Luacheck is a static analyzer and a linter for Lua [1]. Luacheck detects various issues such as usage of undefined global variables, unused variables and values, accessing uninitialized variables, unreachable code and more.
“Luacheck [2]”
The one real issue I have with Lua [3] is its dynamic typing [4]. Of all the bugs I fix in my own Lua code, I would say that the majority are due to typos (wrong variable name) or an unexpected type. So I was quite happy to come across and try out Luacheck. And fortunately, it's pretty straightforward to run [5].
I ran it over “Project: Sippy- Cup [6]” and … wow. The extensive regression test I have has already flushed out the typos and the unexpected type errors I tend to make. But Luacheck found quite a few unused variables (which is nice—it also found a bunch of unsused LPeg [7] expressions) and a ton of unintentional global variables (because I forgot to declare them with local).
The output is easy to read (here's a representative sample from some non- work related code I have):
>
```
Checking ptest-cr-select.lua **Failure**
ptest-cr-select.lua:53:9: variable **amount** was previously defined as an argument on line 52
ptest-cr-select.lua:128:9: variable **okay** is never accessed
ptest-cr-select.lua:193:40: unused argument **event**
ptest-cr-select.lua:197:43: shadowing upvalue **conn** on line 194
ptest-cr-select.lua:213:21: shadowing upvalue **argument** event on line 193
ptest-cr-select.lua:215:15: unused variable **rem**
ptest-cr-select.lua:215:15: shadowing upvalue **rem** on line 194
Total: **7** warnings / **0** errors in 1 file
```
About the only false positive it finds is this idiom:
>
```
function foo(param1,param2)
local param1 = param1 or "default value"
local param2 = param2 or 3
local a = ...
-- ...
end
```
where it will flag param1 and param2 as shadowing an upvalue. This idiom though, is used to provide a default value if a parameter isn't given to a function. It's easy enough to fix, either:
>
```
function foo(param1,param2)
param1 = param1 or "default value"
param2 = param2 or 3
local a = ...
-- ...
end
```
or
>
```
function foo(param1,param2)
local param1 = param1 or "default value" -- luacheck: ignore
local param2 = param2 or 3 -- luacheck: ignore
local a = ...
-- ...
end
```
Overall, I'm glad I found this tool. It's been a real eye opener.
[2] https://github.com/mpeterv/luacheck