File indexing completed on 2024-05-05 04:36:51

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 #include <duchain/declarations/moduledeclaration.h>
0020 #include <language/duchain/duchainregister.h>
0021 
0022 namespace ruby {
0023 
0024 REGISTER_DUCHAIN_ITEM(ModuleDeclaration);
0025 DEFINE_LIST_MEMBER_HASH(ModuleDeclarationData, moduleMixins, ModuleMixin)
0026 DEFINE_LIST_MEMBER_HASH(ModuleDeclarationData, mixers, ModuleMixin)
0027 
0028 ModuleDeclaration::ModuleDeclaration(ModuleDeclarationData &data,
0029                                      const KDevelop::RangeInRevision &range)
0030     : KDevelop::Declaration(data, range)
0031 {
0032 }
0033 
0034 ModuleDeclaration::ModuleDeclaration(const ModuleDeclaration &rhs)
0035     : KDevelop::Declaration(*new ModuleDeclarationData(*rhs.d_func()))
0036 {
0037 }
0038 
0039 ModuleDeclaration::ModuleDeclaration(ModuleDeclarationData &data)
0040     : KDevelop::Declaration(data)
0041 {
0042 }
0043 
0044 ModuleDeclaration::ModuleDeclaration(const KDevelop::RangeInRevision &range,
0045                                      KDevelop::DUContext *context)
0046     : KDevelop::Declaration(*new ModuleDeclarationData, range)
0047 {
0048     d_func_dynamic()->setClassId(this);
0049     if (context) {
0050         setContext(context);
0051     }
0052 }
0053 
0054 void ModuleDeclaration::clearModuleMixins()
0055 {
0056     bool wasInSymbolTable = d_func()->m_inSymbolTable;
0057     setInSymbolTable(false);
0058     d_func_dynamic()->moduleMixinsList().clear();
0059     setInSymbolTable(wasInSymbolTable);
0060 }
0061 
0062 uint ModuleDeclaration::moduleMixinsSize()
0063 {
0064     return d_func()->moduleMixinsSize();
0065 }
0066 
0067 const ModuleMixin * ModuleDeclaration::moduleMixins() const
0068 {
0069     return d_func()->moduleMixins();
0070 }
0071 
0072 void ModuleDeclaration::addModuleMixin(ModuleMixin module)
0073 {
0074     bool wasInSymbolTable = d_func()->m_inSymbolTable;
0075     setInSymbolTable(false);
0076     if (!mixinExists(module, false)) {
0077         d_func_dynamic()->moduleMixinsList().append(module);
0078     }
0079     setInSymbolTable(wasInSymbolTable);
0080 }
0081 
0082 void ModuleDeclaration::clearMixers()
0083 {
0084     bool wasInSymbolTable = d_func()->m_inSymbolTable;
0085     setInSymbolTable(false);
0086     d_func_dynamic()->mixersList().clear();
0087     setInSymbolTable(wasInSymbolTable);
0088 }
0089 
0090 uint ModuleDeclaration::mixersSize()
0091 {
0092     return d_func()->mixersSize();
0093 }
0094 
0095 const ModuleMixin* ModuleDeclaration::mixers() const
0096 {
0097     return d_func()->mixers();
0098 }
0099 
0100 void ModuleDeclaration::addMixer(ModuleMixin module)
0101 {
0102     bool wasInSymbolTable = d_func()->m_inSymbolTable;
0103     setInSymbolTable(false);
0104     if (!mixinExists(module, true)) {
0105         d_func_dynamic()->mixersList().append(module);
0106     }
0107     setInSymbolTable(wasInSymbolTable);
0108 }
0109 
0110 bool ModuleDeclaration::isModule() const
0111 {
0112     return d_func()->isModule;
0113 }
0114 
0115 void ModuleDeclaration::setIsModule(bool isModule)
0116 {
0117     d_func_dynamic()->isModule = isModule;
0118 }
0119 
0120 void ModuleDeclaration::setBaseClass(KDevelop::IndexedType base)
0121 {
0122     d_func_dynamic()->baseClass = base;
0123 }
0124 
0125 void ModuleDeclaration::setEigenClass(KDevelop::DUContext *ctx)
0126 {
0127     d_func_dynamic()->eigenClass = ctx;
0128 }
0129 
0130 void ModuleDeclaration::clearBaseClass()
0131 {
0132     bool wasInSymbolTable = d_func()->m_inSymbolTable;
0133     setInSymbolTable(false);
0134     d_func_dynamic()->baseClass = KDevelop::IndexedType();
0135     setInSymbolTable(wasInSymbolTable);
0136 }
0137 
0138 KDevelop::IndexedType ModuleDeclaration::baseClass() const
0139 {
0140     return d_func()->baseClass;
0141 }
0142 
0143 KDevelop::DUContext * ModuleDeclaration::eigenClass() const
0144 {
0145     return d_func()->eigenClass;
0146 }
0147 
0148 QString ModuleDeclaration::toString() const
0149 {
0150     return ((isModule()) ? "module " : "class ") + identifier().toString();
0151 }
0152 
0153 bool ModuleDeclaration::mixinExists(ModuleMixin module, bool who)
0154 {
0155     const ModuleMixin *list;
0156     uint size;
0157     if (who) {
0158         list = d_func()->mixers();
0159         size = d_func()->mixersSize();
0160     } else {
0161         list = d_func()->moduleMixins();
0162         size = d_func()->moduleMixinsSize();
0163     }
0164 
0165     for (uint i = 0; i < size; i++) {
0166         if (list[i].module == module.module) {
0167             return true;
0168         }
0169     }
0170     return false;
0171 }
0172 
0173 KDevelop::Declaration * ModuleDeclaration::clonePrivate() const
0174 {
0175     return new ModuleDeclaration(*this);
0176 }
0177 
0178 }