strict.lua 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. if info ~= nil then
  19. local desc = ("%s:%d"):format(info.short_src, info.currentline)
  20. local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
  21. if not warned[warn_key] and info.what ~= "main" and info.what ~= "C" then
  22. core.log("warning", ("Assignment to undeclared global %q inside a function at %s.")
  23. :format(name, desc))
  24. warned[warn_key] = true
  25. end
  26. end
  27. declared[name] = true
  28. end
  29. function meta:__index(name)
  30. if declared[name] then
  31. return
  32. end
  33. local info = getinfo(2, "Sl")
  34. if info == nil then
  35. return
  36. end
  37. local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
  38. if not warned[warn_key] and info.what ~= "C" then
  39. core.log("warning", ("Undeclared global variable %q accessed at %s:%s")
  40. :format(name, info.short_src, info.currentline))
  41. warned[warn_key] = true
  42. end
  43. end
  44. setmetatable(_G, meta)