File indexing completed on 2024-04-28 04:35:52

0001 /*
0002  * This file is part of KDevelop
0003  * Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
0004  *
0005  * This program is free software: you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation, either version 3 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017  */
0018 
0019 #ifndef RUBY_MODULE_DECLARATION_H
0020 #define RUBY_MODULE_DECLARATION_H
0021 
0022 #include <duchain/duchainexport.h>
0023 #include <language/duchain/declaration.h>
0024 #include <language/duchain/declarationdata.h>
0025 
0026 namespace ruby {
0027 
0028 /// Struct used in the appended list in the MethodDeclarationData.
0029 struct KDEVRUBYDUCHAIN_EXPORT ModuleMixin {
0030     KDevelop::IndexedType module;
0031     bool included;
0032 };
0033 
0034 KDEVRUBYDUCHAIN_EXPORT DECLARE_LIST_MEMBER_HASH(ModuleDeclarationData, moduleMixins, ModuleMixin)
0035 KDEVRUBYDUCHAIN_EXPORT DECLARE_LIST_MEMBER_HASH(ModuleDeclarationData, mixers, ModuleMixin)
0036 
0037 /**
0038  * @class ModuleDeclarationData
0039  *
0040  * Private data structure for ModuleDeclaration. It contains an appended list
0041  * of module mix-ins and another one for the mixers.
0042  */
0043 class KDEVRUBYDUCHAIN_EXPORT ModuleDeclarationData : public KDevelop::DeclarationData
0044 {
0045 public:
0046     ModuleDeclarationData()
0047         : isModule(true)
0048         , eigenClass(nullptr)
0049     {
0050         initializeAppendedLists();
0051     }
0052 
0053     explicit ModuleDeclarationData(const ModuleDeclarationData &rhs)
0054         : KDevelop::DeclarationData(rhs)
0055     {
0056         initializeAppendedLists();
0057         copyListsFrom(rhs);
0058         isModule = rhs.isModule;
0059         baseClass = rhs.baseClass;
0060         eigenClass = rhs.eigenClass;
0061     }
0062 
0063     ~ModuleDeclarationData()
0064     {
0065         freeAppendedLists();
0066     }
0067 
0068     // List of module mixins.
0069     START_APPENDED_LISTS_BASE(ModuleDeclarationData, KDevelop::DeclarationData);
0070     APPENDED_LIST_FIRST(ModuleDeclarationData, ModuleMixin, moduleMixins);
0071     APPENDED_LIST(ModuleDeclarationData, ModuleMixin, mixers, moduleMixins);
0072     END_APPENDED_LISTS(ModuleDeclarationData, mixers);
0073 
0074     /// True if it's a module, false if it's a class.
0075     bool isModule;
0076 
0077     /// The eigen class for this module/class.
0078     KDevelop::DUContext *eigenClass;
0079 
0080     /// The base class type (if this is actually a class).
0081     KDevelop::IndexedType baseClass;
0082 };
0083 
0084 /**
0085  * @class ModuleDeclaration
0086  *
0087  * This class represents a module declaration. It defines methods to access to
0088  * the list of module mixins and the list of the mixers.
0089  */
0090 class KDEVRUBYDUCHAIN_EXPORT ModuleDeclaration : public KDevelop::Declaration
0091 {
0092 public:
0093     // Constructors.
0094     ModuleDeclaration(ModuleDeclarationData &data,
0095                                const KDevelop::RangeInRevision &range);
0096     ModuleDeclaration(const KDevelop::RangeInRevision &range,
0097                                KDevelop::DUContext *context);
0098     explicit ModuleDeclaration(const ModuleDeclaration &rhs);
0099     explicit ModuleDeclaration(ModuleDeclarationData &data);
0100 
0101     /// Clean the list of module mix-ins.
0102     void clearModuleMixins();
0103 
0104     /// @returns the size of the list of module mix-ins.
0105     uint moduleMixinsSize();
0106 
0107     /// @returns the list of module mix-ins.
0108     const ModuleMixin * moduleMixins() const;
0109 
0110     /// Add a new module mix-in @p module to the list of module mix-ins.
0111     void addModuleMixin(ModuleMixin module);
0112 
0113     /// Clean the list of mixers.
0114     void clearMixers();
0115 
0116     /// @returns the size of the list of mixers.
0117     uint mixersSize();
0118 
0119     /// @returns the list of mixers.
0120     const ModuleMixin * mixers() const;
0121 
0122     /// Add a new module mix-in @p module to the mixers list.
0123     void addMixer(ModuleMixin module);
0124 
0125     /// @returns true if this is a module, false if it's a class.
0126     bool isModule() const;
0127 
0128     /**
0129      * Set @p isModule to true if this is a module declaration, set to false
0130      * if this is a class declaration.
0131      */
0132     void setIsModule(bool isModule);
0133 
0134     /// Set the type @p base as the new base class for this class declaration.
0135     void setBaseClass(KDevelop::IndexedType base);
0136 
0137     /// Set @p ctx as the new context for the eigenclass.
0138     void setEigenClass(KDevelop::DUContext *ctx);
0139 
0140     /// Invalidate the current base class.
0141     void clearBaseClass();
0142 
0143     /// @returns the base class for this class declaration.
0144     KDevelop::IndexedType baseClass() const;
0145 
0146     /// @returns the eigen class for this module/class declaration.
0147     KDevelop::DUContext *eigenClass() const;
0148 
0149     /// Re-implemented from KDevelop::Declaration.
0150     QString toString() const override;
0151 
0152     enum { Identity = 44 /** The id of this Type. */ };
0153 
0154 private:
0155     /**
0156      * Check whether a module exists or not in one of the selected lists.
0157      *
0158      * @param module The given module.
0159      * @param who set to true if the mixers list is to be picked, and set to
0160      * false if the moduleMixins list is the one to be picked.
0161      * @returns true if the module exists, false otherwise.
0162      */
0163     bool mixinExists(ModuleMixin module, bool who);
0164 
0165 private:
0166     /// Re-implemented from KDevelop::Declaration.
0167     KDevelop::Declaration * clonePrivate() const override;
0168 
0169     DUCHAIN_DECLARE_DATA(ModuleDeclaration)
0170 };
0171 
0172 }
0173 
0174 Q_DECLARE_TYPEINFO(ruby::ModuleMixin, Q_MOVABLE_TYPE);
0175 
0176 #endif // RUBY_MODULE_DECLARATION_H