asledgehammer / Candle-Compiler

GNU Lesser General Public License v3.0
2 stars 3 forks source link

Represent interfaces as classes #4

Open demiurgeQuantified opened 6 months ago

demiurgeQuantified commented 6 months ago

Currently we use a decorative ---@implement to annotate what interfaces that a class implements. I suggest that we instead have implementing classes inherit from them. The benefit to this would be when a method's return type is an interface - for example, IsoZombie's getThumpTarget returns a Thumpable. There's basically nothing you can do with this without raising a warning.

local thumpable = zombie:getThumpTarget()
---@cast thumpable IsoThumpable

---@type IsoThumpable
local thumpable = zombie:getThumpTarget()

Both of these snippets raise a warning in the type checker as it doesn't see Thumpable as assignable to IsoThumpable (though they do still work).

If we were to do this, we'd also need to generate stubs for non-exposed interfaces that are implemented by exposed classes (I'm not really sure why there are exposed interfaces, but only they are currently annotated) - for example, Thumpable from the previous example isn't exposed, which means you can't call the interface methods without a warning either. We'd also need to undo the work on 'flattening' interfaces into their implementing classes.

I recall us having some trouble with interfaces before, so there may be a pitfall to this approach I'm missing. If there is, we could instead just alias all interfaces as a union type of all exposed implementing classes for similar effect - in fact we've already done this manually for Map and List.

JabDoesThings commented 6 months ago

This may take some work to implement and isn't critical so I'm going to keep the priority low for the issue. It's definitely something that needs to happen.