]> git.lizzy.rs Git - minetest.git/blob - builtin/common/strict.lua
Always set globals in __newindex (#13131)
[minetest.git] / builtin / common / strict.lua
1 local getinfo, rawget, rawset = debug.getinfo, rawget, rawset
2
3 function core.global_exists(name)
4         if type(name) ~= "string" then
5                 error("core.global_exists: " .. tostring(name) .. " is not a string")
6         end
7         return rawget(_G, name) ~= nil
8 end
9
10
11 local meta = {}
12 local declared = {}
13 -- Key is source file, line, and variable name; separated by NULs
14 local warned = {}
15
16 function meta:__newindex(name, value)
17         rawset(self, name, value)
18         if declared[name] then
19                 return
20         end
21         local info = getinfo(2, "Sl")
22         local desc = ("%s:%d"):format(info.short_src, info.currentline)
23         local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
24         if not warned[warn_key] and info.what ~= "main" and info.what ~= "C" then
25                 core.log("warning", ("Assignment to undeclared global %q inside a function at %s.")
26                                 :format(name, desc))
27                 warned[warn_key] = true
28         end
29         declared[name] = true
30 end
31
32
33 function meta:__index(name)
34         if declared[name] then
35                 return
36         end
37         local info = getinfo(2, "Sl")
38         local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
39         if not warned[warn_key] and info.what ~= "C" then
40                 core.log("warning", ("Undeclared global variable %q accessed at %s:%s")
41                                 :format(name, info.short_src, info.currentline))
42                 warned[warn_key] = true
43         end
44 end
45
46 setmetatable(_G, meta)