Closed winterwolf closed 2 years ago
I don't think that ---@constructor
is standard EmmyLua. I would suggest to default the metatable to the class itself and resolve metamethods like __call
. There would be also another usecase:
local a = vector.new(1, 1)
local b = vector.new(2, 2)
local c = a + b
Currently c
won't be resolved to a vector, but any
, which is quite annoying sometimes.
I will try to analyze meta-methods first. However, the concern is that there may be performance issues. I will decide the next step based on the test results.
Lua's meta-method syntax is too general, and it is difficult to make specific optimizations.
Maybe another solution would be to give information about metamethods in @class
definition. However i don't know if EmmyLua supports that.
However i don't know if EmmyLua supports that.
I have added many new annotations, this is not a problem.
Ah, I thought you didn't want to extend EmmyLua. Is there a list of annotations, that you have added so far (beyond what EmmyLua supports)?
i will create a wiki about it
Of course, it would be perfect if the extension parse metatables, but I think adding a new tag is the easiest and safest solution. Parsing metatables can not only reduce performance, but also cause a lot of new bugs.
i will create a wiki about it
Should I try to help document the basic things on EmmyLua annotations? Even though I don't know the implementation and don't even understand the tests on https://github.com/sumneko/lua-language-server/blob/master/test/definition/luadoc.lua
i will create a wiki about it
Should I try to help document the basic things on EmmyLua annotations? Even though I don't know the implementation and don't even understand the tests on https://github.com/sumneko/lua-language-server/blob/master/test/definition/luadoc.lua
Sure, thank you!
@Ketho Hello. I would like to supplement your article 'EmmyLua Annotations' in the wiki. Just a few extra examples and a descriptions. Since you are the author of this article, I would not like to make changes to the article without your permission. Perhaps it makes sense to create a thread in Discussions where we could discuss the changes in the article beforehand.
Yeah sure, make a thread in Discussions and we can talk 👍
Lua's meta-method syntax is too general, and it is difficult to make specific optimizations.
确实 所以我建议只分析文档注释和对原方法的调用 而不是内部实现 开销应该小得多 Indeed, so I suggest that only analyzing emmydoc and calls to the metamethod rather than internal implementation should be much less expensive
@alias type.method type.__call
I'd like this feature also. In the meantime I found a workaround is to decorate Test as a fun, like so:
---@class Test
---@field [1] number
---@field [2] string
---@type fun(arg1:number, arg2:string):Test
local Test = {}
I had an idea for how to handle deferred constructor arguments. Consider this base Object class:
---@class Object
local Object = {
__name = "Object"
}
--- Creates a new object of type T
---@generic T
---@param self T
---@return T
function Object:new(...)
local object = setmetatable({}, self)
object:init(...)
return object
end
function Object:init(...) end
return Object
Now, when inheriting from a class, the new functions gives, as expected the new object.
---@class SubClass : Object
local SubClass = {}
function SubClass:init(value)
self.value = value
end
-- No argument suggestions here :*(, but the type is correct :)
local object = SubClass:new(10)
However, it would be awesome, to also have argument completion. An option would be to have generic varargs, which infer the arguments of a given function. One would edit the base class as follows:
--- Creates a new object of type T
---@generic T
---@param self T
---@param ... T.init(self, ...) # Notice the pattern matching here. Alternativly I would suggest T:init(...)
---@return T
function Object:new(...)
local object = setmetatable({}, self)
object:init(...)
return object
end
This would allow for argument completion in various scenarios, where the final varargs are determined by the given input. Another example (this hasn't been tested, but I already wrote similar code for Löve2D) would be:
local delayedCalls = { }
--- Registers a draw call which will be called, once the graphics module is enabled
---@generic T : function
---@param func T
---@param ... T(...)
local function register(func, ...)
delayedCalls = { func = func, args = table.pack(...) }
end
local function draw(x, y, width, height)
love.graphics.setColor(1, 1, 1)
love.graphics.rectangle("fill", x, y, width, height)
end
-- No argument suggestions here :*(
register(draw, 10, 10, 100, 100)
function love.draw()
for _, call in ipairs(delayedCalls) do
call.func(unpack(call.args, 1, call.args.n))
end
end
Currently register won't display the arguments used by func
. (And I don't know if ---@generic T : function
is supported), but this way I would think, the language server should have enough information to determine what arguments to expect.
Is this in the realm of the possibles?
Perhaps could pull the solution from here in?
https://github.com/Benjamin-Dobell/IntelliJ-Luanalysis#callable-types
Have supported ---@overload
any eg about @overload
?
wiki have a eg about fun overload. how it work with construct?
@sumneko
any eg about
@overload
? wiki have a eg about fun overload. how it work with construct? @sumneko
---@class A
---@overload fun():A
local mt = {}
Please look at this short example:
It is the simplest emulation of class
Test
with the constructornew
.The problem here is that we don't get any suggestion after we type:
Test(
because your extension don't parse metatables.I want to ask - is it possible to add some tag, like
---@constructor
to be able to mark functionnew
as the constructor for classTest
? Thank you.