Add AbstractDeclarationNavigationContext, and move the html-method from
[kdevelopdvcssupport.git] / language / duchain / declarationid.cpp
blob5ffa4fac8a9608fb93e40ca66c223e0d4e8dbff8
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 "declarationid.h"
20 #include "ducontext.h"
21 #include "topducontext.h"
22 #include "../editor/simplecursor.h"
23 #include "duchain.h"
24 #include "declaration.h"
25 #include "persistentsymboltable.h"
26 #include "arrayhelpers.h"
28 namespace KDevelop {
30 DeclarationId::DeclarationId(const IndexedQualifiedIdentifier& id, uint additionalId, uint specialization)
31 : m_direct(false), m_specialization(specialization)
33 indirect.m_identifier = id;
34 indirect.m_additionalIdentity = additionalId;
38 DeclarationId::DeclarationId(const IndexedDeclaration& decl, uint specialization)
39 : direct(decl), m_direct(true), m_specialization(specialization)
44 // IndexedQualifiedIdentifier DeclarationId::identifier() const
45 // {
46 // return m_identifier;
47 // }
48 //
49 // uint DeclarationId::additionalIdentity() const
50 // {
51 // return m_additionalIdentity;
52 // }
54 bool DeclarationId::isDirect() const
56 return m_direct;
59 void DeclarationId::setSpecialization(uint spec) {
60 m_specialization = spec;
63 uint DeclarationId::specialization() const {
64 return m_specialization;
67 KDevVarLengthArray<Declaration*> DeclarationId::getDeclarations(const TopDUContext* top) const
69 KDevVarLengthArray<Declaration*> ret;
71 if(m_direct == false) {
72 //Find the declaration by its qualified identifier and additionalIdentity
73 QualifiedIdentifier id(indirect.m_identifier);
75 const IndexedDeclaration* decls;
76 uint declCount = 0;
77 PersistentSymbolTable::self().declarations(id, declCount, decls);
79 const QSet<uint>* recursiveImportIndices = top ? &top->recursiveImportIndices() : 0;
81 for(uint a = 0; a < declCount; ++a) {
82 const IndexedDeclaration& iDecl(decls[a]);
84 //Don't trigger loading of top-contexts from here, it will create a lot of problems
85 if((!top && !DUChain::self()->isInMemory(iDecl.topContextIndex())))
86 continue;
88 if(!top || top->ownIndex() == iDecl.topContextIndex() || recursiveImportIndices->contains(iDecl.topContextIndex())) {
89 Declaration* decl = iDecl.data();
90 if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) {
91 //Hit
92 ret.append(decl);
96 }else{
97 ret.append(direct.declaration());
100 if(!ret.isEmpty() && m_specialization) {
101 KDevVarLengthArray<Declaration*> newRet;
102 FOREACH_ARRAY(Declaration* decl, ret) {
103 Declaration* specialized = decl->specialize(m_specialization, top ? top : decl->topContext());
104 if(specialized)
105 newRet.append(specialized);
107 return newRet;
109 return ret;
112 Declaration* DeclarationId::getDeclaration(const TopDUContext* top) const
114 Declaration* ret = 0;
116 if(m_direct == false) {
117 //Find the declaration by its qualified identifier and additionalIdentity
118 QualifiedIdentifier id(indirect.m_identifier);
120 const IndexedDeclaration* decls;
121 uint declCount = 0;
122 PersistentSymbolTable::self().declarations(id, declCount, decls);
124 const QSet<uint>* recursiveImportIndices = top ? &top->recursiveImportIndices() : 0;
126 for(uint a = 0; a < declCount; ++a) {
127 const IndexedDeclaration& iDecl(decls[a]);
129 //Don't trigger loading of top-contexts from here, it will create a lot of problems
130 if((!top && !DUChain::self()->isInMemory(iDecl.topContextIndex())))
131 continue;
133 if(!top || top->ownIndex() == iDecl.topContextIndex() || recursiveImportIndices->contains(iDecl.topContextIndex())) {
134 Declaration* decl = iDecl.data();
135 if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) {
136 //Hit
137 ret = decl;
139 //If this is a forward declaration, search on.
140 if(!decl->isForwardDeclaration())
141 break;
145 }else{
146 //Find the declaration by m_topContext and m_declaration
147 ret = direct.declaration();
150 if(ret)
151 return ret->specialize(m_specialization, top ? top : ret->topContext());
152 else
153 return 0;
156 QualifiedIdentifier DeclarationId::qualifiedIdentifier() const {
157 Declaration* decl = getDeclaration(0);
158 if(decl)
159 return decl->qualifiedIdentifier();
160 else if(m_direct)
161 return QualifiedIdentifier(QString("(unknown direct declaration)"));
162 else
163 return QualifiedIdentifier(QString("(missing)")) + indirect.m_identifier.identifier();