transform back into metatable-based object-orientation

dev
kikito 10 years ago
parent 2961caa14a
commit d07147ed54
  1. 232
      inspect.lua

@ -170,142 +170,148 @@ local function processRecursive(process, item, path)
return processed return processed
end end
-------------------------------------------------------------------
function inspect.inspect(root, options)
options = options or {}
local depth = options.depth or math.huge
local process = options.process
if process then
root = processRecursive(process, root, {})
end
local tableAppearances = countTableAppearances(root) -------------------------------------------------------------------
local buffer = {} local Inspector = {}
local maxIds = setmetatable({}, maxIdsMetaTable) local Inspector_mt = {__index = Inspector}
local ids = setmetatable({}, idsMetaTable)
local level = 0
local blen = 0 -- buffer length
local function puts(...) function Inspector:puts(...)
local args = {...} local args = {...}
for i=1, #args do local buffer = self.buffer
blen = blen + 1 local len = #buffer
buffer[blen] = tostring(args[i]) for i=1, #args do
end len = len + 1
buffer[len] = tostring(args[i])
end end
end
local function down(f) function Inspector:down(f)
level = level + 1 self.level = self.level + 1
f() f()
level = level - 1 self.level = self.level - 1
end end
local function tabify() function Inspector:tabify()
puts("\n", string.rep(" ", level)) self:puts("\n", string.rep(" ", self.level))
end end
local function commaControl(needsComma) function Inspector:commaControl(needsComma)
if needsComma then puts(',') end if needsComma then self:puts(',') end
return true return true
end end
local function alreadyVisited(v) function Inspector:alreadyVisited(v)
return ids[type(v)][v] ~= nil return self.ids[type(v)][v] ~= nil
end end
local function getId(v) function Inspector:getId(v)
local tv = type(v) local tv = type(v)
local id = ids[tv][v] local id = self.ids[tv][v]
if not id then if not id then
id = maxIds[tv] + 1 id = self.maxIds[tv] + 1
maxIds[tv] = id self.maxIds[tv] = id
ids[tv][v] = id self.ids[tv][v] = id
end
return id
end end
return id
end
local putValue -- forward declaration that needs to go before putTable & putKey function Inspector:putKey(k)
if isIdentifier(k) then return self:puts(k) end
self:puts("[")
self:putValue(k)
self:puts("]")
end
local function putKey(k) function Inspector:putTable(t)
if isIdentifier(k) then return puts(k) end if self:alreadyVisited(t) then
puts( "[" ) self:puts('<table ', self:getId(t), '>')
putValue(k, {}) elseif self.level >= self.depth then
puts("]") self:puts('{...}')
end else
if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
local dictKeys = getDictionaryKeys(t)
local length = #t
local mt = getmetatable(t)
local to_string_result = getToStringResultSafely(t, mt)
self:puts('{')
self:down(function()
if to_string_result then
self:puts(' -- ', escape(to_string_result))
if length >= 1 then self:tabify() end
end
local function putTable(t) local needsComma = false
if alreadyVisited(t) then for i=1, length do
puts('<table ', getId(t), '>') needsComma = self:commaControl(needsComma)
elseif level >= depth then self:puts(' ')
puts('{...}') self:putValue(t[i])
else
if tableAppearances[t] > 1 then puts('<', getId(t), '>') end
local dictKeys = getDictionaryKeys(t)
local length = #t
local mt = getmetatable(t)
local to_string_result = getToStringResultSafely(t, mt)
puts('{')
down(function()
if to_string_result then
puts(' -- ', escape(to_string_result))
if length >= 1 then tabify() end -- tabify the array values
end
local needsComma = false
for i=1, length do
needsComma = commaControl(needsComma)
puts(' ')
putValue(t[i])
end
for _,k in ipairs(dictKeys) do
needsComma = commaControl(needsComma)
tabify()
putKey(k)
puts(' = ')
putValue(t[k])
end
if mt then
needsComma = commaControl(needsComma)
tabify()
puts('<metatable> = ')
putValue(mt)
end
end)
if #dictKeys > 0 or mt then -- dictionary table. Justify closing }
tabify()
elseif length > 0 then -- array tables have one extra space before closing }
puts(' ')
end end
puts('}') for _,k in ipairs(dictKeys) do
needsComma = self:commaControl(needsComma)
self:tabify()
self:putKey(k)
self:puts(' = ')
self:putValue(t[k])
end
if mt then
needsComma = self:commaControl(needsComma)
self:tabify()
self:puts('<metatable> = ')
self:putValue(mt)
end
end)
if #dictKeys > 0 or mt then -- dictionary table. Justify closing }
self:tabify()
elseif length > 0 then -- array tables have one extra space before closing }
self:puts(' ')
end end
self:puts('}')
end end
end
-- putvalue is forward-declared before putTable & putKey function Inspector:putValue(v)
putValue = function(v) local tv = type(v)
local tv = type(v)
if tv == 'string' then
self:puts(smartQuote(escape(v)))
elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
self:puts(tostring(v))
elseif tv == 'table' then
self:putTable(v)
else
self:puts('<',tv,' ',self:getId(v),'>')
end
end
if tv == 'string' then -------------------------------------------------------------------
puts(smartQuote(escape(v)))
elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then function inspect.inspect(root, options)
puts(tostring(v)) options = options or {}
elseif tv == 'table' then local depth = options.depth or math.huge
putTable(v) local process = options.process
else if process then
puts('<',tv,' ',getId(v),'>') root = processRecursive(process, root, {})
end
end end
putValue(root, {}) local inspector = setmetatable({
depth = depth,
buffer = {},
level = 0,
ids = setmetatable({}, idsMetaTable),
maxIds = setmetatable({}, maxIdsMetaTable),
tableAppearances = countTableAppearances(root)
}, Inspector_mt)
inspector:putValue(root)
return table.concat(buffer) return table.concat(inspector.buffer)
end end
setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end }) setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })

Loading…
Cancel
Save