Merge pull request #20570 from lewis6991/refactor/lua2dox

refactor: lua2dox
This commit is contained in:
Lewis Russell
2022-10-11 08:28:36 +01:00
committed by GitHub
2 changed files with 163 additions and 235 deletions

View File

@@ -50,108 +50,46 @@ However I have put in a hack that will insert the "missing" close paren.
The effect is that you will get the function documented, but not with the parameter list you might expect. The effect is that you will get the function documented, but not with the parameter list you might expect.
]] ]]
local function class(BaseClass, ClassInitialiser) local function class()
local newClass = {} -- a new class newClass local newClass = {} -- a new class newClass
if not ClassInitialiser and type(BaseClass) == 'function' then
ClassInitialiser = BaseClass
BaseClass = nil
elseif type(BaseClass) == 'table' then
-- our new class is a shallow copy of the base class!
for i,v in pairs(BaseClass) do
newClass[i] = v
end
newClass._base = BaseClass
end
-- the class will be the metatable for all its newInstanceects, -- the class will be the metatable for all its newInstanceects,
-- and they will look up their methods in it. -- and they will look up their methods in it.
newClass.__index = newClass newClass.__index = newClass
-- expose a constructor which can be called by <classname>(<args>) -- expose a constructor which can be called by <classname>(<args>)
local classMetatable = {} setmetatable(newClass, {
classMetatable.__call = function(class_tbl, ...) __call = function(class_tbl, ...)
local newInstance = {} local newInstance = {}
setmetatable(newInstance, newClass) setmetatable(newInstance, newClass)
--if init then --if init then
-- init(newInstance,...) -- init(newInstance,...)
if class_tbl.init then if class_tbl.init then
class_tbl.init(newInstance, ...) class_tbl.init(newInstance, ...)
else
-- make sure that any stuff from the base class is initialized!
if BaseClass and BaseClass.init then
BaseClass.init(newInstance, ...)
end
end end
return newInstance return newInstance
end end
newClass.init = ClassInitialiser })
newClass.is_a = function(this, klass)
local thisMetatable = getmetatable(this)
while thisMetatable do
if thisMetatable == klass then
return true
end
thisMetatable = thisMetatable._base
end
return false
end
setmetatable(newClass, classMetatable)
return newClass return newClass
end end
--! \class TCore_Clock
--! \brief a clock
local TCore_Clock = class()
--! \brief get the current time
function TCore_Clock.GetTimeNow()
local gettimeofday = os.gettimeofday -- luacheck: ignore 143 Accessing an undefined field of a global variable.
if gettimeofday then
return gettimeofday()
else
return os.time()
end
end
--! \brief constructor
function TCore_Clock.init(this,T0)
if T0 then
this.t0 = T0
else
this.t0 = TCore_Clock.GetTimeNow()
end
end
--! \brief get time string
function TCore_Clock.getTimeStamp(this,T0)
local t0
if T0 then
t0 = T0
else
t0 = this.t0
end
return os.date('%c %Z',t0)
end
--! \brief write to stdout --! \brief write to stdout
local function TCore_IO_write(Str) local function TCore_IO_write(Str)
if (Str) then if Str then
io.write(Str) io.write(Str)
end end
end end
--! \brief write to stdout --! \brief write to stdout
local function TCore_IO_writeln(Str) local function TCore_IO_writeln(Str)
if (Str) then if Str then
io.write(Str) io.write(Str)
end end
io.write("\n") io.write('\n')
end end
--! \brief trims a string --! \brief trims a string
local function string_trim(Str) local function string_trim(Str)
return Str:match("^%s*(.-)%s*$") return Str:match('^%s*(.-)%s*$')
end end
--! \brief split a string --! \brief split a string
@@ -162,11 +100,11 @@ end
---@return string[] ---@return string[]
local function string_split(Str, Pattern) local function string_split(Str, Pattern)
local splitStr = {} local splitStr = {}
local fpat = "(.-)" .. Pattern local fpat = '(.-)' .. Pattern
local last_end = 1 local last_end = 1
local str, e, cap = string.find(Str, fpat, 1) local str, e, cap = string.find(Str, fpat, 1)
while str do while str do
if str ~= 1 or cap ~= "" then if str ~= 1 or cap ~= '' then
table.insert(splitStr, cap) table.insert(splitStr, cap)
end end
last_end = e + 1 last_end = e + 1
@@ -179,7 +117,6 @@ local function string_split(Str, Pattern)
return splitStr return splitStr
end end
--! \class TCore_Commandline --! \class TCore_Commandline
--! \brief reads/parses commandline --! \brief reads/parses commandline
local TCore_Commandline = class() local TCore_Commandline = class()
@@ -213,7 +150,6 @@ function TStream_Read.getContents(this,Filename)
assert(Filename) assert(Filename)
-- get lines from file -- get lines from file
-- syphon lines to our table -- syphon lines to our table
--TCore_Debug_show_var('Filename',Filename)
local filecontents = {} local filecontents = {}
for line in io.lines(Filename) do for line in io.lines(Filename) do
table.insert(filecontents, line) table.insert(filecontents, line)
@@ -371,7 +307,7 @@ local function checkComment4fn(Fn_magic,MagicLines)
return fn_magic return fn_magic
end end
local types = {"number", "string", "table", "list", "boolean", "function"} local types = { 'number', 'string', 'table', 'list', 'boolean', 'function' }
--! \brief run the filter --! \brief run the filter
function TLua2DoX_filter.readfile(this, AppStamp, Filename) function TLua2DoX_filter.readfile(this, AppStamp, Filename)
@@ -379,7 +315,7 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
local outStream = TStream_Write() local outStream = TStream_Write()
this.outStream = outStream -- save to this obj this.outStream = outStream -- save to this obj
if (inStream:getContents(Filename)) then if inStream:getContents(Filename) then
-- output the file -- output the file
local line local line
local fn_magic -- function name/def from magic comment local fn_magic -- function name/def from magic comment
@@ -395,8 +331,6 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
local l = 0 local l = 0
while not (inStream:eof()) do while not (inStream:eof()) do
line = string_trim(inStream:getLine()) line = string_trim(inStream:getLine())
-- TCore_Debug_show_var('inStream',inStream)
-- TCore_Debug_show_var('line',line )
l = l + 1 l = l + 1
if string.sub(line, 1, 2) == '--' then -- it's a comment if string.sub(line, 1, 2) == '--' then -- it's a comment
-- Allow people to write style similar to EmmyLua (since they are basically the same) -- Allow people to write style similar to EmmyLua (since they are basically the same)
@@ -414,22 +348,23 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
local magic_split = string_split(magic, ' ') local magic_split = string_split(magic, ' ')
if magic_split[1] == 'param' then if magic_split[1] == 'param' then
for _, type in ipairs(types) do for _, type in ipairs(types) do
magic = magic:gsub("^param%s+([a-zA-Z_?]+)%s+.*%((" .. type .. ")%)", "param %1 %2" ) magic = magic:gsub('^param%s+([a-zA-Z_?]+)%s+.*%((' .. type .. ')%)', 'param %1 %2')
magic = magic:gsub("^param%s+([a-zA-Z_?]+)%s+.*%((" .. type .. "|nil)%)", "param %1 %2" ) magic =
magic:gsub('^param%s+([a-zA-Z_?]+)%s+.*%((' .. type .. '|nil)%)', 'param %1 %2')
end end
magic_split = string_split(magic, ' ') magic_split = string_split(magic, ' ')
elseif magic_split[1] == 'return' then elseif magic_split[1] == 'return' then
for _, type in ipairs(types) do for _, type in ipairs(types) do
magic = magic:gsub("^return%s+.*%((" .. type .. ")%)", "return %1" ) magic = magic:gsub('^return%s+.*%((' .. type .. ')%)', 'return %1')
magic = magic:gsub("^return%s+.*%((" .. type .. "|nil)%)", "return %1" ) magic = magic:gsub('^return%s+.*%((' .. type .. '|nil)%)', 'return %1')
end end
magic_split = string_split(magic, ' ') magic_split = string_split(magic, ' ')
end end
if magic_split[1] == "generic" then if magic_split[1] == 'generic' then
local generic_name, generic_type = line:match("@generic%s*(%w+)%s*:?%s*(.*)") local generic_name, generic_type = line:match('@generic%s*(%w+)%s*:?%s*(.*)')
if generic_type == "" then if generic_type == '' then
generic_type = "any" generic_type = 'any'
end end
generic[generic_name] = generic_type generic[generic_name] = generic_type
else else
@@ -440,9 +375,9 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
if magic_split[type_index] then if magic_split[type_index] then
-- fix optional parameters -- fix optional parameters
if magic_split[type_index] and magic_split[2]:find("%?$") then if magic_split[type_index] and magic_split[2]:find('%?$') then
if not magic_split[type_index]:find("nil") then if not magic_split[type_index]:find('nil') then
magic_split[type_index] = magic_split[type_index] .. "|nil" magic_split[type_index] = magic_split[type_index] .. '|nil'
end end
magic_split[2] = magic_split[2]:sub(1, -2) magic_split[2] = magic_split[2]:sub(1, -2)
end end
@@ -454,8 +389,10 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
end end
-- surround some types by () -- surround some types by ()
for _, type in ipairs(types) do for _, type in ipairs(types) do
magic_split[type_index] = magic_split[type_index]:gsub("^(" .. type .. "|nil):?$", "(%1)") magic_split[type_index] =
magic_split[type_index] = magic_split[type_index]:gsub("^(" .. type .. "):?$", "(%1)") magic_split[type_index]:gsub('^(' .. type .. '|nil):?$', '(%1)')
magic_split[type_index] =
magic_split[type_index]:gsub('^(' .. type .. '):?$', '(%1)')
end end
end end
@@ -471,7 +408,7 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
line = string.sub(line, 5) -- nibble head line = string.sub(line, 5) -- nibble head
local comment = '' local comment = ''
local closeSquare, hitend, thisComment local closeSquare, hitend, thisComment
while (not hitend) and (not inStream:eof()) do while not hitend and (not inStream:eof()) do
closeSquare = string.find(line, ']]') closeSquare = string.find(line, ']]')
if not closeSquare then -- need to look on another line if not closeSquare then -- need to look on another line
thisComment = line .. '\n' thisComment = line .. '\n'
@@ -510,12 +447,6 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
-- ....v... -- ....v...
if pos_fn then if pos_fn then
-- we've got a function -- we've got a function
local fn_type
if string.find(line,'^local%s+') then
fn_type = ''--'static ' -- static functions seem to be excluded
else
fn_type = ''
end
local fn = TString_removeCommentFromLine(string_trim(string.sub(line, pos_fn + 8))) local fn = TString_removeCommentFromLine(string_trim(string.sub(line, pos_fn + 8)))
if fn_magic then if fn_magic then
fn = fn_magic fn = fn_magic
@@ -537,28 +468,31 @@ function TLua2DoX_filter.readfile(this,AppStamp,Filename)
end end
-- Big hax -- Big hax
if string.find(fn, ":") then if string.find(fn, ':') then
-- TODO: We need to add a first parameter of "SELF" here -- TODO: We need to add a first parameter of "SELF" here
-- local colon_place = string.find(fn, ":") -- local colon_place = string.find(fn, ":")
-- local name = string.sub(fn, 1, colon_place) -- local name = string.sub(fn, 1, colon_place)
fn = fn:gsub(":", ".", 1) fn = fn:gsub(':', '.', 1)
outStream:writeln("/// @param self") outStream:writeln('/// @param self')
local paren_start = string.find(fn, "(", 1, true) local paren_start = string.find(fn, '(', 1, true)
local paren_finish = string.find(fn, ")", 1, true) local paren_finish = string.find(fn, ')', 1, true)
-- Nothing in between the parens -- Nothing in between the parens
local comma local comma
if paren_finish == paren_start + 1 then if paren_finish == paren_start + 1 then
comma = "" comma = ''
else else
comma = ", " comma = ', '
end end
fn = string.sub(fn, 1, paren_start) .. "self" .. comma .. string.sub(fn, paren_start + 1) fn = string.sub(fn, 1, paren_start)
.. 'self'
.. comma
.. string.sub(fn, paren_start + 1)
end end
-- add vanilla function -- add vanilla function
outStream:writeln(fn_type .. 'function ' .. fn .. '{}') outStream:writeln('function ' .. fn .. '{}')
end end
else else
this:warning(inStream:getLineNo(), 'something weird here') this:warning(inStream:getLineNo(), 'something weird here')
@@ -593,16 +527,14 @@ local TApp = class()
--! \brief constructor --! \brief constructor
function TApp.init(this) function TApp.init(this)
local t0 = TCore_Clock() this.timestamp = os.date('%c %Z', os.time())
this.timestamp = t0:getTimeStamp()
this.name = 'Lua2DoX' this.name = 'Lua2DoX'
this.version = '0.2 20130128' this.version = '0.2 20130128'
this.copyright = 'Copyright (c) Simon Dales 2012-13' this.copyright = 'Copyright (c) Simon Dales 2012-13'
end end
function TApp.getRunStamp(this) function TApp.getRunStamp(this)
return this.name .. ' (' .. this.version .. ') ' return this.name .. ' (' .. this.version .. ') ' .. this.timestamp
.. this.timestamp
end end
function TApp.getVersion(this) function TApp.getVersion(this)
@@ -642,5 +574,4 @@ else
filter:readfile(appStamp, filename) filter:readfile(appStamp, filename)
end end
--eof --eof

