Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local classes are recognized by lemmy-help but their methods aren't #66

Open
idanarye opened this issue Dec 1, 2022 · 12 comments
Open
Labels
help wanted Extra attention is needed

Comments

@idanarye
Copy link

idanarye commented Dec 1, 2022

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.

@numToStr
Copy link
Owner

numToStr commented Dec 5, 2022

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 = {}

@idanarye
Copy link
Author

idanarye commented Dec 5, 2022

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...

@numToStr
Copy link
Owner

numToStr commented Dec 5, 2022

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.

@idanarye
Copy link
Author

idanarye commented Dec 5, 2022

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.

@numToStr
Copy link
Owner

numToStr commented Dec 5, 2022

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.

@idanarye
Copy link
Author

idanarye commented Dec 5, 2022

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.

@idanarye
Copy link
Author

idanarye commented Dec 5, 2022

Also, it could be a workaround to the three-idents-name problem.

@numToStr
Copy link
Owner

numToStr commented Dec 6, 2022

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.

@idanarye
Copy link
Author

idanarye commented Dec 6, 2022

local my_module = require('my_module')
local foo_instance = my_module.make_foo()
foo_instance:bar()

@numToStr
Copy link
Owner

numToStr commented Dec 6, 2022

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.

@idanarye
Copy link
Author

idanarye commented Dec 6, 2022

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?

@numToStr
Copy link
Owner

numToStr commented Dec 6, 2022

That's subjective, You could separate classes into their own files. But you can also use ---@class as type for (exported) function params.

@numToStr numToStr added the help wanted Extra attention is needed label Dec 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants