Add strict module

Also fix leaking globals found by it.
This commit is contained in:
ShadowNinja 2014-06-05 12:40:34 -04:00
parent 6afdb22ba7
commit a6ba042cf7
4 changed files with 51 additions and 3 deletions

47
builtin/common/strict.lua Normal file

@ -0,0 +1,47 @@
-- Always warn when creating a global variable, even outside of a function.
-- This ignores mod namespaces (variables with the same name as the current mod).
local WARN_INIT = false
local function warn(message)
print(os.date("%H:%M:%S: WARNING: ")..message)
end
local meta = {}
local declared = {}
function meta:__newindex(name, value)
local info = debug.getinfo(2, "Sl")
local desc = ("%s:%d"):format(info.short_src, info.currentline)
if not declared[name] then
if info.what ~= "main" and info.what ~= "C" then
warn(("Assignment to undeclared global %q inside"
.." a function at %s.")
:format(name, desc))
end
declared[name] = true
end
-- Ignore mod namespaces
if WARN_INIT and (not core.get_current_modname or
name ~= core.get_current_modname()) then
warn(("Global variable %q created at %s.")
:format(name, desc))
end
rawset(self, name, value)
end
function meta:__index(name)
local info = debug.getinfo(2, "Sl")
if not declared[name] and info.what ~= "C" then
warn(("Undeclared global variable %q accessed at %s:%s")
:format(name, info.short_src, info.currentline))
end
return rawget(self, name)
end
setmetatable(_G, meta)

@ -7,7 +7,7 @@
function core.string_to_privs(str, delim) function core.string_to_privs(str, delim)
assert(type(str) == "string") assert(type(str) == "string")
delim = delim or ',' delim = delim or ','
privs = {} local privs = {}
for _, priv in pairs(string.split(str, delim)) do for _, priv in pairs(string.split(str, delim)) do
privs[priv:trim()] = true privs[priv:trim()] = true
end end
@ -17,7 +17,7 @@ end
function core.privs_to_string(privs, delim) function core.privs_to_string(privs, delim)
assert(type(privs) == "table") assert(type(privs) == "table")
delim = delim or ',' delim = delim or ','
list = {} local list = {}
for priv, bool in pairs(privs) do for priv, bool in pairs(privs) do
if bool then if bool then
table.insert(list, priv) table.insert(list, priv)

@ -56,7 +56,7 @@ core.register_entity(":__builtin:item", {
item_texture = core.registered_items[itemname].inventory_image item_texture = core.registered_items[itemname].inventory_image
item_type = core.registered_items[itemname].type item_type = core.registered_items[itemname].type
end end
prop = { local prop = {
is_visible = true, is_visible = true,
visual = "wielditem", visual = "wielditem",
textures = {itemname}, textures = {itemname},

@ -17,6 +17,7 @@ local gamepath = scriptdir.."game"..DIR_DELIM
local commonpath = scriptdir.."common"..DIR_DELIM local commonpath = scriptdir.."common"..DIR_DELIM
local asyncpath = scriptdir.."async"..DIR_DELIM local asyncpath = scriptdir.."async"..DIR_DELIM
dofile(commonpath.."strict.lua")
dofile(commonpath.."serialize.lua") dofile(commonpath.."serialize.lua")
dofile(commonpath.."misc_helpers.lua") dofile(commonpath.."misc_helpers.lua")