language/duchain
declarationid.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "declarationid.h"
00020 #include "ducontext.h"
00021 #include "topducontext.h"
00022 #include "../editor/simplecursor.h"
00023 #include "duchain.h"
00024 #include "declaration.h"
00025 #include "persistentsymboltable.h"
00026 #include "arrayhelpers.h"
00027 #include "instantiationinformation.h"
00028 #include <util/convenientfreelist.h>
00029
00030 namespace KDevelop {
00031
00032 DeclarationId::DeclarationId(const IndexedQualifiedIdentifier& id, uint additionalId, IndexedInstantiationInformation specialization)
00033 : m_direct(false), m_specialization(specialization)
00034 {
00035 indirect.m_identifier = id;
00036 indirect.m_additionalIdentity = additionalId;
00037
00038 }
00039
00040 DeclarationId::DeclarationId(const IndexedDeclaration& decl, IndexedInstantiationInformation specialization)
00041 : direct(decl), m_direct(true), m_specialization(specialization)
00042 {
00043
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 bool DeclarationId::isDirect() const
00057 {
00058 return m_direct;
00059 }
00060
00061 void DeclarationId::setSpecialization(IndexedInstantiationInformation spec) {
00062 m_specialization = spec;
00063 }
00064
00065 IndexedInstantiationInformation DeclarationId::specialization() const {
00066 return m_specialization;
00067 }
00068
00069 KDevVarLengthArray<Declaration*> DeclarationId::getDeclarations(const TopDUContext* top) const
00070 {
00071 KDevVarLengthArray<Declaration*> ret;
00072
00073 if(m_direct == false) {
00074
00075 QualifiedIdentifier id(indirect.m_identifier);
00076
00077 if(top) {
00078
00079 PersistentSymbolTable::FilteredDeclarationIterator filter = PersistentSymbolTable::self().getFilteredDeclarations(id, top->recursiveImportIndices());
00080 for(; filter; ++filter) {
00081 Declaration* decl = filter->data();
00082 if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) {
00083
00084 ret.append(decl);
00085 }
00086 }
00087 }else{
00088
00089 PersistentSymbolTable::Declarations decls = PersistentSymbolTable::self().getDeclarations(id);
00090 PersistentSymbolTable::Declarations::Iterator decl = decls.iterator();
00091 for(; decl; ++decl) {
00092 const IndexedDeclaration& iDecl(*decl);
00093
00095
00096 if((!DUChain::self()->isInMemory(iDecl.topContextIndex())))
00097 continue;
00098
00099 if(!top) {
00100 Declaration* decl = iDecl.data();
00101 if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) {
00102
00103 ret.append(decl);
00104 }
00105 }
00106 }
00107 }
00108 }else{
00109 ret.append(direct.declaration());
00110 }
00111
00112 if(!ret.isEmpty() && m_specialization.index()) {
00113 KDevVarLengthArray<Declaration*> newRet;
00114 FOREACH_ARRAY(Declaration* decl, ret) {
00115 Declaration* specialized = decl->specialize(m_specialization, top ? top : decl->topContext());
00116 if(specialized)
00117 newRet.append(specialized);
00118 }
00119 return newRet;
00120 }
00121 return ret;
00122 }
00123
00124 Declaration* DeclarationId::getDeclaration(const TopDUContext* top) const
00125 {
00126 Declaration* ret = 0;
00127
00128 if(m_direct == false) {
00129
00130 QualifiedIdentifier id(indirect.m_identifier);
00131
00132 if(top) {
00133
00134 PersistentSymbolTable::FilteredDeclarationIterator filter = PersistentSymbolTable::self().getFilteredDeclarations(id, top->recursiveImportIndices());
00135 for(; filter; ++filter) {
00136 Declaration* decl = filter->data();
00137 if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) {
00138
00139 ret = decl;
00140 if(!ret->isForwardDeclaration())
00141 break;
00142 }
00143 }
00144 }else{
00145
00146 PersistentSymbolTable::Declarations decls = PersistentSymbolTable::self().getDeclarations(id);
00147 PersistentSymbolTable::Declarations::Iterator decl = decls.iterator();
00148 for(; decl; ++decl) {
00149 const IndexedDeclaration& iDecl(*decl);
00150
00152
00153 if((!DUChain::self()->isInMemory(iDecl.topContextIndex())))
00154 continue;
00155
00156 if(!top) {
00157 Declaration* decl = iDecl.data();
00158 if(decl && indirect.m_additionalIdentity == decl->additionalIdentity()) {
00159
00160 ret = decl;
00161 if(!ret->isForwardDeclaration())
00162 break;
00163 }
00164 }
00165 }
00166 }
00167 }else{
00168
00169 ret = direct.declaration();
00170 }
00171
00172 if(ret)
00173 return ret->specialize(m_specialization, top ? top : ret->topContext());
00174 else
00175 return 0;
00176 }
00177
00178 QualifiedIdentifier DeclarationId::qualifiedIdentifier() const {
00179
00180 if(!m_direct) {
00181 QualifiedIdentifier baseIdentifier = indirect.m_identifier.identifier();
00182 if(!m_specialization.index())
00183 return baseIdentifier;
00184 return m_specialization.information().applyToIdentifier(baseIdentifier);
00185 } else {
00186 Declaration* decl = getDeclaration(0);
00187 if(decl)
00188 return decl->qualifiedIdentifier();
00189
00190 return QualifiedIdentifier(QString("(unknown direct declaration)"));
00191 }
00192
00193 return QualifiedIdentifier(QString("(missing)")) + indirect.m_identifier.identifier();
00194 }
00195
00196 }