lua 代码静态分析

原文 2016-09-19 21:50:48 发表于 CSDN,这里对以前写的文章做下收录。

随着 lua 可移植性、热更特性被挖掘,越来越多项目使用 lua 做开发,但 lua 代码通常需要等代码跑起来且执行到才知道是否有错误,这对开发来说,不是很友好,文章讲解下 lua代码如何静态分析

lua项目代码静态分析的方法有两个:
1、使用lua编译器(luac)进行分析
2、使用luacheck插件进行分析

第一种方法,利用lua编译器对lua代码进行语法检查。这种方法简单有效:
luac [ options ] [ filenames ]
options 说明:

options  说明
-l 生成lua编译后字节码的可视化数据,这对于学习lua虚拟机很有帮助
-o file 编译lua代码,输出文件为file。默认生成 luac.out
-s 写入输出文件时去掉调试信息。可以减少输出文件的大小,但错误信息就比较简单,例如,少了行号和局部变量名
-v 显示版本信息

第二种方法,使用Luacheck对lua代码进行分析。这种方法是我比较推荐的,luacheck是个优秀的第三方插件,代码是MIT开源的,有兴趣点这里围观。Luacheck Git

Lua分析器(Luacheck)

Luacheck介绍

Luacheck是Lua一个静态分析工具,与Lua语言编译器相比,Luacheck可以对lua程序进行更加严格的错误分析。不但可检查出lua语法问题,而且可检查那些完全合乎语法但可能是错误的代码。换句话说,Luacheck能检查到lua程序中潜在的错误,如未定义的变量使用,未使用的变量和值,未定义的全局变量使用,执行不到的代码等等

Luacheck安装与使用

安装:

# git clone https://github.com/mpeterv/luacheck.git 
# cd luacheck
# ./install.lua /usr

使用:

# luacheck ./install.lua
Checking install.lua                              OK
Total: 0 warnings / 0 errors in 1 file

注意了,luacheck依赖lua,使用请确保lua已安装

如果想检查整个项目的lua代码,方法如下:

#!/bin/bash
Luas=`find . -name "*.lua"`
if [ "$Luas" != "" ]; then
  luacheck $Luas
fi

保存为 test.sh,执行,大致效果如下:

# chmod +x ./test.sh
# ./test.sh
Checking bin/luacheck.lua OK
Checking spec/check_spec.lua OK
Checking spec/lexer_spec.lua OK
Checking spec/cache_spec.lua OK
Checking spec/globbing_spec.lua OK
Checking spec/config_spec.lua OK
...

Total: 0 warnings / 0 errors in 42 files

Luacheck参数说明

Luacheck值得推荐的地方,除了能查找lua错误,更重要的是,它可以自定义捕捉的错误类型。可能有些写法我们不认为是错的,就可以避免显示出来。

# luacheck --help
Usage: luacheck ([--config <config>] | [--no-config]) [-g] [-u] [-r]
       [-a] [-s] [--no-self] [--std <std>] [-c] [-d] [-t] [-m]
       [--no-inline] [--filename <filename>] [-j <jobs>]
       [--formatter <formatter>] [-q] [--codes] [--ranges]
       [--no-color] [-v] [-h] <file> [<file>] ...
       [--globals [<global>] ...] [--read-globals [<global>] ...]
       [--new-globals [<global>] ...]
       [--new-read-globals [<global>] ...]
       [--ignore <patt> [<patt>] ...] [--enable <patt> [<patt>] ...]
       [--only <patt> [<patt>] ...]
       [--exclude-files <glob> [<glob>] ...]
       [--include-files <glob> [<glob>] ...]

这里重点介绍以下几个参数:
--no-unused 忽略变量未使用
--no-unused-args 忽略参数未使用
--no-redefined 忽略变量重定义
--globals <global> ... 忽略哪些全局变量
--ignore <patt> ... 忽略哪些错误提示
--quiet 只显示有错误的文件提示
--codes 显示错误编号

Luacheck示例
以例子说明前面几个参数吧。

# luacheck $Luas --no-unused --quiet --no-unused-args --no-redefined --no-color --globals table string --ignore 542 512
Total: 0 warnings / 0 errors in 42 files

解释以上,个别参数分别代表什么意思?
--globals table string 忽略全局变量table、string的声明和使用
--ignore 542 512 忽略编号为542、512的错误

至于 542 512分别代表什么,怎么得到的,看这里。

怎么得到一个错误的编号?

# cat ./test.lua
local t={}
for k,v in pairs(t) do
  return k,v
end
# luacheck ./test.lua --codes
Checking test.lua 1 warning

test.lua:2:1: (W512) loop is executed at most once

Total: 1 warning / 0 errors in 1 file

以上,512就是这个错误的编号,所以 --ignore 512就是忽略这个错误提示。

发表评论

邮箱地址不会被公开。 必填项已用*标注