View File

@@ -25,9 +25,8 @@ LANG=""
test_executable() { test_executable() {
P_EXE="$1" P_EXE="$1"
######### #########
WHICH=`which ${P_EXE}` WHICH=$(which "$P_EXE")
if test -z "${WHICH}" if test -z "${WHICH}"; then
then
echo "not found \"${P_EXE}\"" echo "not found \"${P_EXE}\""
else else
EXE="${P_EXE}" EXE="${P_EXE}"
@@ -57,30 +56,28 @@ do_readlink(){
pushd . > /dev/null pushd . > /dev/null
TARGET_FILE=$1 TARGET_FILE=$1
cd `dirname $TARGET_FILE` cd "$(dirname $TARGET_FILE)"
TARGET_FILE=`basename $TARGET_FILE` TARGET_FILE=$(basename "$TARGET_FILE")
# Iterate down a (possible) chain of symlinks # Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ] while [ -L "$TARGET_FILE" ]; do
do TARGET_FILE=$(readlink "$TARGET_FILE")
TARGET_FILE=`readlink $TARGET_FILE` cd $(dirname "$TARGET_FILE")
cd `dirname $TARGET_FILE` TARGET_FILE=$(basename "$TARGET_FILE")
TARGET_FILE=`basename $TARGET_FILE`
done done
PHYS_DIR=`pwd -P` PHYS_DIR=$(pwd -P)
RESULT=$PHYS_DIR RESULT=$PHYS_DIR
popd > /dev/null popd > /dev/null
} }
##main ##main
set_lua set_lua
if test -z "${EXE}" if test -z "${EXE}"; then
then
echo "no lua interpreter found" echo "no lua interpreter found"
exit 1 exit 1
else else
BASENAME=`basename "$0"` BASENAME=$(basename "$0")
do_readlink "$0" do_readlink "$0"
DIRNAME="${RESULT}" DIRNAME="${RESULT}"
@@ -89,5 +86,5 @@ else
${EXE} ${LUASCRIPT} $@ ${EXE} ${LUASCRIPT} $@
fi fi
#
##eof ##eof