LuaLS / LuaLS/lua-language-server
Function Overloading Overhaul (`@function` annotation)
Nobody has claimed this yet.
- Dominant language
- Lua
- Stars
- 4.4k
- Forks
- 442
- PR merge metrics
- No merged PRs in 30d
Description
# The Problem
I think function overloading needs some changes in order for it to really function in the way that most people would find useful. This is especially problematic with event systems, as I and [others](https://github.com/sumneko/lua-language-server/discussions/1452) have encountered.
# Example
Currently, let's say I have the following function that I want to provide an overload for:
```lua
function Shape:listen(event, callback) end
```
## Using `@overload`
The first logical option is to use [`@overload`](https://github.com/sumneko/lua-language-server/wiki/Annotations#overload):
```lua
---@class Shape
local Shape = {}
---Subscribe to an event on this shape
---@param event "Destroy"
---@param callback fun(self: Shape)
---@overload fun(event: "Repair", callback: fun(self: Shape, amount: number))
function Shape:listen(event, callback) end
```
But there is a problem, when using methods (`:`), the first parameter only gets completions for the first `@param` and ignores the `@overload` entirely.

Ok, so for testing, let's replace the method (`:`) with a static function (`.`):
```lua
---@class Shape
local Shape = {}
---Subscribe to an event on this shape
---@param event "Destroy"
---@param callback fun(self: Shape)
---@overload fun(event: "Repair", callback: fun(self: Shape, amount: number))
function Shape.listen(event, callback) end
```
This still isn't great, we are still offered both callbacks even though the info we have entered only matches the `@overload`. At least the first parameter was completed this time.

## Multiple Definitions
So then maybe we try defining multiple functions where each `event` param has the type set to the event name we are looking for:
```lua
---@class Shape
local Shape = {}
---Subscribe to an event on this shape
---@param event "Destroy"
---@param callback fun(self: Shape)
function Shape:listen(event, callback) end
---Subscribe to an event on this shape
---@param event "Repair"
---@param callback fun(self: Shape, amount: number)
function Shape:listen(event, callback) end
```
Now, even as methods (`:`) we are receiving correct completions for the first parameter... nice! However, we are still receiving two completions for the callback - there is no narrowing happening. The completion also shows the `event` as `"Destroy"`, which is incorrect for our second definition as we have only allowed `"Repair"`.

At least when defining the function twice, we are able to write a separate description for each of them as well as their `@param`s and `@return`s. However, we receive a warning saying that we have a duplicate field.
# Proposed Solution
See @flrgh['s idea](https://github.com/LuaLS/lua-language-server/issues/1456#issuecomment-1210963693) to add a `@function` annotation to add more in-depth support for defining functions overall.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the issue's @overload and multiple-definition examples, then read the linked @flrgh proposal for the @function annotation. The work is done when function definitions support the proposed annotation with correct event- and callback-specific completions, without the duplicate-definition warning described here.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100