Feature Request: Typestate / Self-Type Refinement for Method Calls
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Anfängerfreundlichkeit
- 45/100
Rechercherichtung
Das Issue nennt keine Implementierungsdateien oder Tests. Beginne damit zu prüfen, wie LuaLS derzeit explizite ---@cast-Anweisungen und Methodenaufrufe behandelt, und bewerte anschließend den vorgeschlagenen Umfang der Verfeinerung: direkte Aufrufe, der aktuelle Gültigkeitsbereich und explizite Annotationen. Als abgeschlossen gilt die Arbeit, wenn ein abgestimmtes Annotationsdesign vorliegt und flusssensitive Fähigkeitsverfeinerung, Autovervollständigung und Diagnosen ohne einen manuellen Cast funktionieren.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Problem
Lua is a highly dynamic language, and many real-world Lua frameworks mutate object capabilities at runtime.
This pattern is especially common in:
- game engines
- UI frameworks
- ECS architectures
- builder APIs
- runtime mixin systems
- userdata bindings from native engines
Currently, LuaLS/LuaCats cannot properly express:
"after calling this method,
selfnow has additional capabilities/methods"
This becomes a major DX limitation for frameworks that dynamically extend objects.
Real-world Example
Consider a UI framework where all elements start as a generic UIElement.
---@class UIElement
local UIElement = {}
Calling:
element:setupUIImage()
injects image-related functionality into the element at runtime:
element:setImage(...)
However, LuaLS still sees element as only UIElement.
The only current workaround is manual casting:
element:setupUIImage()
---@cast element UIImage
element:setImage(material)
This works technically, but becomes repetitive and hurts DX significantly in large codebases.
Comparison to TypeScript
TypeScript supports type refinement after method calls through assertion signatures such as:
asserts this is SomeType
This allows APIs to safely refine object types after capability-changing methods.
A good real-world example is discord.js, where Interaction objects can be refined into subtypes through methods like:
interaction.isButton()
interaction.isChatInputCommand()
After refinement, TypeScript understands the new subtype automatically.
Lua frameworks often use similar runtime patterns, but LuaLS currently cannot model them.
Proposed Solution
Introduce a LuaCats annotation for self-type refinement / capability injection.
Possible syntax examples:
---@injects UIImage
function UIElement:setupUIImage() end
or:
---@mutates self UIImage
function UIElement:setupUIImage() end
or:
---@becomes UIImage
function UIElement:setupUIImage() end
Expected Behavior
After:
element:setupUIImage()
LuaLS would understand:
element :: UIElement & UIImage
allowing:
element:setImage(...)
without requiring manual casts.
Why This Matters
This would greatly improve support for:
- dynamic Lua architectures
- runtime capability injection
- engine bindings
- UI frameworks
- builder APIs
- fluent APIs
- mixin systems
while keeping Lua's dynamic nature intact.
This feature would also reduce:
- repetitive
---@cast - noisy annotations
- inaccurate supersets in base classes
- degraded autocomplete quality
Additional Notes
This feature does not need to become full typestate analysis or advanced dependent typing.
Even a pragmatic flow-sensitive refinement system limited to:
- direct method calls
- current scope
- explicit annotations only
would already provide massive DX improvements.
Example Use Case
---@class UIImage
---@field setImage fun(self: UIImage, material: string)
---@class UIElement
---@injects UIImage
function UIElement:setupUIImage() end
local element = UIElement.new()
element:setupUIImage()
element:setImage("icon")
Expected:
- autocomplete works
- diagnostics recognize
setImage - no manual cast required
Thanks for all the amazing work on LuaLS and LuaCats.
This would significantly improve tooling support for dynamic Lua patterns commonly used in real-world frameworks and game engines.
- Vorherrschende Sprache
- Lua
- Sterne
- 4.4k
- Forks
- 442
- Ø Merge
- 8 T. 9 Std.
- Gemergte PRs (30 T.)
- 1
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus LuaLS/lua-language-server
-
enhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
LuaLS/lua-language-server#1776 ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 65/100
LuaLS/lua-language-server#3463 · 5 Kommentare ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 55/100
LuaLS/lua-language-server#3461 ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 68/100
LuaLS/lua-language-server#3460 · 1 Kommentar · 1 Reaktion ·
-
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 68/100
LuaLS/lua-language-server#3459 · 1 Reaktion ·
Alle Issues in LuaLS/lua-language-server
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
HenrikBengtsson/CBI-software#134 ·
-
Nmap
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 85/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
secondlife/slua#96 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100