From 346afd61c05675863e5a928e1ffa9360b7043f76 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Fri, 14 Jul 2017 16:51:19 +0200 Subject: [PATCH] Major restructure for finding documentation and function source. Fixes some issues --- function.lua | 101 ++++++++++++++++++----------------------- test/test_function.lua | 21 +++++++-- 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/function.lua b/function.lua index defd260..54f65af 100644 --- a/function.lua +++ b/function.lua @@ -112,51 +112,43 @@ local function get_line_index (str, line_nr) return index end -local function get_function_paramlist_and_body (str, start_line, end_line) - -- Will attempt to find a string which refer to a function starting on - -- line `start_line` and ending on line `end_line`. +local function get_function_paramlist_and_body (info) + -- Will attempt to find a string which refer to the function. This will + -- possibly require opening a file. - assert(type(str) == 'string') - assert(type(start_line) == 'number') - assert(type(end_line) == 'number') + -- Error check + assert(type(info) == 'table') - local start_line_index = get_line_index(str, start_line) - local end_line_index = get_line_index(str, end_line + 1) + if info.defined_how == 'C' then + error('[pretty.function/internal]: Cannot find source-code for C functions.', 2) + end + -- First find the string to search through. + local str = info.source + if info.defined_how == 'file' then + -- Read file + local file = io.open(info.short_src, 'r') + str = file:read '*all' + file:close() + end + + -- Calculate indices of the lines the function should be defined at. + local start_line_index = get_line_index(str, info.linedefined) + local end_line_index = get_line_index(str, info.lastlinedefined + 1) + + -- Now find the function parameters and the function body. local function_params, function_body = str:sub(start_line_index, end_line_index):match('.*%f[%a_]function%f[^%a_]%s*[a-zA-Z0-9_.]*%s*(%([a-zA-Z0-9_,. \t]*%))[ \t]*(.+)[ \t]*end') + assert(type(function_params) == 'string' and type(function_body) == 'string') function_body = function_body:match('^%s*(.-)%s*$') assert(type(function_params) == 'string' and type(function_body) == 'string') + -- And return them. return function_params, function_body end -local function get_function_body_from_file (filename, start_line, end_line) - assert(type(filename) == 'string') - assert(type(start_line) == 'number') - assert(type(end_line) == 'number') - - local file = io.open(filename, 'r') - local str = file:read('*all') - file:close() - return select(2, get_function_paramlist_and_body(str, start_line, end_line)) +local function get_function_string (...) + return string.format('function %s %s end', get_function_paramlist_and_body(...)) end -local function get_full_function_str (...) - local function_params, function_body = get_function_paramlist_and_body(...) - return 'function '..function_params..' '..function_body..' end' -end - -local function get_function_str_from_file (filename, start_line, end_line) - assert(type(filename) == 'string') - assert(type(start_line) == 'number') - assert(type(end_line) == 'number') - - local file = io.open(filename, 'r') - local str = file:read('*all') - file:close() - return get_full_function_str(str, start_line, end_line) -end - - local function width_of_strings_in_l (l, start_i, end_i) -- FIXME: Copy of the one in pretty.lua local width = 0 @@ -167,7 +159,7 @@ local function width_of_strings_in_l (l, start_i, end_i) end local function add_indent_to_string (str, indent) - assert(type(str) == 'string') + assert(type(str) == 'string') assert(type(indent) == 'string') return indent .. str:gsub('\n', '\n'..indent) @@ -210,12 +202,7 @@ local function format_function_with_closure (value, depth, l, format_value) local info = get_function_info(value) - local function_str = nil - if (info.defined_how == 'string') then - function_str = get_full_function_str(info.source, info.linedefined, info.lastlinedefined) - else - function_str = get_function_str_from_file(info.short_src, info.linedefined, info.lastlinedefined) - end + local function_str = get_function_string(info) if info.nups > 0 then l[#l+1] = '(function () ' end -- Upvalues @@ -247,11 +234,7 @@ return function (value, depth, l, format_value) if info.defined_how == 'string' and l.options.embed_loaded_funcs then -- Function was defined as a string. - function_params, function_body = get_function_paramlist_and_body(info.source, info.linedefined, info.lastlinedefined) - --elseif info.defined_how == 'file' then - --function_body = get_function_body_from_file(info.short_src, info.linedefined, info.lastlinedefined) - ----print(function_body) - --function_body = function_body or '...' + function_params, function_body = get_function_paramlist_and_body(info) end if info.builtin and l.options.short_builtins then @@ -297,7 +280,7 @@ return function (value, depth, l, format_value) -- Doc if not info.doc then - local function_body = get_function_body_from_file(info.short_src, info.linedefined, info.lastlinedefined) + local function_body = select(2, get_function_paramlist_and_body(info)) if function_body then local documentation = get_docs_from_function_body(function_body) info.doc = documentation ~= '' and documentation @@ -312,9 +295,13 @@ return function (value, depth, l, format_value) end -- source - if not info.builtin and not info.doc then + if info.doc then -- Do nothing + elseif info.defined_how == 'string' then + l[#l+1] = indent + l[#l+1] = '-- Loaded from string' + elseif not info.builtin then l[#l+1] = indent - l[#l+1] = ('-- source_file: \'%s\' '):format(info.short_src) + l[#l+1] = ('-- Source file: \'%s\' '):format(info.short_src) if info.linedefined == info.lastlinedefined then l[#l+1] = ('[Line: %i]'):format(info.linedefined) else @@ -325,7 +312,7 @@ return function (value, depth, l, format_value) -- upvalues if info.nups > 0 and (not info.builtin and not info.doc) then l[#l+1] = indent - l[#l+1] = '-- up_values: ' + l[#l+1] = '-- Up values: ' format_value(info.ups, depth + 1, l) end @@ -335,15 +322,17 @@ return function (value, depth, l, format_value) -- Native l[#l+1] = indent - l[#l+1] = '-- native_repr: ' + l[#l+1] = '-- Native Representation: ' l[#l+1] = tostring(value) -- Function body - l[#l+1] = indent - l[#l+1] = '--[[ function_body:\n\t' - l[#l+1] = add_indent_to_string(get_function_str_from_file(info.short_src, info.linedefined, info.lastlinedefined), l.options.indent) - l[#l+1] = indent - l[#l+1] = '--]]' + if info.defined_how ~= 'C' then + l[#l+1] = indent + l[#l+1] = '--[[ Function Body:\n\t' + l[#l+1] = add_indent_to_string(get_function_string(info), l.options.indent) + l[#l+1] = indent + l[#l+1] = '--]]' + end -- Full info l[#l+1] = indent diff --git a/test/test_function.lua b/test/test_function.lua index 4da72c4..6edc2c0 100644 --- a/test/test_function.lua +++ b/test/test_function.lua @@ -96,7 +96,7 @@ local func_line = curline(3) format_test { name = 'Singleline elaborate function', input = function () end, - expect = 'function ()\n -- source_file: \'./test/test_function.lua\' [Line: '..func_line..']\n\n ...\nend', + expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n\n ...\nend', } local func_line = curline(3) @@ -104,7 +104,7 @@ format_test { name = 'Multiline elaborate function', input = function () end, - expect = 'function ()\n -- source_file: \'./test/test_function.lua\' [Lines: '..func_line..' - '..(func_line+1)..']\n\n ...\nend', + expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Lines: '..func_line..' - '..(func_line+1)..']\n\n ...\nend', } local func_line = curline(3) -- Must be exactly 3 lines above function @@ -112,7 +112,7 @@ format_test { name = 'Elaborate function with upvalue included 1', input = function () l = TEST_UPVALUE end, adv_getlocal = true, - expect = 'function ()\n -- source_file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- up_values: { TEST_UPVALUE = 42 }\n\n ...\nend' + expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values: { TEST_UPVALUE = 42 }\n\n ...\nend' } local func_line = curline(3) -- Must be exactly 3 lines above function @@ -120,7 +120,7 @@ format_test { name = 'Elaborate function with upvalue included 2', input = function () TEST_UPVALUE = true end, adv_getlocal = true, - expect = 'function ()\n -- source_file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- up_values: { TEST_UPVALUE = 42 }\n\n ...\nend' + expect = 'function ()\n -- Source file: \'./test/test_function.lua\' [Line: '..func_line..']\n -- Up values: { TEST_UPVALUE = 42 }\n\n ...\nend' } -------------------------------------------------------------------------------- @@ -186,6 +186,18 @@ format_test { expect = 'function ()\n -- Hi\n\n ...\nend', } +format_test { + name = 'Can find docs from string-loaded function', + input = loadstring 'return function ()\n--Hello\nend' (), + expect = 'function ()\n -- Hello\n\n ...\nend', +} + +format_test { + name = 'String-loaded functions without docs, won\'t display Source file comment', + input = loadstring 'return function () end' (), + expect = 'function ()\n -- Loaded from string\n\n ...\nend', +} + -------------------------------------------------------------------------------- -- Builtins @@ -294,6 +306,7 @@ format_test { expect = 'function () function_body() end', } + -------------------------------------------------------------------------------- -- Indent functions nicely