strict.lua 1.3 KB

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