add mixins to classic

This commit is contained in:
Alexander Courtis
2024-11-04 17:26:02 +11:00
parent 35015149e2
commit 359398db05
3 changed files with 50 additions and 26 deletions

View File

@@ -6,16 +6,24 @@
-- This module is free software; you can redistribute it and/or modify it under -- This module is free software; you can redistribute it and/or modify it under
-- the terms of the MIT license. See LICENSE for details. -- the terms of the MIT license. See LICENSE for details.
-- --
-- https://github.com/rxi/classic
--
---@class (exact) Object
---@field super Object
---@field private implements table<Object, boolean>
local Object = {} local Object = {}
Object.__index = Object Object.__index = Object ---@diagnostic disable-line: inject-field
---Default constructor
function Object:new() function Object:new(...)
end end
---Extend a class T
---super will be set to T
---@generic T
---@param self T
---@return T
function Object:extend() function Object:extend()
local cls = {} local cls = {}
for k, v in pairs(self) do for k, v in pairs(self) do
@@ -29,22 +37,32 @@ function Object:extend()
return cls return cls
end end
---Implement the functions of a mixin
function Object:implement(...) ---Add the mixin to the implements table
for _, cls in pairs({...}) do ---@param class Object
for k, v in pairs(cls) do function Object:implement(class)
if self[k] == nil and type(v) == "function" then if not rawget(self, "implements") then
self[k] = v rawset(self, "implements", {})
end end
self.implements[class] = true
for k, v in pairs(class) do
if self[k] == nil and type(v) == "function" then
self[k] = v
end end
end end
end end
---Object is an instance of class or implements a mixin
function Object:is(T) ---@generic T
---@param class T
---@return boolean
function Object:is(class)
local mt = getmetatable(self) local mt = getmetatable(self)
while mt do while mt do
if mt == T then if mt == class then
return true
end
if mt.implements and mt.implements[class] then
return true return true
end end
mt = getmetatable(mt) mt = getmetatable(mt)
@@ -52,26 +70,28 @@ function Object:is(T)
return false return false
end end
---Return object if :is otherwise nil
---Return object if it is an instance of class, otherwise nil
---@generic T ---@generic T
---@param cls T ---@param class T
---@return T|nil ---@return T|nil
function Object:as(cls) function Object:as(class)
return self:is(cls) and self or nil return self:is(class) and self or nil
end end
---Constructor that invokes :new on a new instance
function Object:__tostring() ---@generic T
return "Object" ---@param self T
end ---@param ... any
---@return T
function Object:__call(...) function Object:__call(...)
local obj = setmetatable({}, self) local obj = setmetatable({}, self)
obj:new(...) obj:new(...)
return obj return obj
end end
-- avoid unused param warnings in abstract methods
---@param ... any
function Object:nop(...) --luacheck: ignore 212
end
return Object return Object

View File

@@ -2,9 +2,11 @@ local git_utils = require("nvim-tree.git.utils")
local utils = require("nvim-tree.utils") local utils = require("nvim-tree.utils")
local DirectoryNode = require("nvim-tree.node.directory") local DirectoryNode = require("nvim-tree.node.directory")
local LinkNode = require("nvim-tree.node.link")
---@class (exact) DirectoryLinkNode: DirectoryNode, LinkNode ---@class (exact) DirectoryLinkNode: DirectoryNode, LinkNode
local DirectoryLinkNode = DirectoryNode:extend() local DirectoryLinkNode = DirectoryNode:extend()
DirectoryLinkNode:implement(LinkNode)
---@param explorer Explorer ---@param explorer Explorer
---@param parent DirectoryNode ---@param parent DirectoryNode

View File

@@ -2,9 +2,11 @@ local git_utils = require("nvim-tree.git.utils")
local utils = require("nvim-tree.utils") local utils = require("nvim-tree.utils")
local FileNode = require("nvim-tree.node.file") local FileNode = require("nvim-tree.node.file")
local LinkNode = require("nvim-tree.node.link")
---@class (exact) FileLinkNode: FileNode, LinkNode ---@class (exact) FileLinkNode: FileNode, LinkNode
local FileLinkNode = FileNode:extend() local FileLinkNode = FileNode:extend()
FileLinkNode:implement(LinkNode)
---@param explorer Explorer ---@param explorer Explorer
---@param parent DirectoryNode ---@param parent DirectoryNode