lua-language-server
lua-language-server copied to clipboard
feature suggestion: add a notation for callbacks that expects the user to implement
There exist some callbacks in the LÖVE framework, like love.conf, love.draw and some others, and there is currently no way in EmmyLua to note that they are callbacks rather than normal functions, and that a new definition of the same function is an implementation rather than a new overload.
Current Behavior
No way to indicate that this is a callback instead of a normal function definition.
-- In the API definition.
---xxx
---@param t string
function callback(t) end
-- In user code
function callback(t)
t:$
end
There is no completion based on the type of the parameter or ...
Suggested Behavior
Add a new notation for callbacks so when user is defining a new implementation, they can get completion on the parameters. This is especially useful when the parameter is extremely complex (for an example, see love.conf)
-- In the API definition.
---@callback
---xxx
---@param t string
callback = nil
-- In the user code
function callback(t)
t:$
end
I am totally open to the specific syntax, and I think what is really important is to have a syntax for them.
I may support this:
---@type fun(t:iolib)
callback = nil
-- In the user code
function callback(t)
t:$
end
I think that should be good enough.
After considering some more details, I think maybe it would be better if I could add comment to the parameters (and maybe also the returned value?) just as I can add comment to function parameters and returned values as well.
After considering some more details, I think maybe it would be better if I could add comment to the parameters (and maybe also the returned value?) just as I can add comment to function parameters and returned values as well.
I haven't thought of a good way to achieve it. The easy way is:
---@param x string -- comment
---@type fun(x: string)
callback = nil
or I need to implement a complete set of interface specifications like this:
---@callback XXX
---@param x string -- comment
---@type XXX
callback = nil
I think maybe a specific keyword is better so a normal user will not accidentally misuse this feature...
Currently I have implemented this way:
---@param x number
---@param y boolean
Interface = nil
function Interface(x, y)
-- x is number and y is boolean here
end
However, I found that this design has problems, such as:
---@param x number
---@param y boolean
Interface = nil
function Interface(y, x)
-- y is boolean and x is number here
-- this is obviously not semantic
end
So i need to modify some design, one way is:
---@param [1] number
---@param [2] boolean
Interface = nil
function Interface(x, y)
-- x is number and y is boolean here
end
Hey, any way to specify callbacks as params? Saying that I accept as a callback a function that should get this arguments and return this other arguments. Something like
---@param fn function(x:number):string the function to call
If it can have support for generics that will be just awesome
Yes, that is the way to define a function param except it is fun not function. @danielo515
There has been some related talk in another issue:
https://github.com/sumneko/lua-language-server/issues/1456
The general consensus seems to be defining functions for overloading and callbacks is not easy or very usable right now.
So I have a library where you instantiate a class and then can set some functions on it that will be called by my library something like this
local Instance = MyClass:new()
function Instance:method () -- This will be called internally, it has a specific type defined by the library
--Method implementation
end
There is no way for me to type this, if I give MyClass.method a type it will complain that I'm redefining it, if I were to just give the user an @alias I wouldn't be able to define an initial value for this method (something like a default), the library would need to use @as every time it calls the method, and the user would need to specify the type every time they define the method
Same issue as @pablomayobre
If we could define functions / classes as interfaces (that can / need to be implemented) that would be amazing