Add AbstractDeclarationNavigationContext, and move the html-method from
[kdevelopdvcssupport.git] / language / duchain / definitions.cpp
blob0992a4302d00a94f3be3760cbe3dc15282e30814
1 /* This file is part of KDevelop
2 Copyright 2008 David Nolden <david.nolden.kdevelop@art-master.de>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "definitions.h"
20 #include "declarationid.h"
21 #include "duchainpointer.h"
22 #include "appendedlist.h"
23 #include "repositories/itemrepository.h"
24 #include <QHash>
25 #include <QVector>
27 namespace KDevelop {
29 DEFINE_LIST_MEMBER_HASH(DefinitionsItem, definitions, IndexedDeclaration)
31 class DefinitionsItem {
32 public:
33 DefinitionsItem() {
34 initializeAppendedLists();
36 DefinitionsItem(const DefinitionsItem& rhs) : declaration(rhs.declaration) {
37 initializeAppendedLists();
38 copyListsFrom(rhs);
41 ~DefinitionsItem() {
42 freeAppendedLists();
45 unsigned int hash() const {
46 //We only compare the declaration. This allows us implementing a map, although the item-repository
47 //originally represents a set.
48 return declaration.hash();
51 unsigned short int itemSize() const {
52 return dynamicSize();
55 uint classSize() const {
56 return sizeof(DefinitionsItem);
59 DeclarationId declaration;
61 START_APPENDED_LISTS(DefinitionsItem);
62 APPENDED_LIST_FIRST(DefinitionsItem, IndexedDeclaration, definitions);
63 END_APPENDED_LISTS(DefinitionsItem, definitions);
66 class DefinitionsRequestItem {
67 public:
69 DefinitionsRequestItem(const DefinitionsItem& item) : m_item(item) {
71 enum {
72 AverageSize = 30 //This should be the approximate average size of an Item
75 unsigned int hash() const {
76 return m_item.hash();
79 size_t itemSize() const {
80 return m_item.itemSize();
83 void createItem(DefinitionsItem* item) const {
84 item->initializeAppendedLists(false);
85 item->declaration = m_item.declaration;
86 item->copyListsFrom(m_item);
89 bool equals(const DefinitionsItem* item) const {
90 return m_item.declaration == item->declaration;
93 const DefinitionsItem& m_item;
97 struct DefinitionsPrivate {
98 DefinitionsPrivate() : m_definitions("Definition Map") {
100 //Maps declaration-ids to definitions
101 ItemRepository<DefinitionsItem, DefinitionsRequestItem> m_definitions;
104 Definitions::Definitions() : d(new DefinitionsPrivate())
108 Definitions::~Definitions()
110 delete d;
113 void Definitions::addDefinition(const DeclarationId& id, const IndexedDeclaration& definition)
115 DefinitionsItem item;
116 item.declaration = id;
117 item.definitionsList().append(definition);
118 DefinitionsRequestItem request(item);
120 uint index = d->m_definitions.findIndex(item);
122 if(index) {
123 //Check whether the item is already in the mapped list, else copy the list into the new created item
124 const DefinitionsItem* oldItem = d->m_definitions.itemFromIndex(index);
125 for(unsigned int a = 0; a < oldItem->definitionsSize(); ++a) {
126 if(oldItem->definitions()[a] == definition)
127 return; //Already there
128 item.definitionsList().append(oldItem->definitions()[a]);
131 d->m_definitions.deleteItem(index);
134 //This inserts the changed item
135 d->m_definitions.index(request);
138 void Definitions::removeDefinition(const DeclarationId& id, const IndexedDeclaration& definition)
140 DefinitionsItem item;
141 item.declaration = id;
142 DefinitionsRequestItem request(item);
144 uint index = d->m_definitions.findIndex(item);
146 if(index) {
147 //Check whether the item is already in the mapped list, else copy the list into the new created item
148 const DefinitionsItem* oldItem = d->m_definitions.itemFromIndex(index);
149 for(unsigned int a = 0; a < oldItem->definitionsSize(); ++a)
150 if(!(oldItem->definitions()[a] == definition))
151 item.definitionsList().append(oldItem->definitions()[a]);
153 d->m_definitions.deleteItem(index);
154 Q_ASSERT(d->m_definitions.findIndex(item) == 0);
156 //This inserts the changed item
157 if(item.definitionsSize() != 0)
158 d->m_definitions.index(request);
162 KDevVarLengthArray<IndexedDeclaration> Definitions::definitions(const DeclarationId& id) const
164 KDevVarLengthArray<IndexedDeclaration> ret;
166 DefinitionsItem item;
167 item.declaration = id;
168 DefinitionsRequestItem request(item);
170 uint index = d->m_definitions.findIndex(item);
172 if(index) {
173 const DefinitionsItem* repositoryItem = d->m_definitions.itemFromIndex(index);
174 FOREACH_FUNCTION(IndexedDeclaration decl, repositoryItem->definitions)
175 ret.append(decl);
178 return ret;