language/duchain
importers.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "importers.h"
00020
00021 #include <QtCore/QHash>
00022 #include <QtCore/QVector>
00023
00024 #include "declarationid.h"
00025 #include "duchainpointer.h"
00026 #include "repositories/itemrepository.h"
00027 #include "topducontext.h"
00028
00029 namespace KDevelop {
00030
00031 DEFINE_LIST_MEMBER_HASH(ImportersItem, importers, IndexedDUContext)
00032
00033 class ImportersItem {
00034 public:
00035 ImportersItem() {
00036 initializeAppendedLists();
00037 }
00038 ImportersItem(const ImportersItem& rhs, bool dynamic = true) : declaration(rhs.declaration) {
00039 initializeAppendedLists(dynamic);
00040 copyListsFrom(rhs);
00041 }
00042
00043 ~ImportersItem() {
00044 freeAppendedLists();
00045 }
00046
00047 unsigned int hash() const {
00048
00049
00050 return declaration.hash();
00051 }
00052
00053 unsigned int itemSize() const {
00054 return dynamicSize();
00055 }
00056
00057 uint classSize() const {
00058 return sizeof(ImportersItem);
00059 }
00060
00061 DeclarationId declaration;
00062
00063 START_APPENDED_LISTS(ImportersItem);
00064 APPENDED_LIST_FIRST(ImportersItem, IndexedDUContext, importers);
00065 END_APPENDED_LISTS(ImportersItem, importers);
00066 };
00067
00068 class ImportersRequestItem {
00069 public:
00070
00071 ImportersRequestItem(const ImportersItem& item) : m_item(item) {
00072 }
00073 enum {
00074 AverageSize = 30
00075 };
00076
00077 unsigned int hash() const {
00078 return m_item.hash();
00079 }
00080
00081 size_t itemSize() const {
00082 return m_item.itemSize();
00083 }
00084
00085 void createItem(ImportersItem* item) const {
00086 new (item) ImportersItem(m_item, false);
00087 }
00088
00089 static void destroy(ImportersItem* item, KDevelop::AbstractItemRepository&) {
00090 item->~ImportersItem();
00091 }
00092
00093 static bool persistent(const ImportersItem* ) {
00094 return true;
00095 }
00096
00097 bool equals(const ImportersItem* item) const {
00098 return m_item.declaration == item->declaration;
00099 }
00100
00101 const ImportersItem& m_item;
00102 };
00103
00104
00105 class ImportersPrivate
00106 {
00107 public:
00108
00109 ImportersPrivate() : m_importers("Importer Map") {
00110 }
00111
00112 ItemRepository<ImportersItem, ImportersRequestItem> m_importers;
00113 };
00114
00115 Importers::Importers() : d(new ImportersPrivate())
00116 {
00117 }
00118
00119 Importers::~Importers()
00120 {
00121 delete d;
00122 }
00123
00124 void Importers::addImporter(const DeclarationId& id, const IndexedDUContext& use)
00125 {
00126 ImportersItem item;
00127 item.declaration = id;
00128 item.importersList().append(use);
00129 ImportersRequestItem request(item);
00130
00131 uint index = d->m_importers.findIndex(item);
00132
00133 if(index) {
00134
00135 const ImportersItem* oldItem = d->m_importers.itemFromIndex(index);
00136 for(unsigned int a = 0; a < oldItem->importersSize(); ++a) {
00137 if(oldItem->importers()[a] == use)
00138 return;
00139 item.importersList().append(oldItem->importers()[a]);
00140 }
00141
00142 d->m_importers.deleteItem(index);
00143 }
00144
00145
00146 d->m_importers.index(request);
00147 }
00148
00149 void Importers::removeImporter(const DeclarationId& id, const IndexedDUContext& use)
00150 {
00151 ImportersItem item;
00152 item.declaration = id;
00153 ImportersRequestItem request(item);
00154
00155 uint index = d->m_importers.findIndex(item);
00156
00157 if(index) {
00158
00159 const ImportersItem* oldItem = d->m_importers.itemFromIndex(index);
00160 for(unsigned int a = 0; a < oldItem->importersSize(); ++a)
00161 if(!(oldItem->importers()[a] == use))
00162 item.importersList().append(oldItem->importers()[a]);
00163
00164 d->m_importers.deleteItem(index);
00165 Q_ASSERT(d->m_importers.findIndex(item) == 0);
00166
00167
00168 if(item.importersSize() != 0)
00169 d->m_importers.index(request);
00170 }
00171 }
00172
00173 KDevVarLengthArray<IndexedDUContext> Importers::importers(const DeclarationId& id) const
00174 {
00175 KDevVarLengthArray<IndexedDUContext> ret;
00176
00177 ImportersItem item;
00178 item.declaration = id;
00179 ImportersRequestItem request(item);
00180
00181 uint index = d->m_importers.findIndex(item);
00182
00183 if(index) {
00184 const ImportersItem* repositoryItem = d->m_importers.itemFromIndex(index);
00185 FOREACH_FUNCTION(IndexedDUContext decl, repositoryItem->importers)
00186 ret.append(decl);
00187 }
00188
00189 return ret;
00190 }
00191
00192 static Importers globalImporters;
00193
00194 Importers& Importers::self() {
00195 return globalImporters;
00196 }
00197
00198 }
00199