IntelliJ-EmmyLua icon indicating copy to clipboard operation
IntelliJ-EmmyLua copied to clipboard

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

Open alek13 opened this issue 1 year ago • 8 comments

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

  • #11
  • #247
  • #402

alek13 avatar Jul 24 '24 22:07 alek13

vscode emmylua supports multiple inheritance

CppCXY avatar Jul 25 '24 02:07 CppCXY

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.

CppCXY avatar Jul 25 '24 02:07 CppCXY

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

alek13 avatar Jul 25 '24 13:07 alek13

maybe you can try my plugin: https://plugins.jetbrains.com/plugin/25076-emmylua2/edit/versions/stable/584455

CppCXY avatar Aug 09 '24 12:08 CppCXY

When is this feature expected to be released in the new version?

LongLostPenPal avatar Jan 17 '25 03:01 LongLostPenPal

When is this feature expected to be released in the new version?

IntelliJ EmmyLua has never had substantial updates; it is recommended to use EmmyLua2 or vscode-emmylua

CppCXY avatar Jan 17 '25 03:01 CppCXY

ui.settings.require_like_function_names=&Require-like function names: intellij has this feature, does vscode has? if so, how to set?

aflyingdoge avatar Mar 19 '25 02:03 aflyingdoge

see: https://github.com/CppCXY/emmylua-analyzer-rust/blob/main/docs/config/emmyrc_json_EN.md

CppCXY avatar Mar 19 '25 02:03 CppCXY