lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On Mon, May 19, 2008 at 10:10 AM, Enrico Tassi <gareuselesinge@libero.it> wrote:
IIRC metalua has a module to do that check (but work on the abstract
syntax I think, not on the bytecode), but I've never tried it,
nor packaged it :-(

Yes it does, it's called metalint and it's one of the samples provided with the latest version of metalua. It requires metalua to be installed, obviously.

Actually, it does a bit more that merely detecting local variables: it checks all global variables, as well as entries in global modules, and makes sure they've been declared in an explicit declaration file *.dlua. That is, it will detect an erroneous call such as tttable.insert(), but also table.iiinsert().

Moreover, it optionally changes all global vars and [sub-]module entries into local variables, to speed up execution (it automates what some people do with idiom "local table_insert = table.insert"). For that, you need of course to let metalint compile your stuff into lua bytecode, and run that resulting bytecode instead of the original Lua sources.

The *.dlua syntax is extremely simple, and includes a wildcard (i.e. "silently accept every entries in module/table $FOOBAR, at an arbitrary level of nesting, without further checking"). Declaration files are loaded automatically when a require() is found in the sources, and are retrieved with the same algorithm as require()'s $LUA_PATH-based system. Check the README for more details.

An assumption behind metalint is that if you've got a project non-trivial enough to need strict variables checking, having a per-module list of exported APIs is a good idea anyway, and will only take a tiny amount of your time. By storing declarations in separate files, it lets you keep your sources 100% pure Lua (although it won't prevent you from using metalua extensions).

Metalint is a very simple ~200 LoC base, upon which many interesting static checking features should be implemented, when time permits.

There's no packaging for now. Assuming that metalua's installed in your path, you just need the metalint executable (source or bytecode with a "#!/usr/local/bin/lua\n" shebang) to be in your path, and $LUA_DPATH to point to your declaration director[y/ies].

I'm always interested by user feedbacks.

References:
* Latest metalua: http://repo.or.cz/w/metalua.git, get the top "snapshot" link
* Metalint declaration file examples: look at  http://repo.or.cz/w/metalua.git?a=tree;f=src/samples/metalint/dlua
* Metalint manual: http://repo.or.cz/w/metalua.git?a=blob_plain;f=src/samples/metalint/README.TXT
* Metalint annouce on the list: http://article.gmane.org/gmane.comp.lang.lua.general/46855