Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
lua-inspect/lib/luainspect/dump.lua
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
90 lines (79 sloc)
2.66 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- Recursive object dumper, for debugging. | |
| -- (c) 2010 David Manura, MIT License. | |
| local M = {} | |
| -- My own object dumper. | |
| -- Intended for debugging, not serialization, with compact formatting. | |
| -- Robust against recursion. | |
| -- Renders Metalua table tag fields specially {tag=X, ...} --> "`X{...}". | |
| -- On first call, only pass parameter o. | |
| -- CATEGORY: AST debug | |
| local ignore_keys_ = {lineinfo=true} | |
| local norecurse_keys_ = {parent=true, ast=true} | |
| local function dumpstring_key_(k, isseen, newindent) | |
| local ks = type(k) == 'string' and k:match'^[%a_][%w_]*$' and k or | |
| '[' .. M.dumpstring(k, isseen, newindent) .. ']' | |
| return ks | |
| end | |
| local function sort_keys_(a, b) | |
| if type(a) == 'number' and type(b) == 'number' then | |
| return a < b | |
| elseif type(a) == 'number' then | |
| return false | |
| elseif type(b) == 'number' then | |
| return true | |
| elseif type(a) == 'string' and type(b) == 'string' then | |
| return a < b | |
| else | |
| return tostring(a) < tostring(b) -- arbitrary | |
| end | |
| end | |
| function M.dumpstring(o, isseen, indent, key) | |
| isseen = isseen or {} | |
| indent = indent or '' | |
| if type(o) == 'table' then | |
| if isseen[o] or norecurse_keys_[key] then | |
| return (type(o.tag) == 'string' and '`' .. o.tag .. ':' or '') .. tostring(o) | |
| else isseen[o] = true end -- avoid recursion | |
| local used = {} | |
| local tag = o.tag | |
| local s = '{' | |
| if type(o.tag) == 'string' then | |
| s = '`' .. tag .. s; used['tag'] = true | |
| end | |
| local newindent = indent .. ' ' | |
| local ks = {}; for k in pairs(o) do ks[#ks+1] = k end | |
| table.sort(ks, sort_keys_) | |
| --for i,k in ipairs(ks) do print ('keys', k) end | |
| local forcenummultiline | |
| for k in pairs(o) do | |
| if type(k) == 'number' and type(o[k]) == 'table' then forcenummultiline = true end | |
| end | |
| -- inline elements | |
| for _,k in ipairs(ks) do | |
| if used[k] then -- skip | |
| elseif ignore_keys_[k] then used[k] = true | |
| elseif (type(k) ~= 'number' or not forcenummultiline) and | |
| type(k) ~= 'table' and (type(o[k]) ~= 'table' or norecurse_keys_[k]) | |
| then | |
| s = s .. dumpstring_key_(k, isseen, newindent) .. '=' .. M.dumpstring(o[k], isseen, newindent, k) .. ', ' | |
| used[k] = true | |
| end | |
| end | |
| -- elements on separate lines | |
| local done | |
| for _,k in ipairs(ks) do | |
| if not used[k] then | |
| if not done then s = s .. '\n'; done = true end | |
| s = s .. newindent .. dumpstring_key_(k, isseen) .. '=' .. M.dumpstring(o[k], isseen, newindent, k) .. ',\n' | |
| end | |
| end | |
| s = s:gsub(',(%s*)$', '%1') | |
| s = s .. (done and indent or '') .. '}' | |
| return s | |
| elseif type(o) == 'string' then | |
| return string.format('%q', o) | |
| else | |
| return tostring(o) | |
| end | |
| end | |
| return M | |