diff --git a/lua/plenary/class.lua b/lua/plenary/class.lua new file mode 100644 index 00000000..e06808c9 --- /dev/null +++ b/lua/plenary/class.lua @@ -0,0 +1,81 @@ +---@brief [[ +---classic +--- +---Copyright (c) 2014, rxi +---@brief ]] + +---@class Object +local Object = {} +Object.__index = Object + +---Does nothing. +---You have to implement this yourself for extra functionality when initializing +---@param self Object +function Object:new() +end + +---Create a new class/object by extending the base Object class. +---The extended object will have a field called `super` that will access the super class. +---@param self Object +---@return Object +function Object:extend() + local cls = {} + for k, v in pairs(self) do + if k:find("__") == 1 then + cls[k] = v + end + end + cls.__index = cls + cls.super = self + setmetatable(cls, self) + return cls +end + +---Implement a mixin onto this Object. +---@param self Object +---@param nil ... +function Object:implement(...) + for _, cls in pairs({...}) do + for k, v in pairs(cls) do + if self[k] == nil and type(v) == "function" then + self[k] = v + end + end + end +end + +---Checks if the object is an instance +---This will start with the lowest class and loop over all the superclasses. +---@param self Object +---@param T Object +---@return boolean +function Object:is(T) + local mt = getmetatable(self) + while mt do + if mt == T then + return true + end + mt = getmetatable(mt) + end + return false +end + +---The default tostring implementation for an object. +---You can override this to provide a different tostring. +---@param self Object +---@return string +function Object:__tostring() + return "Object" +end + +---You can call the class the initialize it without using `Object:new`. +---@param self Object +---@param nil ... +---@return Object +function Object:__call(...) + local obj = setmetatable({}, self) + obj:new(...) + return obj +end + +return Object