xref: /f-stack/app/redis-5.0.5/deps/lua/etc/strict.lua (revision 572c4311)
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