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