<commit_before>--
-- @copyright 2015 Upstart Illustration LLC. All rights reserved.
--

require "lang.Protocol"

--
-- Factory method for creating new classes.
--
function Class(extends)
    local class = {}
    class.__index = class

    -- Class information --
    local info = debug.getinfo(2, "Sl")
    local className = string.split(info.source, "/")
    className = string.split(className[#className], "%.")
    className = className[1]

    function class.getInfo()
        return info
    end

    -- Prints detailed information about the class.
    function class.__tostring()
        return string.format("Instantiated in file (%s) on line (%d)", info.source, info.currentline)
    end

    -- Abstract --
    local abstract
    function class.abstract(a)
        abstract = a
    end

    -- Returns the protocol that every subclass of this class must conform to.
    function class.protocol()
        return abstract
    end

    -- Subclassing --
    function class.kindOf(kind)
        if kind == class then
            return true
        end
        if extends then
            return extends.kindOf(kind)
        end
        return false
    end

    -- Protocol --
    local protocols = {}

    function class.implements(...)
        local args = {...}
        table.extend(protocols, args)
    end

    function class.conformsTo(protocol)
        for _, p in ipairs(protocols) do
            if protocol == p then
                return true
            end
        end
        return false
    end

    function class.getProtocols()
        return protocols
    end

    local validated = false
    local function validate(instance)
        if #protocols == 0 then
            validated = true
            return
        end
        for _, protocol in ipairs(protocols) do
            protocol.validate(instance)
        end
        validated = true
    end

    if extends then
        local protocol = extends.protocol()
        if protocol then
            class.implements(protocol)
        end
    end

    -- Factory --
    setmetatable(class, {
        __call = function (cls, ...)
            if not cls or type(cls.new) ~= "function" then
                assert(false, string.format("(%s).new must be implemented", className))
            end

            local self = extends and extends() or {}
            cls.new(self, ...)

            function self.getClass()
                return class
            end

            function self.getClassName()
                return className<commit_msg>Pass arguments to base class initializer. Added getClassName as class method to return class's name.<commit_after>--
-- @copyright 2015 Upstart Illustration LLC. All rights reserved.
--

require "lang.Protocol"

--
-- Factory method for creating new classes.
--
function Class(extends)
    local class = {}
    class.__index = class

    -- Class information --
    local info = debug.getinfo(2, "Sl")
    local className = string.split(info.source, "/")
    className = string.split(className[#className], "%.")
    className = className[1]

    function class.getInfo()
        return info
    end

    -- Prints detailed information about the class.
    function class.__tostring()
        return string.format("Instantiated in file (%s) on line (%d)", info.source, info.currentline)
    end

    function class.getClassName()
        return className
    end

    -- Abstract --
    local abstract
    function class.abstract(a)
        abstract = a
    end

    -- Returns the protocol that every subclass of this class must conform to.
    function class.protocol()
        return abstract
    end

    -- Subclassing --
    function class.kindOf(kind)
        if kind == class then
            return true
        end
        if extends then
            return extends.kindOf(kind)
        end
        return false
    end

    -- Protocol --
    local protocols = {}

    function class.implements(...)
        local args = {...}
        table.extend(protocols, args)
    end

    function class.conformsTo(protocol)
        for _, p in ipairs(protocols) do
            if protocol == p then
                return true
            end
        end
        return false
    end

    function class.getProtocols()
        return protocols
    end

    local validated = false
    local function validate(instance)
        if #protocols == 0 then
            validated = true
            return
        end
        for _, protocol in ipairs(protocols) do
            protocol.validate(instance)
        end
        validated = true
    end

    -- Ensure any abstract methods are being implemented in the subclass.
    if extends then
        local protocol = extends.protocol()
        if protocol then
            class.implements(protocol)
        end
    end

    -- Factory --
    setmetatable(class, {
        __call = function (cls, ...)
            if not cls or type(cls.new) ~= "function" then
                assert(false, string.format("(%s).new must be implemented", className))
            end

            local self = extends and extends(...) or {}
            cls.new(self, ...)

            function self.getClass()
                return class
            end

            function self.getClassName()
                return className
{'fraction_non_alphanumeric': 0.08591975775927328, 'fraction_numerical': 0.0026495079485238456, 'mean_word_length': 1.7256317689530687, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5067277', 'n_tokens_mistral': 1365, 'n_tokens_neox': 1303, 'n_words': 444}