LuaLS / LuaLS/lua-language-server
Feature Request: Typestate / Self-Type Refinement for Method Calls
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Lua
- Sterne
- 4.4k
- Forks
- 442
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
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.
Bewertung
- Tech-Stack
- lua
- Bereich
- devtools
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Ruhig
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 45/100