|
|
@ -31,9 +31,6 @@ local inspect ={ |
|
|
|
inspect.KEY = setmetatable({}, {__tostring = function() return 'inspect.KEY' end}) |
|
|
|
inspect.KEY = setmetatable({}, {__tostring = function() return 'inspect.KEY' end}) |
|
|
|
inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end}) |
|
|
|
inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end}) |
|
|
|
|
|
|
|
|
|
|
|
-- returns the length of a table, ignoring __len (if it exists) |
|
|
|
|
|
|
|
local rawlen = _G.rawlen or function(t) return #t end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Apostrophizes the string if it has quotes, but not aphostrophes |
|
|
|
-- Apostrophizes the string if it has quotes, but not aphostrophes |
|
|
|
-- Otherwise, it returns a regular quoted string |
|
|
|
-- Otherwise, it returns a regular quoted string |
|
|
|
local function smartQuote(str) |
|
|
|
local function smartQuote(str) |
|
|
@ -57,10 +54,10 @@ local function isIdentifier(str) |
|
|
|
return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" ) |
|
|
|
return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" ) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function isSequenceKey(k, length) |
|
|
|
local function isSequenceKey(k, sequenceLength) |
|
|
|
return type(k) == 'number' |
|
|
|
return type(k) == 'number' |
|
|
|
and 1 <= k |
|
|
|
and 1 <= k |
|
|
|
and k <= length |
|
|
|
and k <= sequenceLength |
|
|
|
and math.floor(k) == k |
|
|
|
and math.floor(k) == k |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
@ -86,13 +83,26 @@ local function sortKeys(a, b) |
|
|
|
return ta < tb |
|
|
|
return ta < tb |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- For implementation reasons, the behavior of rawlen & # is "undefined" when |
|
|
|
|
|
|
|
-- tables aren't pure sequences. So we implement our own # operator. |
|
|
|
|
|
|
|
local function getSequenceLength(t) |
|
|
|
|
|
|
|
local len = 1 |
|
|
|
|
|
|
|
local v = rawget(t,len) |
|
|
|
|
|
|
|
while v ~= nil do |
|
|
|
|
|
|
|
len = len + 1 |
|
|
|
|
|
|
|
v = rawget(t,len) |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
return len - 1 |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function getNonSequentialKeys(t) |
|
|
|
local function getNonSequentialKeys(t) |
|
|
|
local keys, length = {}, rawlen(t) |
|
|
|
local keys = {} |
|
|
|
|
|
|
|
local sequenceLength = getSequenceLength(t) |
|
|
|
for k,_ in pairs(t) do |
|
|
|
for k,_ in pairs(t) do |
|
|
|
if not isSequenceKey(k, length) then table.insert(keys, k) end |
|
|
|
if not isSequenceKey(k, sequenceLength) then table.insert(keys, k) end |
|
|
|
end |
|
|
|
end |
|
|
|
table.sort(keys, sortKeys) |
|
|
|
table.sort(keys, sortKeys) |
|
|
|
return keys |
|
|
|
return keys, sequenceLength |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function getToStringResultSafely(t, mt) |
|
|
|
local function getToStringResultSafely(t, mt) |
|
|
@ -234,8 +244,7 @@ function Inspector:putTable(t) |
|
|
|
else |
|
|
|
else |
|
|
|
if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end |
|
|
|
if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end |
|
|
|
|
|
|
|
|
|
|
|
local nonSequentialKeys = getNonSequentialKeys(t) |
|
|
|
local nonSequentialKeys, sequenceLength = getNonSequentialKeys(t) |
|
|
|
local length = rawlen(t) |
|
|
|
|
|
|
|
local mt = getmetatable(t) |
|
|
|
local mt = getmetatable(t) |
|
|
|
local toStringResult = getToStringResultSafely(t, mt) |
|
|
|
local toStringResult = getToStringResultSafely(t, mt) |
|
|
|
|
|
|
|
|
|
|
@ -243,11 +252,11 @@ function Inspector:putTable(t) |
|
|
|
self:down(function() |
|
|
|
self:down(function() |
|
|
|
if toStringResult then |
|
|
|
if toStringResult then |
|
|
|
self:puts(' -- ', escape(toStringResult)) |
|
|
|
self:puts(' -- ', escape(toStringResult)) |
|
|
|
if length >= 1 then self:tabify() end |
|
|
|
if sequenceLength >= 1 then self:tabify() end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local count = 0 |
|
|
|
local count = 0 |
|
|
|
for i=1, length do |
|
|
|
for i=1, sequenceLength do |
|
|
|
if count > 0 then self:puts(',') end |
|
|
|
if count > 0 then self:puts(',') end |
|
|
|
self:puts(' ') |
|
|
|
self:puts(' ') |
|
|
|
self:putValue(t[i]) |
|
|
|
self:putValue(t[i]) |
|
|
@ -273,7 +282,7 @@ function Inspector:putTable(t) |
|
|
|
|
|
|
|
|
|
|
|
if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing } |
|
|
|
if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing } |
|
|
|
self:tabify() |
|
|
|
self:tabify() |
|
|
|
elseif length > 0 then -- array tables have one extra space before closing } |
|
|
|
elseif sequenceLength > 0 then -- array tables have one extra space before closing } |
|
|
|
self:puts(' ') |
|
|
|
self:puts(' ') |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|