Local classes are recognized by lemmy-help but their methods aren't
I've created this file:
$ cat my_module.lua
---@mod my_module
local M = {}
---@class Foo
M.Foo = {}
function M.Foo:bar()
end
---@class Baz
local Baz = {}
function Baz:qux()
end
return M
The I ran lemmy-help version 0.10.0 on it:
$ lemmy-help my_module.lua
================================================================================
*my_module*
Foo *Foo*
M.Foo() *M.Foo*
Baz *Baz*
vim:tw=78:ts=8:noet:ft=help:norl:
The Foo class was exported and its method bar was recognized by lemmy-help, but qux did not get an entry even though its class Baz did. Is it because Baz is declared local? But these classes' methods should still get into the docs because users can still get them via functions.
The Foo class was exported and its method bar was recognized by lemmy-help
If you look closely bar() is not recognized. It's a limitation. The parser, currently, can only recognize this <ident>[.:]<ident> far, so both M.foo and M.foo:bar will rendered as M.foo. Although, I do want to fix this limitation.
but qux did not get an entry even though its class Baz did. Is it because Baz is declared local? But these classes' methods should still get into the docs because users can still get them via functions.
Yes, local Baz is not included because it's defined as local. But ---@class Baz was included in help bcz lemmy-help doesn't know whether the class is private or not. If you want to exclude it from the help, then use ---@private. And I am pretty sure you can't access Baz from outside of the file.
---@private
---@class Baz
local Baz = {}
If you look closely
bar()is not recognized.
Oh, I think I got confused by M.Foo which was shown in addition to Foo...
Isn't this a problem though? I was kind of hoping lemmy-help parses its annotations in a similar way to Sumneko, where having a ---@class directly above a the declaration of the class in the code associates them with each other...
Well, sumneko's lua parser is designed to work with its LSP server. So, it's natural that it knows more about code than lemmy-help straight & simple top-down parser. And fun part, lemmy-help only parses the code that it needs to be able to generate help doc.
What if we could manually annotate it? Something like:
---@owner Baz
function Baz:qux()
end
Then lemmy-help will know that this function belongs to ---@class Baz, which is on a single global namespace, and it won't have to statically analyze the flow of the Lua code like Sumneko does.
What's the point of it? In your example you are exporting M so only methods and properties attached to M will be documented. Beside that, any ---@class, ---@type, ---@alias will also be included unless ---@private is used.
My actual usecase is this: https://github.com/idanarye/nvim-channelot/blob/main/lua/channelot/init.lua
But that's may be too long to read and discuss, so consider this:
---@mod my_module
local M = {}
---@class Foo
local Foo = {}
function Foo:bar()
end
---@return Foo
function M.make_foo()
end
return M
I'm not exporting Foo here, because I don't want it to be created by the users directly - only by calling make_foo (which, BTW, can be a method of a different class. But let's keep the example simple)
Still - users can get their hand on an instance of Foo and invoke it's :bar() method, and thus I want this method to be documented in the vimdoc that lemmy-help generates.
Also, it could be a workaround to the three-idents-name problem.
Still - users can get their hand on an instance of Foo and invoke it's :bar() method,
How? You are only exporting M and Foo is defined locally. I maybe not an expert on lua, but I am pretty sure that lua doesn't work like that.
local my_module = require('my_module')
local foo_instance = my_module.make_foo()
foo_instance:bar()
local my_module = require('my_module') local foo_instance = my_module.make_foo() foo_instance:bar()
Ahh, Now I understand. I was keep thinking about the same file.
Hmm, it's an interesting use case. I guess we can directly look for exported identifiers, let say ---@class Baz is there and then you have function Baz:foo(). Then we can check whether both have the same identifier i.e., Baz; if yes then document it otherwise discard it. This way we won't be needing the ---@owner tag as you suggested. And obviously this whole thing won't work if ---@private in used. Now the problems:
- The identifier lookup, currently every node it stored in an array and so to make it optimal we need to store exported identifiers in hashmap.
- This will definitely interfere with the
--prefix-*options as they modify the identifier name used for the doc tag.
What was the intended use then? Were classes supposed to be their own files, so each file is either a class or a bundle of free functions?
That's subjective, You could separate classes into their own files. But you can also use ---@class as type for (exported) function params.