feat(docs): render class dot members as module functions

AI-assisted: Codex
This commit is contained in:
Yi Ming
2026-04-15 22:12:18 +08:00
parent 481e70550c
commit 37aa66c1a2
6 changed files with 200 additions and 113 deletions

View File

@@ -4287,31 +4287,19 @@ by |vim.Pos| objects.
as format conversions.
Fields: ~
• {row} (`integer`) 0-based byte index.
• {col} (`integer`) 0-based byte index.
• {buf} (`integer`) buffer handle.
• {to_lsp} (`fun(pos: vim.Pos, position_encoding: lsp.PositionEncodingKind)`)
See |Pos:to_lsp()|.
• {lsp} (`fun(buf: integer, pos: lsp.Position, position_encoding: lsp.PositionEncodingKind)`)
See |Pos:lsp()|.
• {to_cursor} (`fun(pos: vim.Pos): integer, integer`) See
|Pos:to_cursor()|.
• {cursor} (`fun(buf: integer, pos: [integer, integer])`) See
|Pos:cursor()|.
• {to_extmark} (`fun(pos: vim.Pos): integer, integer`) See
|Pos:to_extmark()|.
• {extmark} (`fun(buf: integer, row: integer, col: integer)`) See
|Pos:extmark()|.
• {row} (`integer`) 0-based byte index.
• {col} (`integer`) 0-based byte index.
• {buf} (`integer`) buffer handle.
Pos:cursor({buf}, {pos}) *Pos:cursor()*
cursor({buf}, {pos}) *vim.pos.cursor()*
Creates a new |vim.Pos| from cursor position (see |api-indexing|).
Parameters: ~
• {buf} (`integer`)
• {pos} (`[integer, integer]`)
Pos:extmark({buf}, {row}, {col}) *Pos:extmark()*
extmark({buf}, {row}, {col}) *vim.pos.extmark()*
Creates a new |vim.Pos| from extmark position (see |api-indexing|).
Parameters: ~
@@ -4319,7 +4307,7 @@ Pos:extmark({buf}, {row}, {col}) *Pos:extmark()*
• {row} (`integer`)
• {col} (`integer`)
Pos:lsp({buf}, {pos}, {position_encoding}) *Pos:lsp()*
lsp({buf}, {pos}, {position_encoding}) *vim.pos.lsp()*
Creates a new |vim.Pos| from `lsp.Position`.
Example: >lua
@@ -4337,7 +4325,7 @@ Pos:lsp({buf}, {pos}, {position_encoding}) *Pos:lsp()*
• {pos} (`lsp.Position`)
• {position_encoding} (`lsp.PositionEncodingKind`)
Pos:to_cursor({pos}) *Pos:to_cursor()*
to_cursor({pos}) *vim.pos.to_cursor()*
Converts |vim.Pos| to cursor position (see |api-indexing|).
Parameters: ~
@@ -4347,7 +4335,7 @@ Pos:to_cursor({pos}) *Pos:to_cursor()*
(`integer`)
(`integer`)
Pos:to_extmark({pos}) *Pos:to_extmark()*
to_extmark({pos}) *vim.pos.to_extmark()*
Converts |vim.Pos| to extmark position (see |api-indexing|).
Parameters: ~
@@ -4357,7 +4345,7 @@ Pos:to_extmark({pos}) *Pos:to_extmark()*
(`integer`)
(`integer`)
Pos:to_lsp({pos}, {position_encoding}) *Pos:to_lsp()*
to_lsp({pos}, {position_encoding}) *vim.pos.to_lsp()*
Converts |vim.Pos| to `lsp.Position`.
Example: >lua
@@ -4413,30 +4401,14 @@ Provides operations to compare, calculate, and convert ranges represented by
<
Fields: ~
• {start_row} (`integer`) 0-based byte index.
• {start_col} (`integer`) 0-based byte index.
• {end_row} (`integer`) 0-based byte index.
• {end_col} (`integer`) 0-based byte index.
• {buf} (`integer`) Optional buffer handle.
• {is_empty} (`fun(self: vim.Range): boolean`) See
|Range:is_empty()|.
• {has} (`fun(outer: vim.Range, inner: vim.Range|vim.Pos): boolean`)
See |Range:has()|.
• {intersect} (`fun(r1: vim.Range, r2: vim.Range): vim.Range?`) See
|Range:intersect()|.
• {to_lsp} (`fun(range: vim.Range, position_encoding: lsp.PositionEncodingKind): lsp.Range`)
See |Range:to_lsp()|.
• {lsp} (`fun(buf: integer, range: lsp.Range, position_encoding: lsp.PositionEncodingKind)`)
See |Range:lsp()|.
• {to_extmark} (`fun(range: vim.Range)`) See |Range:to_extmark()|.
• {extmark} (`fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer)`)
See |Range:extmark()|.
• {to_cursor} (`fun(range: vim.Range)`) See |Range:to_cursor()|.
• {cursor} (`fun(buf: integer, start_pos: [integer, integer], end_pos: [integer, integer])`)
See |Range:cursor()|.
• {start_row} (`integer`) 0-based byte index.
• {start_col} (`integer`) 0-based byte index.
• {end_row} (`integer`) 0-based byte index.
• {end_col} (`integer`) 0-based byte index.
• {buf} (`integer`) Optional buffer handle.
Range:cursor({buf}, {start_pos}, {end_pos}) *Range:cursor()*
cursor({buf}, {start_pos}, {end_pos}) *vim.range.cursor()*
Creates a new |vim.Range| from mark-like range (see |api-indexing|).
Example: >lua
@@ -4453,8 +4425,8 @@ Range:cursor({buf}, {start_pos}, {end_pos}) *Range:cursor()*
• {start_pos} (`[integer, integer]`)
• {end_pos} (`[integer, integer]`)
*Range:extmark()*
Range:extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col})
*vim.range.extmark()*
extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col})
Creates a new |vim.Range| from extmark range (see |api-indexing|).
Example: >lua
@@ -4470,7 +4442,7 @@ Range:extmark({buf}, {start_row}, {start_col}, {end_row}, {end_col})
• {end_row} (`integer`)
• {end_col} (`integer`)
Range:has({outer}, {inner}) *Range:has()*
has({outer}, {inner}) *vim.range.has()*
Checks whether {outer} range contains {inner} range or position.
Parameters: ~
@@ -4481,7 +4453,7 @@ Range:has({outer}, {inner}) *Range:has()*
(`boolean`) `true` if {outer} range fully contains {inner} range or
position.
Range:intersect({r1}, {r2}) *Range:intersect()*
intersect({r1}, {r2}) *vim.range.intersect()*
Computes the common range shared by the given ranges.
Parameters: ~
@@ -4492,13 +4464,16 @@ Range:intersect({r1}, {r2}) *Range:intersect()*
(`vim.Range?`) range that is present inside both `r1` and `r2`. `nil`
if such range does not exist. See |vim.Range|.
Range:is_empty() *Range:is_empty()*
is_empty({range}) *vim.range.is_empty()*
Checks whether the given range is empty; i.e., start >= end.
Return: ~
(`boolean`) `true` if the given range is empty
Parameters: ~
• {range} (`vim.Range`) See |vim.Range|.
Range:lsp({buf}, {range}, {position_encoding}) *Range:lsp()*
Return: ~
(`boolean`) `true` if the given range is empty.
lsp({buf}, {range}, {position_encoding}) *vim.range.lsp()*
Creates a new |vim.Range| from `lsp.Range`.
Example: >lua
@@ -4516,7 +4491,7 @@ Range:lsp({buf}, {range}, {position_encoding}) *Range:lsp()*
• {range} (`lsp.Range`)
• {position_encoding} (`lsp.PositionEncodingKind`)
Range:to_cursor({range}) *Range:to_cursor()*
to_cursor({range}) *vim.range.to_cursor()*
Converts |vim.Range| to mark-like range (see |api-indexing|).
Example: >lua
@@ -4530,7 +4505,7 @@ Range:to_cursor({range}) *Range:to_cursor()*
Parameters: ~
• {range} (`vim.Range`) See |vim.Range|.
Range:to_extmark({range}) *Range:to_extmark()*
to_extmark({range}) *vim.range.to_extmark()*
Converts |vim.Range| to extmark range (see |api-indexing|).
Example: >lua
@@ -4544,7 +4519,7 @@ Range:to_extmark({range}) *Range:to_extmark()*
Parameters: ~
• {range} (`vim.Range`) See |vim.Range|.
Range:to_lsp({range}, {position_encoding}) *Range:to_lsp()*
to_lsp({range}, {position_encoding}) *vim.range.to_lsp()*
Converts |vim.Range| to `lsp.Range`.
Example: >lua

