| ------------------------------------------------------------------------------- |
| -- Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. |
| -- |
| -- This program and the accompanying materials are made available |
| -- under the terms of the Eclipse Public License v1.0 which |
| -- accompanies this distribution, and is available at |
| -- http://www.eclipse.org/legal/epl-v10.html |
| -- |
| -- This program and the accompanying materials are also made available |
| -- under the terms of the MIT public license which accompanies this |
| -- distribution, and is available at http://www.lua.org/license.html |
| -- |
| ------------------------------------------------------------------------------- |
| |
| -- |
| -- strict.lua |
| -- checks uses of undeclared global variables |
| -- All global variables must be 'declared' through a regular assignment |
| -- (even assigning nil will do) in a main chunk before being used |
| -- anywhere or assigned to inside a function. |
| -- |
| |
| local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget |
| |
| local mt = getmetatable(_G) |
| if mt == nil then |
| mt = {} |
| setmetatable(_G, mt) |
| end |
| |
| __strict = true |
| mt.__declared = {} |
| |
| local function what () |
| local d = getinfo(3, "S") |
| return d and d.what or "C" |
| end |
| |
| mt.__newindex = function (t, n, v) |
| if __strict and not mt.__declared[n] then |
| local w = what() |
| if w ~= "main" and w ~= "C" then |
| error("assign to undeclared variable '"..n.."'", 2) |
| end |
| mt.__declared[n] = true |
| end |
| rawset(t, n, v) |
| end |
| |
| mt.__index = function (t, n) |
| if __strict and not mt.__declared[n] and what() ~= "C" then |
| error("variable '"..n.."' is not declared", 2) |
| end |
| return rawget(t, n) |
| end |
| |
| function global(...) |
| for _, v in ipairs{...} do mt.__declared[v] = true end |
| end |