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