blob: 7854f1f8f0734943cf28648db16dd473b8245679 [file] [log] [blame]
-------------------------------------------------------------------------------
-- Copyright (c) 2012 Sierra Wireless and others.
-- 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
--
-- Contributors:
-- Sierra Wireless - initial API and implementation
-------------------------------------------------------------------------------
local formatter = require 'formatter'
local compiler = require 'metalua.compiler'
local mlc = compiler.new()
local Q = require 'metalua.treequery'
local M = {}
local cache
local function buildcache(str)
-- Generate AST
local ast = mlc:src_to_ast(str)
local status, astvalid, errormsg = pcall(compiler.check_ast, ast)
if not astvalid then
return nil, string.format("Unable to build AST.%s", errormsg)
end
-- Cache string nodes
cache = {}
Q(ast):filter('String') :foreach(function(node)
if node.tag == 'String' then
table.insert(cache, node)
end
end)
return true
end
local function mustbeignored(offset)
if not cache then
return nil, 'Cache is not available.'
end
for _, node in ipairs(cache) do
if node.lineinfo.first.offset <= offset and offset <= node.lineinfo.last.offset then
return true
end
end
return false
end
function M.prettify(serializedtablestring)
-- Check input
if type(serializedtablestring) ~= 'string' then
return nil, 'String expected.'
end
local chartoindent = {
[','] = ',\n',
[';'] = ';\n',
['{'] = '{\n',
['}'] = '\n}\n'
}
--
-- Replace provided characters
--
for char, replacement in pairs(chartoindent) do
-- Refresh cache as offset of analyzed string change at each loop
local status, error = buildcache(serializedtablestring)
if not status then
return nil, error
end
--
-- Seek for character to replace
--
local buffer = {}
local searchstart= 1
local charposition = serializedtablestring:find(char, searchstart, true)
while charposition ~= nil do
-- Bufferize code before character
table.insert(buffer, serializedtablestring:sub(searchstart, charposition - 1))
-- Ensure that we can replace this character, avoiding thoses in strings
local ignoreposition, errormessage = mustbeignored(charposition)
if errormessage then
return nil, string.format('Unable to know if offset %d has to be formated.%s.', charposition, errormessage)
elseif ignoreposition then
-- Ignore character
table.insert(buffer, char)
else
-- Actual character replacement
table.insert(buffer, replacement)
end
-- Move to next replacement
searchstart = charposition + 1
charposition = serializedtablestring:find(char, searchstart, true)
end
-- Append remaining string
table.insert(buffer, serializedtablestring:sub(searchstart))
-- Replace original string
serializedtablestring = table.concat(buffer)
end
-- Format resulting code
return formatter.indentcode(serializedtablestring, '\n', true, '\t')
end
return M