1*572c4311Sfengbojiang-- 2*572c4311Sfengbojiang-- strict.lua 3*572c4311Sfengbojiang-- checks uses of undeclared global variables 4*572c4311Sfengbojiang-- All global variables must be 'declared' through a regular assignment 5*572c4311Sfengbojiang-- (even assigning nil will do) in a main chunk before being used 6*572c4311Sfengbojiang-- anywhere or assigned to inside a function. 7*572c4311Sfengbojiang-- 8*572c4311Sfengbojiang 9*572c4311Sfengbojianglocal getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget 10*572c4311Sfengbojiang 11*572c4311Sfengbojianglocal mt = getmetatable(_G) 12*572c4311Sfengbojiangif mt == nil then 13*572c4311Sfengbojiang mt = {} 14*572c4311Sfengbojiang setmetatable(_G, mt) 15*572c4311Sfengbojiangend 16*572c4311Sfengbojiang 17*572c4311Sfengbojiangmt.__declared = {} 18*572c4311Sfengbojiang 19*572c4311Sfengbojianglocal function what () 20*572c4311Sfengbojiang local d = getinfo(3, "S") 21*572c4311Sfengbojiang return d and d.what or "C" 22*572c4311Sfengbojiangend 23*572c4311Sfengbojiang 24*572c4311Sfengbojiangmt.__newindex = function (t, n, v) 25*572c4311Sfengbojiang if not mt.__declared[n] then 26*572c4311Sfengbojiang local w = what() 27*572c4311Sfengbojiang if w ~= "main" and w ~= "C" then 28*572c4311Sfengbojiang error("assign to undeclared variable '"..n.."'", 2) 29*572c4311Sfengbojiang end 30*572c4311Sfengbojiang mt.__declared[n] = true 31*572c4311Sfengbojiang end 32*572c4311Sfengbojiang rawset(t, n, v) 33*572c4311Sfengbojiangend 34*572c4311Sfengbojiang 35*572c4311Sfengbojiangmt.__index = function (t, n) 36*572c4311Sfengbojiang if not mt.__declared[n] and what() ~= "C" then 37*572c4311Sfengbojiang error("variable '"..n.."' is not declared", 2) 38*572c4311Sfengbojiang end 39*572c4311Sfengbojiang return rawget(t, n) 40*572c4311Sfengbojiangend 41*572c4311Sfengbojiang 42