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"
29 DEFINE_LIST_MEMBER_HASH(DefinitionsItem
, definitions
, IndexedDeclaration
)
31 class DefinitionsItem
{
34 initializeAppendedLists();
36 DefinitionsItem(const DefinitionsItem
& rhs
) : declaration(rhs
.declaration
) {
37 initializeAppendedLists();
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 {
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
{
69 DefinitionsRequestItem(const DefinitionsItem
& item
) : m_item(item
) {
72 AverageSize
= 30 //This should be the approximate average size of an Item
75 unsigned int hash() const {
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()
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
);
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
);
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
);
173 const DefinitionsItem
* repositoryItem
= d
->m_definitions
.itemFromIndex(index
);
174 FOREACH_FUNCTION(IndexedDeclaration decl
, repositoryItem
->definitions
)