notpeter / playdate-luacats

LuaCATS for Panic PlaydateSDK API
Apache License 2.0
77 stars 1 forks source link

Typing for Panic Lua classes (object.lua): class() and .extends() #1

Closed notpeter closed 1 year ago

notpeter commented 1 year ago

The Playdate Lua SDK includes an object/class implementation which is called with the following syntax:

class("MySprite").extends("playdate.graphics.sprite")

Both these parts are required, the bulk of the class setup actually occurs in .extends and class("MySprite") alone does not create a usable class. In the example above there is an implicit creation of a MySprite in the _G table making it globally accessible -- this makes it difficult for lua-language-server to know where a MySprite object is declared.

Currently I am using the following workaround:

class("MySprite").extends("playdate.graphics.sprite")
---@class MySprite: _Sprite
MySprite = MySprite or {}

I have submitted an enhancement request at devforum.play.date for a trivial enhancement which have .extends() returning the class (it currently returns nil). This would allow the following syntax which feels relatively clear, if still technically redundant:

---@class MySprite: _Sprite
MySprite = class("MySprite").extends("playdate.graphics.sprite")

I think with this I would not define the return type of .extends() which would let the type-checker off the hook.

notpeter commented 1 year ago

Also need to somehow inject .super as a field for new classes because we need to run self.super.init() in our MyClass:init().

Workaround:

---@field super any
erasin commented 10 months ago

@notpeter

---@class TextSprite: playdate.graphics.sprite
---@field text string
---@field font _Font
---@field alignment integer
---@overload fun(text: string): TextSprite
TextSprite = class("TextSprite").extends(playdate.graphics.sprite) or TextSprite -- no-op for LuaLS

---init
---@param text string
function TextSprite:init(text)
  self.text = text
end

-- t Will be recognized as TextSprite 
local t = TextSprite("str")
notpeter commented 10 months ago

Thanks for this @erasin. I had tried to use ---@field __call but it didn't work.

I updated the readme to include this.

I wish there was a way to explicitly document the constructor with comments and just not the limited fun() function format. Perhaps via ---@meta if you included both the ---@class and an identically named function stub with LuaCATS comments. Dunno.