aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2023-07-18 12:24:53 +0100
committerGitHub <noreply@github.com>2023-07-18 12:24:53 +0100
commit9fcb0a64ee9195434113c10cb6e958cfe3b2c2cd (patch)
tree039c2b28116857111e885f84b64d55de97601e96
parente4da418ba8388e94bb186e3f9a2004ee1e96f1e5 (diff)
downloadrneovim-9fcb0a64ee9195434113c10cb6e958cfe3b2c2cd.tar.gz
rneovim-9fcb0a64ee9195434113c10cb6e958cfe3b2c2cd.tar.bz2
rneovim-9fcb0a64ee9195434113c10cb6e958cfe3b2c2cd.zip
refactor(lua2dox): overhaul (#24386)
-rw-r--r--runtime/doc/lua.txt8
-rw-r--r--runtime/doc/treesitter.txt7
-rw-r--r--scripts/lua2dox.lua774
3 files changed, 310 insertions, 479 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index fd75fdb2dd..ac40d61e20 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -674,7 +674,7 @@ vim.regex:match_str({str}) *regex:match_str()*
match is returned. When there is no match, `nil` is returned. As any integer is truth-y, `regex:match()` can be directly used as a condition in an if-statement.
Parameters: ~
- • {str} (string)
+ • {str} (string)
==============================================================================
@@ -1988,13 +1988,13 @@ vim.Ringbuf:peek() *Ringbuf:peek()*
Returns the first unread item without removing it
Return: ~
- any?|ni
+ any?|nil
vim.Ringbuf:pop() *Ringbuf:pop()*
Removes and returns the first unread item
Return: ~
- any?|ni
+ any?|nil
vim.Ringbuf:push({item}) *Ringbuf:push()*
Adds an item, overriding the oldest item if the buffer is full.
@@ -3044,7 +3044,7 @@ vim.version.last({versions}) *vim.version.last()*
• {versions} Version []
Return: ~
- Version ?|ni
+ Version ?|nil
vim.version.lt({v1}, {v2}) *vim.version.lt()*
Returns `true` if `v1 < v2` . See |vim.version.cmp()| for usage.
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index bb0d435f4a..1effc87500 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -1035,7 +1035,7 @@ set({lang}, {query_name}, {text}) *vim.treesitter.query.set()*
Lua module: vim.treesitter.highlighter *lua-treesitter-highlighter*
TSHighlighter:destroy() *TSHighlighter:destroy()*
- Removes all internal references to the highlighter
+ Removes all internal references to the highlighter.
==============================================================================
@@ -1100,7 +1100,8 @@ LanguageTree:destroy() *LanguageTree:destroy()*
Any cleanup logic should be performed here.
- Note: This DOES NOT remove this tree from a parent. Instead, `remove_child` must be called on the parent to remove it.
+ Note: This DOES NOT remove this tree from a parent. Instead,
+ `remove_child` must be called on the parent to remove it.
*LanguageTree:for_each_child()*
LanguageTree:for_each_child({fn}, {include_self})
@@ -1117,7 +1118,7 @@ LanguageTree:for_each_tree({fn}) *LanguageTree:for_each_tree()*
Note: This includes the invoking tree's child trees as well.
Parameters: ~
- • {fn} fun(tree: TSTree, ltree: LanguageTree)
+ • {fn} fun(tree: TSTree, ltree: LanguageTree)
LanguageTree:included_regions() *LanguageTree:included_regions()*
Gets the set of included regions
diff --git a/scripts/lua2dox.lua b/scripts/lua2dox.lua
index 55cb566ca3..be72b9e1c0 100644
--- a/scripts/lua2dox.lua
+++ b/scripts/lua2dox.lua
@@ -1,6 +1,6 @@
---[[--------------------------------------------------------------------------
--- Copyright (C) 2012 by Simon Dales --
--- simon@purrsoft.co.uk --
+-----------------------------------------------------------------------------
+-- Copyright (C) 2012 by Simon Dales --
+-- simon@purrsoft.co.uk --
-- --
-- This program is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by --
@@ -16,7 +16,7 @@
-- along with this program; if not, write to the --
-- Free Software Foundation, Inc., --
-- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --
-----------------------------------------------------------------------------]]
+-----------------------------------------------------------------------------
--[[!
Lua-to-Doxygen converter
@@ -48,536 +48,364 @@ It only has to be good enough for doxygen to see it as legal.
One limitation is that each line is treated separately (except for long comments).
The implication is that class and function declarations must be on the same line.
-Some functions can have their parameter lists extended over multiple lines to make it look neat.
-Managing this where there are also some comments is a bit more coding than I want to do at this stage,
-so it will probably not document accurately if we do do this.
-However I have put in a hack that will insert the "missing" close paren.
+There is 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.
]]
-local _debug_outfile = nil
-local _debug_output = {}
-
-local function class()
- local newClass = {} -- a new class newClass
- -- the class will be the metatable for all its newInstanceects,
- -- and they will look up their methods in it.
- newClass.__index = newClass
-
- -- expose a constructor which can be called by <classname>(<args>)
- setmetatable(newClass, {
- __call = function(class_tbl, ...)
- local newInstance = {}
- setmetatable(newInstance, newClass)
- --if init then
- -- init(newInstance,...)
- if class_tbl.init then
- class_tbl.init(newInstance, ...)
- end
- return newInstance
- end
- })
- return newClass
-end
+local TYPES = { 'integer', 'number', 'string', 'table', 'list', 'boolean', 'function' }
--- write to stdout
-local function TCore_IO_write(Str)
- if Str then
- io.write(Str)
- if _debug_outfile then
- table.insert(_debug_output, Str)
- end
- end
-end
+local TAGGED_TYPES = { 'TSNode', 'LanguageTree' }
--- write to stdout
-local function TCore_IO_writeln(Str)
- TCore_IO_write(Str)
- TCore_IO_write('\n')
-end
+-- Document these as 'table'
+local ALIAS_TYPES = { 'Range', 'Range4', 'Range6', 'TSMetadata' }
--- trims a string
-local function string_trim(Str)
- return Str:match('^%s*(.-)%s*$')
-end
+local debug_outfile = nil --- @type string?
+local debug_output = {}
--- split a string
---!
---! \param Str
---! \param Pattern
---! \returns table of string fragments
----@return string[]
-local function string_split(Str, Pattern)
- local splitStr = {}
- local fpat = '(.-)' .. Pattern
- local last_end = 1
- local str, e, cap = string.find(Str, fpat, 1)
- while str do
- if str ~= 1 or cap ~= '' then
- table.insert(splitStr, cap)
- end
- last_end = e + 1
- str, e, cap = string.find(Str, fpat, last_end)
+--- write to stdout
+--- @param str? string
+local function write(str)
+ if not str then
+ return
end
- if last_end <= #Str then
- cap = string.sub(Str, last_end)
- table.insert(splitStr, cap)
+
+ io.write(str)
+ if debug_outfile then
+ table.insert(debug_output, str)
end
- return splitStr
end
--------------------------------
--- file buffer
---!
---! an input file buffer
-local TStream_Read = class()
-
--- get contents of file
---!
---! \param Filename name of file to read (or nil == stdin)
-function TStream_Read.getContents(this, Filename)
- assert(Filename, ('invalid file: %s'):format(Filename))
+--- write to stdout
+--- @param str? string
+local function writeln(str)
+ write(str)
+ write('\n')
+end
+
+--- an input file buffer
+--- @class StreamRead
+--- @field currentLine string?
+--- @field contentsLen integer
+--- @field currentLineNo integer
+--- @field filecontents string[]
+local StreamRead = {}
+
+--- @return StreamRead
+--- @param filename string
+function StreamRead.new(filename)
+ assert(filename, ('invalid file: %s'):format(filename))
-- get lines from file
-- syphon lines to our table
- local filecontents = {}
- for line in io.lines(Filename) do
- table.insert(filecontents, line)
- end
-
- if filecontents then
- this.filecontents = filecontents
- this.contentsLen = #filecontents
- this.currentLineNo = 1
+ local filecontents = {} --- @type string[]
+ for line in io.lines(filename) do
+ filecontents[#filecontents+1] = line
end
- return filecontents
-end
-
--- get lineno
-function TStream_Read.getLineNo(this)
- return this.currentLineNo
+ return setmetatable({
+ filecontents = filecontents,
+ contentsLen = #filecontents,
+ currentLineNo = 1,
+ }, { __index = StreamRead })
end
-- get a line
-function TStream_Read.getLine(this)
- local line
- if this.currentLine then
- line = this.currentLine
- this.currentLine = nil
- else
- -- get line
- if this.currentLineNo <= this.contentsLen then
- line = this.filecontents[this.currentLineNo]
- this.currentLineNo = this.currentLineNo + 1
- else
- line = ''
- end
+function StreamRead:getLine()
+ if self.currentLine then
+ self.currentLine = nil
+ return self.currentLine
end
- return line
+
+ -- get line
+ if self.currentLineNo <= self.contentsLen then
+ local line = self.filecontents[self.currentLineNo]
+ self.currentLineNo = self.currentLineNo + 1
+ return line
+ end
+
+ return ''
end
-- save line fragment
-function TStream_Read.ungetLine(this, LineFrag)
- this.currentLine = LineFrag
+--- @param line_fragment string
+function StreamRead:ungetLine(line_fragment)
+ self.currentLine = line_fragment
end
-- is it eof?
-function TStream_Read.eof(this)
- if this.currentLine or this.currentLineNo <= this.contentsLen then
- return false
+function StreamRead:eof()
+ return not self.currentLine and self.currentLineNo > self.contentsLen
+end
+
+-- input filter
+--- @class Lua2DoxFilter
+local Lua2DoxFilter = {}
+setmetatable(Lua2DoxFilter, { __index = Lua2DoxFilter })
+
+--- trim comment off end of string
+---
+--- @param line string
+--- @return string, string?
+local function removeCommentFromLine(line)
+ local pos_comment = line:find('%-%-')
+ if not pos_comment then
+ return line
end
- return true
+ return line:sub(1, pos_comment - 1), line:sub(pos_comment)
end
--- output stream
-local TStream_Write = class()
+--- @param line string
+--- @param generics table<string,string>
+--- @return string?
+local function process_magic(line, generics)
+ line = line:gsub('^%s+@', '@')
+ line = line:gsub('@package', '@private')
--- constructor
-function TStream_Write.init(this)
- this.tailLine = {}
-end
+ if not vim.startswith(line, '@') then -- it's a magic comment
+ return '/// ' .. line
+ end
--- write immediately
-function TStream_Write.write(_, Str)
- TCore_IO_write(Str)
-end
+ local magic = line:sub(2)
+ local magic_split = vim.split(magic, ' ', { plain = true })
+ local directive = magic_split[1]
--- write immediately
-function TStream_Write.writeln(_, Str)
- TCore_IO_writeln(Str)
-end
+ if vim.list_contains({
+ 'cast', 'diagnostic', 'overload', 'meta', 'type'
+ }, directive) then
+ -- Ignore LSP directives
+ return '// gg:"' .. line .. '"'
+ end
--- write immediately
-function TStream_Write.writelnComment(_, Str)
- TCore_IO_write('// ZZ: ')
- TCore_IO_writeln(Str)
-end
+ if directive == 'defgroup' or directive == 'addtogroup' then
+ -- Can't use '.' in defgroup, so convert to '--'
+ return '/// @' .. magic:gsub('%.', '-dot-')
+ end
--- write to tail
-function TStream_Write.writelnTail(this, Line)
- if not Line then
- Line = ''
+ if directive == 'generic' then
+ local generic_name, generic_type = line:match('@generic%s*(%w+)%s*:?%s*(.*)')
+ if generic_type == '' then
+ generic_type = 'any'
+ end
+ generics[generic_name] = generic_type
+ return
end
- table.insert(this.tailLine, Line)
-end
--- output tail lines
-function TStream_Write.write_tailLines(this)
- for _, line in ipairs(this.tailLine) do
- TCore_IO_writeln(line)
+ local type_index = 2
+
+ if directive == 'param' then
+ 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 .. '|nil)%)', 'param %1 %2')
+ end
+ magic_split = vim.split(magic, ' ', { plain = true })
+ type_index = 3
+ elseif directive == 'return' then
+ for _, type in ipairs(TYPES) do
+ magic = magic:gsub('^return%s+.*%((' .. type .. ')%)', 'return %1')
+ magic = magic:gsub('^return%s+.*%((' .. type .. '|nil)%)', 'return %1')
+ end
+ -- handle the return of vim.spell.check
+ magic = magic:gsub('({.*}%[%])', '`%1`')
+ magic_split = vim.split(magic, ' ', { plain = true })
end
- TCore_IO_write('// Lua2DoX new eof')
-end
--- input filter
-local TLua2DoX_filter = class()
+ local ty = magic_split[type_index]
--- allow us to do errormessages
-function TLua2DoX_filter.warning(this, Line, LineNo, Legend)
- this.outStream:writelnTail(
- '//! \todo warning! ' .. Legend .. ' (@' .. LineNo .. ')"' .. Line .. '"'
- )
-end
+ if ty then
+ -- fix optional parameters
+ if magic_split[2]:find('%?$') then
+ if not ty:find('nil') then
+ ty = ty .. '|nil'
+ end
+ magic_split[2] = magic_split[2]:sub(1, -2)
+ end
+
+ -- replace generic types
+ for k, v in pairs(generics) do
+ ty = ty:gsub(k, v) --- @type string
+ end
+
+ for _, type in ipairs(TAGGED_TYPES) do
+ ty = ty:gsub(type, '|%1|')
+ end
+
+ for _, type in ipairs(ALIAS_TYPES) do
+ ty = ty:gsub('^'..type..'$', 'table') --- @type string
+ end
+
+ -- surround some types by ()
+ for _, type in ipairs(TYPES) do
+ ty = ty
+ :gsub('^(' .. type .. '|nil):?$', '(%1)')
+ :gsub('^(' .. type .. '):?$', '(%1)')
+ end
+
+ magic_split[type_index] = ty
--- trim comment off end of string
---!
---! If the string has a comment on the end, this trims it off.
---!
-local function TString_removeCommentFromLine(Line)
- local pos_comment = string.find(Line, '%-%-')
- local tailComment
- if pos_comment then
- Line = string.sub(Line, 1, pos_comment - 1)
- tailComment = string.sub(Line, pos_comment)
end
- return Line, tailComment
+
+ magic = table.concat(magic_split, ' ')
+
+ return '/// @' .. magic
end
--- get directive from magic
-local function getMagicDirective(Line)
- local macro, tail
- local macroStr = '[\\@]'
- local pos_macro = string.find(Line, macroStr)
- if pos_macro then
- --! ....\\ macro...stuff
- --! ....\@ macro...stuff
- local line = string.sub(Line, pos_macro + 1)
- local space = string.find(line, '%s+')
- if space then
- macro = string.sub(line, 1, space - 1)
- tail = string_trim(string.sub(line, space + 1))
+--- @param line string
+--- @param in_stream StreamRead
+--- @return string
+local function process_block_comment(line, in_stream)
+ local comment_parts = {} --- @type string[]
+ local done --- @type boolean?
+
+ while not done and not in_stream:eof() do
+ local thisComment --- @type string?
+ local closeSquare = line:find(']]')
+ if not closeSquare then -- need to look on another line
+ thisComment = line .. '\n'
+ line = in_stream:getLine()
else
- macro = line
- tail = ''
+ thisComment = line:sub(1, closeSquare - 1)
+ done = true
+
+ -- unget the tail of the line
+ -- in most cases it's empty. This may make us less efficient but
+ -- easier to program
+ in_stream:ungetLine(vim.trim(line:sub(closeSquare + 2)))
end
+ comment_parts[#comment_parts+1] = thisComment
end
- return macro, tail
+
+ local comment = table.concat(comment_parts)
+
+ if comment:sub(1, 1) == '@' then -- it's a long magic comment
+ return '/*' .. comment .. '*/ '
+ end
+
+ -- discard
+ return '/* zz:' .. comment .. '*/ '
end
--- check comment for fn
-local function checkComment4fn(Fn_magic, MagicLines)
- local fn_magic = Fn_magic
- -- TCore_IO_writeln('// checkComment4fn "' .. MagicLines .. '"')
+--- @param line string
+--- @return string
+local function process_function_header(line)
+ local pos_fn = assert(line:find('function'))
+ -- we've got a function
+ local fn = removeCommentFromLine(vim.trim(line:sub(pos_fn + 8)))
+
+ if fn:sub(1, 1) == '(' then
+ -- it's an anonymous function
+ return '// ZZ: '..line
+ end
+ -- fn has a name, so is interesting
- local magicLines = string_split(MagicLines, '\n')
+ -- want to fix for iffy declarations
+ if fn:find('[%({]') then
+ -- we might have a missing close paren
+ if not fn:find('%)') then
+ fn = fn .. ' ___MissingCloseParenHere___)'
+ end
+ end
- local macro, tail
+ -- Big hax
+ if fn:find(':') then
+ fn = fn:gsub(':', '.', 1)
- for _, line in ipairs(magicLines) do
- macro, tail = getMagicDirective(line)
- if macro == 'fn' then
- fn_magic = tail
- -- TCore_IO_writeln('// found fn "' .. fn_magic .. '"')
- --else
- --TCore_IO_writeln('// not found fn "' .. line .. '"')
+ local paren_start = fn:find('(', 1, true)
+ local paren_finish = fn:find(')', 1, true)
+
+ -- Nothing in between the parens
+ local comma --- @type string
+ if paren_finish == paren_start + 1 then
+ comma = ''
+ else
+ comma = ', '
end
+
+ fn = fn:sub(1, paren_start)
+ .. 'self'
+ .. comma
+ .. fn:sub(paren_start + 1)
end
- return fn_magic
+ -- add vanilla function
+ return 'function ' .. fn .. '{}'
end
-local types = { 'integer', 'number', 'string', 'table', 'list', 'boolean', 'function' }
-
-local tagged_types = { 'TSNode', 'LanguageTree' }
+--- @param line string
+--- @param in_stream StreamRead
+--- @param generics table<string,string>>
+--- @return string?
+local function process_line(line, in_stream, generics)
+ if vim.startswith(line, '---') then
+ return process_magic(line:sub(4), generics)
+ end
--- Document these as 'table'
-local alias_types = { 'Range', 'Range4', 'Range6', 'TSMetadata' }
+ if vim.startswith(line, '--'..'[[') then -- it's a long comment
+ return process_block_comment(line:sub(5), in_stream)
+ end
--- Processes the file and writes filtered output to stdout.
-function TLua2DoX_filter.filter(this, AppStamp, Filename)
- local inStream = TStream_Read()
- local outStream = TStream_Write()
- this.outStream = outStream -- save to this obj
-
- if inStream:getContents(Filename) then
- -- output the file
- local line
- local fn_magic -- function name/def from magic comment
-
- outStream:writelnTail('// #######################')
- outStream:writelnTail('// app run:' .. AppStamp)
- outStream:writelnTail('// #######################')
- outStream:writelnTail()
-
- local state = '' -- luacheck: ignore 231 variable is set but never accessed.
- local offset = 0
- local generic = {}
- local l = 0
- while not (inStream:eof()) do
- line = string_trim(inStream:getLine())
- l = l + 1
- if string.sub(line, 1, 2) == '--' then -- it's a comment
- line = line:gsub('^---%s+@', '---@')
- -- Allow people to write style similar to EmmyLua (since they are basically the same)
- -- instead of silently skipping things that start with ---
- if string.sub(line, 3, 3) == '@' then -- it's a magic comment
- offset = 0
- elseif string.sub(line, 1, 4) == '---@' then -- it's a magic comment
- offset = 1
- end
-
- line = line:gsub('@package', '@private')
-
- if vim.startswith(line, '---@cast')
- or vim.startswith(line, '---@diagnostic')
- or vim.startswith(line, '---@overload')
- or vim.startswith(line, '---@meta')
- or vim.startswith(line, '---@type') then
- -- Ignore LSP directives
- outStream:writeln('// gg:"' .. line .. '"')
- elseif string.sub(line, 3, 3) == '@' or string.sub(line, 1, 4) == '---@' then -- it's a magic comment
- state = 'in_magic_comment'
- local magic = string.sub(line, 4 + offset)
-
- local magic_split = string_split(magic, ' ')
- if magic_split[1] == 'param' then
- 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 .. '|nil)%)', 'param %1 %2')
- end
- magic_split = string_split(magic, ' ')
- elseif magic_split[1] == 'return' then
- for _, type in ipairs(types) do
- magic = magic:gsub('^return%s+.*%((' .. type .. ')%)', 'return %1')
- magic = magic:gsub('^return%s+.*%((' .. type .. '|nil)%)', 'return %1')
- end
- -- handle the return of vim.spell.check
- magic = magic:gsub('({.*}%[%])', '`%1`')
- magic_split = string_split(magic, ' ')
- end
-
- if magic_split[1] == 'generic' then
- local generic_name, generic_type = line:match('@generic%s*(%w+)%s*:?%s*(.*)')
- if generic_type == '' then
- generic_type = 'any'
- end
- generic[generic_name] = generic_type
- else
- local type_index = 2
- if magic_split[1] == 'param' then
- type_index = type_index + 1
- end
-
- if magic_split[type_index] then
- -- fix optional parameters
- if magic_split[type_index] and magic_split[2]:find('%?$') then
- if not magic_split[type_index]:find('nil') then
- magic_split[type_index] = magic_split[type_index] .. '|nil'
- end
- magic_split[2] = magic_split[2]:sub(1, -2)
- end
- -- replace generic types
- if magic_split[type_index] then
- for k, v in pairs(generic) do
- magic_split[type_index] = magic_split[type_index]:gsub(k, v)
- end
- end
-
- for _, type in ipairs(tagged_types) do
- magic_split[type_index] =
- magic_split[type_index]:gsub(type, '|%1|')
- end
-
- for _, type in ipairs(alias_types) do
- magic_split[type_index] =
- magic_split[type_index]:gsub('^'..type..'$', 'table')
- end
-
- -- surround some types by ()
- 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]:gsub('^(' .. type .. '):?$', '(%1)')
- end
-
-
- end
-
- magic = table.concat(magic_split, ' ')
-
- if magic_split[1] == 'defgroup' or magic_split[1] == 'addtogroup' then
- -- Can't use '.' in defgroup, so convert to '--'
- magic = magic:gsub('%.', '-dot-')
- end
-
- outStream:writeln('/// @' .. magic)
- fn_magic = checkComment4fn(fn_magic, magic)
- end
- elseif string.sub(line, 3, 3) == '-' then -- it's a nonmagic doc comment
- local comment = string.sub(line, 4)
- outStream:writeln('/// ' .. comment)
- elseif string.sub(line, 3, 4) == '[[' then -- it's a long comment
- line = string.sub(line, 5) -- nibble head
- local comment = ''
- local closeSquare, hitend, thisComment
- while not hitend and (not inStream:eof()) do
- closeSquare = string.find(line, ']]')
- if not closeSquare then -- need to look on another line
- thisComment = line .. '\n'
- line = inStream:getLine()
- else
- thisComment = string.sub(line, 1, closeSquare - 1)
- hitend = true
-
- -- unget the tail of the line
- -- in most cases it's empty. This may make us less efficient but
- -- easier to program
- inStream:ungetLine(string_trim(string.sub(line, closeSquare + 2)))
- end
- comment = comment .. thisComment
- end
- if string.sub(comment, 1, 1) == '@' then -- it's a long magic comment
- outStream:write('/*' .. comment .. '*/ ')
- fn_magic = checkComment4fn(fn_magic, comment)
- else -- discard
- outStream:write('/* zz:' .. comment .. '*/ ')
- fn_magic = nil
- end
- -- TODO(justinmk): Uncomment this if we want "--" lines to continue the
- -- preceding magic ("---", "--@", …) lines.
- -- elseif state == 'in_magic_comment' then -- next line of magic comment
- -- outStream:writeln('/// '.. line:sub(3))
- else -- discard
- outStream:writeln('// zz:"' .. line .. '"')
- fn_magic = nil
- end
- elseif string.find(line, '^function') or string.find(line, '^local%s+function') then
- generic = {}
- state = 'in_function' -- it's a function
- local pos_fn = string.find(line, 'function')
- -- function
- -- ....v...
- if pos_fn then
- -- we've got a function
- local fn = TString_removeCommentFromLine(string_trim(string.sub(line, pos_fn + 8)))
- if fn_magic then
- fn = fn_magic
- end
-
- if string.sub(fn, 1, 1) == '(' then
- -- it's an anonymous function
- outStream:writelnComment(line)
- else
- -- fn has a name, so is interesting
-
- -- want to fix for iffy declarations
- local open_paren = string.find(fn, '[%({]')
- if open_paren then
- -- we might have a missing close paren
- if not string.find(fn, '%)') then
- fn = fn .. ' ___MissingCloseParenHere___)'
- end
- end
-
- -- Big hax
- if string.find(fn, ':') then
- -- TODO: We need to add a first parameter of "SELF" here
- -- local colon_place = string.find(fn, ":")
- -- local name = string.sub(fn, 1, colon_place)
- fn = fn:gsub(':', '.', 1)
- outStream:writeln('/// @param self')
-
- local paren_start = string.find(fn, '(', 1, true)
- local paren_finish = string.find(fn, ')', 1, true)
-
- -- Nothing in between the parens
- local comma
- if paren_finish == paren_start + 1 then
- comma = ''
- else
- comma = ', '
- end
- fn = string.sub(fn, 1, paren_start)
- .. 'self'
- .. comma
- .. string.sub(fn, paren_start + 1)
- end
-
- -- add vanilla function
- outStream:writeln('function ' .. fn .. '{}')
- end
- else
- this:warning(inStream:getLineNo(), 'something weird here')
- end
- fn_magic = nil -- mustn't inadvertently use it again
-
- -- TODO: If we can make this learn how to generate these, that would be helpful.
- -- elseif string.find(line, "^M%['.*'%] = function") then
- -- state = 'in_function' -- it's a function
- -- outStream:writeln("function textDocument/publishDiagnostics(...){}")
-
- -- fn_magic = nil -- mustn't inadvertently use it again
- else
- state = '' -- unknown
- if #line > 0 then -- we don't know what this line means, so just comment it out
- outStream:writeln('// zz: ' .. line)
- else
- outStream:writeln() -- keep this line blank
- end
- end
- end
+ if line:find('^function') or line:find('^local%s+function') then
+ return process_function_header(line)
+ end
- -- output the tail
- outStream:write_tailLines()
- else
- outStream:writeln('!empty file')
+ if #line > 0 then -- we don't know what this line means, so just comment it out
+ return '// zz: ' .. line
end
+
+ return ''
end
--- this application
-local TApp = class()
+-- Processes the file and writes filtered output to stdout.
+---@param filename string
+function Lua2DoxFilter:filter(filename)
+ local in_stream = StreamRead.new(filename)
--- constructor
-function TApp.init(this)
- this.timestamp = os.date('%c %Z', os.time())
- this.name = 'Lua2DoX'
- this.version = '0.2 20130128'
- this.copyright = 'Copyright (c) Simon Dales 2012-13'
-end
+ local generics = {} --- @type table<string,string>
-function TApp.getRunStamp(this)
- return this.name .. ' (' .. this.version .. ') ' .. this.timestamp
-end
+ while not in_stream:eof() do
+ local line = vim.trim(in_stream:getLine())
+
+ local out_line = process_line(line, in_stream, generics)
+
+ if not vim.startswith(line, '---') then
+ generics = {}
+ end
-function TApp.getVersion(this)
- return this.name .. ' (' .. this.version .. ') '
+ if out_line then
+ writeln(out_line)
+ end
+ end
end
-function TApp.getCopyright(this)
- return this.copyright
+--- @class TApp
+--- @field timestamp string|osdate
+--- @field name string
+--- @field version string
+--- @field copyright string
+--- this application
+local TApp = {
+ timestamp = os.date('%c %Z', os.time()),
+ name = 'Lua2DoX',
+ version = '0.2 20130128',
+ copyright = 'Copyright (c) Simon Dales 2012-13'
+}
+
+setmetatable(TApp, { __index = TApp })
+
+function TApp:getRunStamp()
+ return self.name .. ' (' .. self.version .. ') ' .. self.timestamp
end
-local This_app = TApp()
+function TApp:getVersion()
+ return self.name .. ' (' .. self.version .. ') '
+end
--main
if arg[1] == '--help' then
- TCore_IO_writeln(This_app:getVersion())
- TCore_IO_writeln(This_app:getCopyright())
- TCore_IO_writeln([[
+ writeln(TApp:getVersion())
+ writeln(TApp.copyright)
+ writeln([[
run as:
nvim -l scripts/lua2dox.lua <param>
--------------
@@ -586,8 +414,8 @@ if arg[1] == '--help' then
--version : show version/copyright info
--help : this help text]])
elseif arg[1] == '--version' then
- TCore_IO_writeln(This_app:getVersion())
- TCore_IO_writeln(This_app:getCopyright())
+ writeln(TApp:getVersion())
+ writeln(TApp.copyright)
else -- It's a filter.
local filename = arg[1]
@@ -597,18 +425,20 @@ else -- It's a filter.
error(('invalid --outdir: "%s"'):format(tostring(outdir)))
end
vim.fn.mkdir(outdir, 'p')
- _debug_outfile = string.format('%s/%s.c', outdir, vim.fs.basename(filename))
+ debug_outfile = string.format('%s/%s.c', outdir, vim.fs.basename(filename))
end
- local appStamp = This_app:getRunStamp()
- local filter = TLua2DoX_filter()
- filter:filter(appStamp, filename)
+ Lua2DoxFilter:filter(filename)
- if _debug_outfile then
- local f = assert(io.open(_debug_outfile, 'w'))
- f:write(table.concat(_debug_output))
+ -- output the tail
+ writeln('// #######################')
+ writeln('// app run:' .. TApp:getRunStamp())
+ writeln('// #######################')
+ writeln()
+
+ if debug_outfile then
+ local f = assert(io.open(debug_outfile, 'w'))
+ f:write(table.concat(debug_output))
f:close()
end
end
-
---eof