-
Notifications
You must be signed in to change notification settings - Fork 261
New Lua language server addon #7267
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
Open
speed2CZ
wants to merge
1
commit into
FAForever:develop
Choose a base branch
from
speed2CZ:new-lua-addon
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # fa-lua-addon | ||
|
|
||
| A [lua-language-server](https://github.com/LuaLS/lua-language-server) workspace plugin that | ||
| teaches LuaLS to read Supreme Commander: Forged Alliance's Lua dialect. SupCom actually runs a | ||
| GPG-modified **Lua 5.0** - confirmed by [FAForever/lua-lang](https://github.com/FAForever/lua-lang), | ||
| a buildable reference implementation of it - and that modified dialect bends the language in | ||
| several ways: a preprocessor comment marker, table-size hints, an OOP call convention, an | ||
| implicit module system - none of it valid standard Lua. This addon rewrites each quirk into | ||
| something LuaLS already understands, in the source text, before the real parser ever sees it. | ||
| It's a from-scratch replacement for the outdated | ||
| [FAForever/fa-lua-language-server](https://github.com/FAForever/fa-lua-language-server) fork, | ||
| built as a plugin against mainline LuaLS instead of a fork of it. | ||
|
|
||
| The addon still configures `Lua.runtime.version = 'Lua 5.1'`, not 5.0: LuaLS doesn't support a | ||
| 5.0 runtime at all, and 5.1 is both the earliest version it does support and the closest one to | ||
| SupCom's actual dialect. | ||
|
|
||
| ## Setup | ||
|
|
||
| Point a workspace's `.vscode/settings.json` at `plugin.lua`: | ||
|
|
||
| ```json | ||
| "Lua.runtime.plugin": "../fa-lua-addon/plugin.lua" | ||
| ``` | ||
|
|
||
| `config.lua` is picked up automatically by LuaLS's third-party config system for any matching | ||
| workspace - no separate wiring needed. | ||
|
|
||
| ## How it works | ||
|
|
||
| `plugin.lua` runs a chain of scanners over every file's text and merges their results into one | ||
| diff list for LuaLS to parse instead of the raw source. Each scanner is a single-purpose module; | ||
| its own file header explains the specific problem it solves and why, in more depth than fits | ||
| here. | ||
|
|
||
| | File | Solves | | ||
| |---|---| | ||
| | `hash-comments.lua` | `#` as a comment marker | | ||
| | `table-hints.lua` | `{&N &N}` table-preallocation hints | | ||
| | `class-support.lua` | `Class()`-family OOP sugar | | ||
| | `for-in-pairs.lua` | untyped bare-table `for` loops | | ||
| | `export-env.lua` | FA's implicit module system (bare top-level exports, forward references) | | ||
| | `hook-files.lua` | SupCom mod "hook" file target detection | | ||
| | `config.lua` | workspace settings: non-standard tokens, engine globals, require/path conventions | | ||
| | `plugin.lua` | orchestrates the above, and safely merges their diffs | | ||
|
|
||
| ## Design constraints | ||
|
|
||
| This is a set of heuristic text scanners, not a real parser - each one documents its own known | ||
| false-positive/false-negative edge cases and the reasoning behind them. Where a rewrite carries | ||
| real risk (e.g. `export-env.lua`'s reference rewriting under name shadowing), the trade-off is | ||
| verified against the full FA source tree and documented in that file, not just asserted. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🌐 Web query:
According to the official LuaLS annotation documentation, verify that---@Generic V, R,---@PARAM list V[], and---@PARAM callback fun(key: integer, value: V):R|nilpreserve callback element types.💡 Result:
According to the official LuaLS documentation and community discussions, the behavior regarding the use of
---@generic,---@param list V[], and---@param callback fun(key: integer, value: V):R|nilfor preserving callback element types is limited and known to have inconsistencies [1][2]. While LuaLS supports generic type parameters for classes and functions [3][4], the implementation of generic type propagation through nested callback parameters (such asfun(key: integer, value: V):R|nil) is not explicitly documented as a supported feature for preserving the generic typeVin the way standard static type systems (like TypeScript) would [5][1]. Key findings from official documentation and developer discussions include: 1. Generic Capture Limitations: The---@genericannotation primarily uses backticks (e.g.,---@param argT``) to capture literal string values from arguments to infer class/type names [3][1][4]. This system is focused on return type inference rather than propagating generic constraints through function parameters in complex callback signatures [1][2]. 2. Callback Inference: LuaLS has ongoing work regarding function parameter inference. While recent updates (e.g.,Lua.type.inferParamType) improve how local functions used as call arguments are inferred, there is no official guarantee or established mechanism in the annotation syntax that ensures a generic `V` defined in one parameter will correctly bind to the `value: V` parameter within a `callback` function parameter [6]. 3. Community/Maintenance Status: Developers have noted that using generics in anything other than `@return` tags often results in incomplete type narrowing [2]. The documentation explicitly states that generics are still a "work in progress" [3][4]. If you are attempting to use this pattern, you may encounter scenarios where the type `V` is not correctly narrowed or identified within the callback signature, as the language server's current generic engine does not consistently support deep propagation through function types [1][2].Citations:
🤖 get_repo_knowledge executed:
get_repo_knowledge FAForever/fa /tmp/coderabbit-repo-knowledge/faforever-fa-d6ccff43/conventions /tmp/coderabbit-repo-knowledge/faforever-fa-d6ccff43/learningsLength of output: 12164
🏁 Script executed:
Repository: FAForever/fa
Length of output: 7606
🏁 Script executed:
Repository: FAForever/fa
Length of output: 7566
🏁 Script executed:
Repository: FAForever/fa
Length of output: 658
🌐 Web query:
site:luals.github.io/wiki/annotations LuaLS generic function parameter callback V[]💡 Result:
In LuaLS, you can define a generic function parameter that utilizes a callback with an array of a generic type by using the
@genericannotation combined with a function type definition. To define a generic type T and an array of that type (T[]), you use the@genericannotation to declare the type placeholder and then reference it in your parameters or return types [1][2]. For callbacks, LuaLS supports inline generic function type definitions using the fun syntax [2]. Here is an example of how to combine these concepts: ---@Generic T ---@PARAM callback fun(items: T[]) ---@PARAM data T[] local function process(callback, data) callback(data) end -- Usage process(function(items) -- items is inferred as string[] print(items[1]) end, {"a", "b", "c"}) In this example: 1. The@genericT annotation creates a placeholder for a type [1][2]. 2. The callback parameter is defined using the fun(items: T[]) syntax, where T[] specifies an array containing elements of the generic type T [1][2]. 3. When the function is called, LuaLS infers the specific type (e.g., string) based on the provided arguments, allowing it to correctly type-check the callback and the data array [1][2].Citations:
Preserve the list element type in
table.foreachi.list: anyerases the element type beforecallbackreceives it, so LuaLS cannot provide type diagnostics or completion forvalue. Use separate generics for the list element and callback result:🤖 Prompt for AI Agents