View File

@@ -39,12 +39,12 @@ local validate = vim.validate
---@field private [1] integer underlying representation of row
---@field private [2] integer underlying representation of col
---@field private [3] integer underlying representation of buf
local Pos = {}
local M = {}
---@private
---@param pos vim.Pos
---@param key any
function Pos.__index(pos, key)
function M.__index(pos, key)
if key == 'row' then
return pos[1]
elseif key == 'col' then
@@ -53,14 +53,14 @@ function Pos.__index(pos, key)
return pos[3]
end
return Pos[key]
return M[key]
end
---@package
---@param buf integer
---@param row integer
---@param col integer
function Pos.new(buf, row, col)
function M.new(buf, row, col)
validate('buf', buf, 'number')
validate('row', row, 'number')
validate('col', col, 'number')
@@ -70,7 +70,7 @@ function Pos.new(buf, row, col)
row,
col,
buf,
}, Pos)
}, M)
return self
end
@@ -98,17 +98,17 @@ local function cmp_pos(p1, p2)
end
---@private
function Pos.__lt(...)
function M.__lt(...)
return cmp_pos(...) == -1
end
---@private
function Pos.__le(...)
function M.__le(...)
return cmp_pos(...) ~= 1
end
---@private
function Pos.__eq(...)
function M.__eq(...)
return cmp_pos(...) == 0
end
@@ -131,7 +131,7 @@ end
--- ```
---@param pos vim.Pos
---@param position_encoding lsp.PositionEncodingKind
function Pos.to_lsp(pos, position_encoding)
function M.to_lsp(pos, position_encoding)
validate('pos', pos, 'table')
validate('position_encoding', position_encoding, 'string')
@@ -161,7 +161,7 @@ end
---@param buf integer
---@param pos lsp.Position
---@param position_encoding lsp.PositionEncodingKind
function Pos.lsp(buf, pos, position_encoding)
function M.lsp(buf, pos, position_encoding)
validate('buf', buf, 'number')
validate('pos', pos, 'table')
validate('position_encoding', position_encoding, 'string')
@@ -175,27 +175,27 @@ function Pos.lsp(buf, pos, position_encoding)
col = vim.str_byteindex(get_line(buf, row), position_encoding, col, false)
end
return Pos.new(buf, row, col)
return M.new(buf, row, col)
end
--- Converts |vim.Pos| to cursor position (see |api-indexing|).
---@param pos vim.Pos
---@return integer, integer
function Pos.to_cursor(pos)
function M.to_cursor(pos)
return pos.row + 1, pos.col
end
--- Creates a new |vim.Pos| from cursor position (see |api-indexing|).
---@param buf integer
---@param pos [integer, integer]
function Pos.cursor(buf, pos)
return Pos.new(buf, pos[1] - 1, pos[2])
function M.cursor(buf, pos)
return M.new(buf, pos[1] - 1, pos[2])
end
--- Converts |vim.Pos| to extmark position (see |api-indexing|).
---@param pos vim.Pos
---@return integer, integer
function Pos.to_extmark(pos)
function M.to_extmark(pos)
local line_count = api.nvim_buf_line_count(pos.buf)
local row = pos.row
@@ -212,16 +212,16 @@ end
---@param buf integer
---@param row integer
---@param col integer
function Pos.extmark(buf, row, col)
return Pos.new(buf, row, col)
function M.extmark(buf, row, col)
return M.new(buf, row, col)
end
-- Overload `Range.new` to allow calling this module as a function.
setmetatable(Pos, {
setmetatable(M, {
__call = function(_, ...)
return Pos.new(...)
return M.new(...)
end,
})
---@cast Pos +fun(buf: integer, row: integer, col: integer): vim.Pos
---@cast M +fun(buf: integer, row: integer, col: integer): vim.Pos
return Pos
return M

View File

@@ -47,12 +47,12 @@ local api = vim.api
---@field private [3] integer underlying representation of end_row
---@field private [4] integer underlying representation of end_col
---@field private [5] integer underlying representation of buf
local Range = {}
local M = {}
---@private
---@param pos vim.Range
---@param key any
function Range.__index(pos, key)
function M.__index(pos, key)
if key == 'start_row' then
return pos[1]
elseif key == 'start_col' then
@@ -65,13 +65,13 @@ function Range.__index(pos, key)
return pos[5]
end
return Range[key]
return M[key]
end
---@package
---@overload fun(start: vim.Pos, end_: vim.Pos): vim.Range
---@overload fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer): vim.Range
function Range.new(...)
function M.new(...)
---@type integer, integer, integer, integer, integer|nil
local start_row, start_col, end_row, end_col, buf
@@ -101,7 +101,7 @@ function Range.new(...)
end_row,
end_col,
buf,
}, Range)
}, M)
return self
end
@@ -155,7 +155,7 @@ end
---@private
---@param r1 vim.Range
---@param r2 vim.Range
function Range.__lt(r1, r2)
function M.__lt(r1, r2)
local r1_inclusive_end_row, r1_inclusive_end_col =
to_inclusive_pos(r1.buf, r1.end_row, r1.end_col)
return cmp_pos(r1_inclusive_end_row, r1_inclusive_end_col, r2.start_row, r2.start_col) == -1
@@ -164,7 +164,7 @@ end
---@private
---@param r1 vim.Range
---@param r2 vim.Range
function Range.__le(r1, r2)
function M.__le(r1, r2)
local r1_inclusive_end_row, r1_inclusive_end_col =
to_inclusive_pos(r1.buf, r1.end_row, r1.end_col)
return cmp_pos(r1_inclusive_end_row, r1_inclusive_end_col, r2.start_row, r2.start_col) ~= 1
@@ -173,19 +173,20 @@ end
---@private
---@param r1 vim.Range
---@param r2 vim.Range
function Range.__eq(r1, r2)
function M.__eq(r1, r2)
return cmp_pos(r1.start_row, r1.start_col, r2.start_row, r2.start_col) == 0
and cmp_pos(r1.end_row, r1.end_col, r2.end_row, r2.end_col) == 0
end
--- Checks whether the given range is empty; i.e., start >= end.
---
---@return boolean `true` if the given range is empty
function Range:is_empty()
---@param range vim.Range
---@return boolean `true` if the given range is empty.
function M.is_empty(range)
local inclusive_end_row, inclusive_end_col =
to_inclusive_pos(self.buf, self.end_row, self.end_col)
to_inclusive_pos(range.buf, range.end_row, range.end_col)
return cmp_pos(self.start_row, self.start_col, inclusive_end_row, inclusive_end_col) ~= -1
return cmp_pos(range.start_row, range.start_col, inclusive_end_row, inclusive_end_col) ~= -1
end
--- Checks whether {outer} range contains {inner} range or position.
@@ -193,7 +194,7 @@ end
---@param outer vim.Range
---@param inner vim.Range|vim.Pos
---@return boolean `true` if {outer} range fully contains {inner} range or position.
function Range.has(outer, inner)
function M.has(outer, inner)
if getmetatable(inner) == vim.pos then
---@cast inner -vim.Range
return cmp_pos(outer.start_row, outer.start_col, inner.row, inner.col) ~= 1
@@ -226,7 +227,7 @@ end
---@param r2 vim.Range Second range to intersect
---@return vim.Range? range that is present inside both `r1` and `r2`.
--- `nil` if such range does not exist.
function Range.intersect(r1, r2)
function M.intersect(r1, r2)
if r1.buf ~= r2.buf then
return nil
end
@@ -245,7 +246,7 @@ function Range.intersect(r1, r2)
local rs = cmp_pos(r1.start_row, r1.start_col, r2.start_row, r2.start_col) ~= 1 and r2 or r1
local re = cmp_pos(r1.end_row, r1.end_col, r2.end_row, r2.end_col) ~= -1 and r2 or r1
return Range.new(r1.buf, rs.start_row, rs.start_col, re.end_row, re.end_col)
return M.new(r1.buf, rs.start_row, rs.start_col, re.end_row, re.end_col)
end
--- Converts |vim.Range| to `lsp.Range`.
@@ -261,7 +262,7 @@ end
---@param range vim.Range
---@param position_encoding lsp.PositionEncodingKind
---@return lsp.Range
function Range.to_lsp(range, position_encoding)
function M.to_lsp(range, position_encoding)
validate('range', range, 'table')
validate('position_encoding', position_encoding, 'string', true)
@@ -287,7 +288,7 @@ end
---@param buf integer
---@param range lsp.Range
---@param position_encoding lsp.PositionEncodingKind
function Range.lsp(buf, range, position_encoding)
function M.lsp(buf, range, position_encoding)
validate('buf', buf, 'number')
validate('range', range, 'table')
validate('position_encoding', position_encoding, 'string')
@@ -297,7 +298,7 @@ function Range.lsp(buf, range, position_encoding)
local start = vim.pos.lsp(buf, range['start'], position_encoding)
local end_ = vim.pos.lsp(buf, range['end'], position_encoding)
return Range.new(start, end_)
return M.new(start, end_)
end
--- Converts |vim.Range| to extmark range (see |api-indexing|).
@@ -311,7 +312,7 @@ end
--- local extmark_range = range:to_extmark()
--- ```
---@param range vim.Range
function Range.to_extmark(range)
function M.to_extmark(range)
validate('range', range, 'table')
local srow, scol = vim.pos(range.buf, range.start_row, range.start_col):to_extmark()
@@ -332,7 +333,7 @@ end
---@param start_col integer
---@param end_row integer
---@param end_col integer
function Range.extmark(buf, start_row, start_col, end_row, end_col)
function M.extmark(buf, start_row, start_col, end_row, end_col)
validate('buf', buf, 'number')
validate('start_row', start_row, 'number')
validate('start_col', start_col, 'number')
@@ -342,7 +343,7 @@ function Range.extmark(buf, start_row, start_col, end_row, end_col)
local start = vim.pos.extmark(buf, start_row, start_col)
local end_ = vim.pos.extmark(buf, end_row, end_col)
return Range.new(start, end_)
return M.new(start, end_)
end
--- Converts |vim.Range| to mark-like range (see |api-indexing|).
@@ -356,7 +357,7 @@ end
--- local cursor_range = range:to_cursor()
--- ```
---@param range vim.Range
function Range.to_cursor(range)
function M.to_cursor(range)
validate('range', range, 'table')
local srow, scol = vim.pos(range.buf, range.start_row, range.start_col):to_cursor()
@@ -378,7 +379,7 @@ end
---@param buf integer
---@param start_pos [integer, integer]
---@param end_pos [integer, integer]
function Range.cursor(buf, start_pos, end_pos)
function M.cursor(buf, start_pos, end_pos)
validate('buf', buf, 'number')
validate('range', start_pos, 'table')
validate('range', end_pos, 'table')
@@ -386,16 +387,16 @@ function Range.cursor(buf, start_pos, end_pos)
local start = vim.pos.cursor(buf, start_pos)
local end_ = vim.pos.cursor(buf, end_pos)
return Range.new(start, end_)
return M.new(start, end_)
end
-- Overload `Range.new` to allow calling this module as a function.
setmetatable(Range, {
setmetatable(M, {
__call = function(_, ...)
return Range.new(...)
return M.new(...)
end,
})
---@cast Range +fun(start: vim.Pos, end_: vim.Pos): vim.Range
---@cast Range +fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer): vim.Range
---@cast M +fun(start: vim.Pos, end_: vim.Pos): vim.Range
---@cast M +fun(buf: integer, start_row: integer, start_col: integer, end_row: integer, end_col: integer): vim.Range
return Range
return M

View File

@@ -67,6 +67,17 @@ local function contains(t, xs)
return vim.tbl_contains(xs, t)
end
--- True if the `.` class member should render like a module function.
--- @param fun nvim.gen_vimdoc.HelptagTarget
--- @return boolean
local function is_module_fun(fun)
return fun.classvar ~= nil
and fun.member_sep == '.'
and fun.modvar ~= nil
and fun.module ~= nil
and fun.classvar == fun.modvar
end
--- @type {level:integer, prerelease:boolean}?
local nvim_api_info_
@@ -99,6 +110,9 @@ end
--- @return string
local function fn_helptag_fmt_common(fun)
local fn_sfx = fun.table and '' or '()'
if is_module_fun(fun) then
return fmt('%s.%s%s', fun.module, fun.name, fn_sfx)
end
if fun.classvar then
return fmt('%s:%s%s', fun.classvar, fun.name, fn_sfx)
end
@@ -663,8 +677,9 @@ end
--- @param class nvim.luacats.parser.class
--- @param classes table<string,nvim.luacats.parser.class>
--- @param hidden_fields? table<string,table<string,true>>
--- @param cfg nvim.gen_vimdoc.Config
local function render_class(class, classes, cfg)
local function render_class(class, classes, hidden_fields, cfg)
if class.access or class.nodoc or class.inlinedoc then
return
end
@@ -683,7 +698,15 @@ local function render_class(class, classes, cfg)
table.insert(ret, md_to_vimdoc(class.desc, INDENTATION, INDENTATION, TEXT_WIDTH))
end
local fields_txt = render_fields_or_params(class.fields, nil, classes, cfg)
local class_hidden = hidden_fields and hidden_fields[class.name]
local fields = class.fields
if class_hidden then
fields = vim.tbl_filter(function(field)
return not class_hidden[field.name]
end, fields)
end
local fields_txt = render_fields_or_params(fields, nil, classes, cfg)
if not fields_txt:match('^%s*$') then
table.insert(ret, '\n Fields: ~\n')
table.insert(ret, fields_txt)
@@ -694,12 +717,22 @@ local function render_class(class, classes, cfg)
end
--- @param classes table<string,nvim.luacats.parser.class>
--- @param funs nvim.luacats.parser.fun[]
--- @param cfg nvim.gen_vimdoc.Config
local function render_classes(classes, cfg)
local function render_classes(classes, funs, cfg)
local ret = {} --- @type string[]
-- Hide `.` members of returned class-modules from class Fields;
-- they render as module functions.
local hidden_fields = {} --- @type table<string,table<string,true>>
for _, fun in ipairs(funs) do
if is_module_fun(fun) and fun.class then
hidden_fields[fun.class] = hidden_fields[fun.class] or {}
hidden_fields[fun.class][fun.name] = true
end
end
for _, class in vim.spairs(classes) do
ret[#ret + 1] = render_class(class, classes, cfg)
ret[#ret + 1] = render_class(class, classes, hidden_fields, cfg)
end
return table.concat(ret)
@@ -718,7 +751,7 @@ local function render_fun_header(fun, cfg)
end
local nm = fun.name
if fun.classvar then
if fun.classvar and not is_module_fun(fun) then
nm = fmt('%s:%s', fun.classvar, nm)
end
if nm == 'vim.bo' then
@@ -735,8 +768,12 @@ local function render_fun_header(fun, cfg)
if #proto + #tag > TEXT_WIDTH - 8 then
table.insert(ret, fmt('%78s\n', tag))
local name, pargs = proto:match('([^(]+%()(.*)')
table.insert(ret, name)
table.insert(ret, wrap(pargs, 0, #name, TEXT_WIDTH))
if name then
table.insert(ret, name)
table.insert(ret, wrap(pargs, 0, #name, TEXT_WIDTH))
else
table.insert(ret, proto)
end
else
local pad = TEXT_WIDTH - #proto - #tag
table.insert(ret, proto .. string.rep(' ', pad) .. tag)
@@ -1115,7 +1152,7 @@ local function gen_target(cfg)
cfg,
briefs,
render_funs(funs, all_classes, cfg),
render_classes(classes, cfg)
render_classes(classes, funs, cfg)
)
end

View File

@@ -30,6 +30,7 @@ local luacats_grammar = require('gen.luacats_grammar')
--- @field module? string
--- @field modvar? string
--- @field classvar? string
--- @field member_sep? '.'|':'
--- @field deprecated? true
--- @field async? true
--- @field since? string
@@ -324,6 +325,7 @@ local function process_lua_line(line, state, classes, classvars, has_indent)
cur_obj.name = fun_or_meth_nm
cur_obj.class = class
cur_obj.classvar = parent_tbl
cur_obj.member_sep = sep
-- Add self param to methods
if sep == ':' then
cur_obj.params = cur_obj.params or {}
@@ -333,7 +335,6 @@ local function process_lua_line(line, state, classes, classvars, has_indent)
})
end
-- Add method as the field to the class
table.insert(classes[class].fields, fun2field(cur_obj))
return
end

View File

@@ -1,5 +1,6 @@
local t = require('test.testutil')
local dedent = t.dedent
local eq = t.eq
local parser = require('gen.luacats_parser')
@@ -104,4 +105,76 @@ describe('luacats parser', function()
]],
exp
)
it('tracks class member declaration style', function()
local classes, funs = parser.parse_str(
dedent([[ --- @class vim.MyClass
local MyClass = {}
--- Dot member.
--- @param obj vim.MyClass
function MyClass.dot_member(obj)
end
--- Colon member.
function MyClass:colon_member()
end
return MyClass
]]),
'runtime/lua/vim/myclass.lua'
)
eq('vim.MyClass', classes['vim.MyClass'].name)
eq({
classvar = 'MyClass',
desc = 'Dot member.',
kind = 'field',
name = 'dot_member',
type = 'fun(obj: vim.MyClass)',
}, classes['vim.MyClass'].fields[1])
eq({
classvar = 'MyClass',
desc = 'Colon member.',
kind = 'field',
name = 'colon_member',
type = 'fun(self: vim.MyClass)',
}, classes['vim.MyClass'].fields[2])
eq('.', funs[1].member_sep)
eq('MyClass', funs[1].classvar)
eq('MyClass', funs[1].modvar)
eq('obj', funs[1].params[1].name)
eq(':', funs[2].member_sep)
eq('self', funs[2].params[1].name)
eq('vim.MyClass', funs[2].params[1].type)
end)
it('keeps non-returned dot members as class fields', function()
local classes = parser.parse_str(
dedent([[ --- @class vim.Helper
local Helper = {}
--- @class vim.Module
local M = {}
--- Helper field.
--- @param helper vim.Helper
function Helper.field(helper)
end
return M
]]),
'runtime/lua/vim/module.lua'
)
eq({
classvar = 'Helper',
desc = 'Helper field.',
kind = 'field',
name = 'field',
type = 'fun(helper: vim.Helper)',
}, classes['vim.Helper'].fields[1])
end)
end)