Skip to content
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

[Feature requset] Multiple inheritance in @class annotation or add new @mixin annotation #588

Open
alek13 opened this issue Jul 24, 2024 · 4 comments

Comments

@alek13
Copy link

alek13 commented Jul 24, 2024

Lua is very flexible and allows you to do anything.

Sometimes we need something like multiple inheritance or rather mixins.
When several functionality is mixed into the resulting class/table when “designing” the class programmatically.

Example

For example, something like:
We have some base "mixer", that can mix different mixins to itself

-- /base_classes/Form/Base.lua

--- @class base_classes.Form.Mixin      @just interface for mixins
--- @field mix_to fun(base_class:base_classes.Form.Base)

--- @class base_classes.Form.Base
local BaseForm  = {
  -- ...
}

--- @param mixin base_classes.Form.Mixin
function BaseForm:mix(mixin)
	mixin.mix_to(self)
end

Then we have some Factory for “designing” the new class programmatically:

-- /base_classes/Form.lua
require('base_classes.Form.Base')

--- Form Class Factory class.
--- This class constructs for you a base form class.
---
--- @class base_classes.Form
--- @field for_node    fun(self:self):self  mixes `base_classes.Form.Mixin.ForNode` into your class
--- @field for_entity  fun(self:self):self  mixes `base_classes.Form.Mixin.ForEntity` into your class
--- @field ...
--- @field ...
local Form = {
	--- @param self  self
	--- @param mixin string
	__index = function(self, mixin)
		if not table.has_key(self.mixins) then
			return self[mixin]
		end

		return function()
			self.now_constructing = self.now_constructing or setmetatable({}, { __index = BaseForm })
			if not self.now_constructing then
				self.now_constructing:mix(ForNode)
			end
		end
	end
}

And we have several mixins for different purposes:

-- /base_classes/Form/Mixin/ForNode.lua

--- @class base_classes.Form.Mixin.ForNode: base_classes.Form.Mixin
--- @field for_node_any_var string
--- @field for_node_any_fun fun(self:base_classes.Form.Base)
--- @field for_node_...
--- @field for_node_...
local ForNode = {}

--- @static
--- @param base_class base_classes.Form.Base
function ForNode.mix_to(base_class)
	base_class.for_node_any_var = 'any_value'
	base_class.for_node_any_fun = function(self, some_var)
		-- ....
	end
	-- ...
end
-- /base_classes/Form/Mixin/ForEntity.lua

--- @class base_classes.Form.Mixin.ForEntity: base_classes.Form.Mixin
--- @field for_entity_...
--- @field for_entity_...
--- @field for_entity_...
local ForEntity = {}
-- ...
-- /base_classes/Form/Mixin/Personal.lua
-- ...
-- /base_classes/Form/Mixin/Shared.lua
-- ...
-- /base_classes/Form/Mixin/WithTabs.lua
-- ...
-- /base_classes/Form/Mixin/WithPlayerInventory.lua
-- ...

and so on....


So, then we can "construct"/design our own class like this:

-- /some_module/src/SomeForm.lua

local SomeForm = base_classes.Form:personal():for_node():with_tabs()

-- ...

Feature request

So.... It would be very useful, if we could specify from which mixins the class consists of.
For example like this:

-- /some_module/src/SomeForm.lua

--- @class some_module.src.SomeForm: base_classes.Form.Base
--- @mixin base_classes.Form.Mixin.Personal
--- @mixin base_classes.Form.Mixin.ForNode
--- @mixin base_classes.Form.Mixin.WithTabs
local SomeForm = base_classes.Form :personal() :for_node() :with_tabs()

-- ...

or just like multiple inheritance:

-- /some_module/src/SomeForm.lua

--- @class some_module.src.SomeForm: base_classes.Form.Base, base_classes.Form.Mixin.Personal, base_classes.Form.Mixin.ForNode, base_classes.Form.Mixin.WithTabs
local SomeForm = base_classes.Form :personal() :for_node() :with_tabs()

-- ...

Related issues

@CppCXY
Copy link
Member

CppCXY commented Jul 25, 2024

vscode emmylua supports multiple inheritance

@CppCXY
Copy link
Member

CppCXY commented Jul 25, 2024

You can also use vscodeemmylua's language server directly in intellij by installing LSP4IJ. VSCode-EmmyLua supports many advanced features and its performance far exceeds IntelliJ-EmmyLua. I will try to make IntelliJ-EmmyLua use the analysis backend of VSCode-EmmyLua.

@alek13
Copy link
Author

alek13 commented Jul 25, 2024

@CppCXY , thanx for suggestion.
Is there any chance, that it will be added to this plugin ?

@CppCXY
Copy link
Member

CppCXY commented Aug 9, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants