• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDevelop Platform Libraries
  • Sitemap
  • Contact Us
 

language/duchain

declaration.cpp

00001 /* This file is part of KDevelop
00002     Copyright 2006 Hamish Rodda <rodda@kde.org>
00003     Copyright 2007 2008 David Nolden <david.nolden.kdevelop@art-master.de>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "declaration.h"
00021 #include "declarationdata.h"
00022 
00023 #include <QtCore/QByteArray>
00024 
00025 #include <ktexteditor/smartrange.h>
00026 #include <ktexteditor/document.h>
00027 
00028 #include <limits>
00029 
00030 #include "topducontext.h"
00031 #include "topducontextdynamicdata.h"
00032 #include "use.h"
00033 #include "forwarddeclaration.h"
00034 #include "duchain.h"
00035 #include "duchainlock.h"
00036 #include "ducontextdata.h"
00037 #include "declarationid.h"
00038 #include "uses.h"
00039 #include "indexedstring.h"
00040 #include "duchainregister.h"
00041 #include "persistentsymboltable.h"
00042 #include "repositories/stringrepository.h"
00043 #include "types/identifiedtype.h"
00044 #include "types/structuretype.h"
00045 #include "functiondefinition.h"
00046 #include "codemodel.h"
00047 #include "specializationstore.h"
00048 #include "types/typeutils.h"
00049 #include "types/typealiastype.h"
00050 
00051 using namespace KTextEditor;
00052 
00053 namespace KDevelop
00054 {
00055 
00057 Repositories::StringRepository commentRepository("Comment Repository");
00058 
00059 REGISTER_DUCHAIN_ITEM(Declaration);
00060 
00061 DeclarationData::DeclarationData()
00062   : m_comment(0), m_isDefinition(false), m_inSymbolTable(false),
00063     m_isTypeAlias(false), m_anonymousInContext(false), m_isFinal(false)
00064 {
00065   m_kind = Declaration::Instance;
00066 }
00067 
00068 DeclarationData::DeclarationData( const DeclarationData& rhs ) : DUChainBaseData(rhs),
00069 m_internalContext(rhs.m_internalContext),
00070 m_type(rhs.m_type),
00071 m_identifier(rhs.m_identifier),
00072 m_declaration(rhs.m_declaration),
00073 m_comment(rhs.m_comment),
00074 m_kind(rhs.m_kind),
00075 m_isDefinition(rhs.m_isDefinition),
00076 m_inSymbolTable(rhs.m_inSymbolTable),
00077 m_isTypeAlias(rhs.m_isTypeAlias),
00078 m_anonymousInContext(rhs.m_anonymousInContext),
00079 m_isFinal(rhs.m_isFinal)
00080 {
00081 }
00082 
00083 Declaration::Kind Declaration::kind() const {
00084   DUCHAIN_D(Declaration);
00085   return d->m_kind;
00086 }
00087 
00088 void Declaration::setKind(Kind kind) {
00089   DUCHAIN_D_DYNAMIC(Declaration);
00090   d->m_kind = kind;
00091   updateCodeModel();
00092 }
00093 
00094 bool Declaration::inDUChain() const {
00095   DUCHAIN_D(Declaration);
00096   if( d->m_anonymousInContext )
00097     return false;
00098   if( !context() )
00099     return false;
00100   TopDUContext* top = topContext();
00101   return top && top->inDUChain();
00102 }
00103 
00104 Declaration::Declaration( const SimpleRange& range, DUContext* context )
00105   : DUChainBase(*new DeclarationData, range)
00106 {
00107   d_func_dynamic()->setClassId(this);
00108   m_topContext = 0;
00109   m_context = 0;
00110   m_indexInTopContext = 0;
00111 
00112   if(context)
00113     setContext(context);
00114 }
00115 
00116 uint Declaration::ownIndex() const
00117 {
00118   ENSURE_CAN_READ
00119   return m_indexInTopContext;
00120 }
00121 
00122 Declaration::Declaration(const Declaration& rhs)
00123   : DUChainBase(*new DeclarationData( *rhs.d_func() )) {
00124   setSmartRange(rhs.smartRange(), DocumentRangeObject::DontOwn);
00125   m_topContext = 0;
00126   m_context = 0;
00127   m_indexInTopContext = 0;
00128 }
00129 
00130 Declaration::Declaration( DeclarationData & dd ) : DUChainBase(dd)
00131 {
00132   m_topContext = 0;
00133   m_context = 0;
00134   m_indexInTopContext = 0;
00135 }
00136 
00137 Declaration::Declaration( DeclarationData & dd, const SimpleRange& range )
00138   : DUChainBase(dd, range)
00139 {
00140   m_topContext = 0;
00141   m_context = 0;
00142   m_indexInTopContext = 0;
00143 }
00144 
00145 Declaration::~Declaration()
00146 {
00147   uint oldOwnIndex = m_indexInTopContext;
00148 
00149   TopDUContext* topContext = this->topContext();
00150 
00151   //Only perform the actions when the top-context isn't being deleted, or when it hasn't been stored to disk
00152   if(!topContext->deleting() || !topContext->isOnDisk()) {
00153     DUCHAIN_D_DYNAMIC(Declaration);
00154     // Inserted by the builder after construction has finished.
00155     if( d->m_internalContext.context() )
00156       d->m_internalContext.context()->setOwner(0);
00157 
00158     if (d->m_inSymbolTable && !d->m_identifier.isEmpty()) {
00159       QualifiedIdentifier id = qualifiedIdentifier();
00160       PersistentSymbolTable::self().removeDeclaration(id, this);
00161       CodeModel::self().removeItem(url(), id);
00162     }
00163 
00164     d->m_inSymbolTable = false;
00165   }
00166 
00167   // If the parent-context already has dynamic data, like for example any temporary context,
00168   // always delete the declaration, to not create crashes within more complex code like C++ template stuff.
00169   if (context() && !d_func()->m_anonymousInContext) {
00170     if(!topContext->deleting() || !topContext->isOnDisk() || context()->d_func()->isDynamic())
00171       context()->m_dynamicData->removeDeclaration(this);
00172   }
00173 
00174   clearOwnIndex();
00175 
00176   if(!topContext->deleting() || !topContext->isOnDisk()) {
00177     setContext(0);
00178 
00179     setAbstractType(AbstractType::Ptr());
00180   }
00181   Q_ASSERT(d_func()->isDynamic() == (!topContext->deleting() || !topContext->isOnDisk() || topContext->m_dynamicData->isTemporaryDeclarationIndex(oldOwnIndex)));
00182   //DUChain::declarationChanged(this, DUChainObserver::Deletion, DUChainObserver::NotApplicable);
00183 }
00184 
00185 QByteArray Declaration::comment() const {
00186   DUCHAIN_D(Declaration);
00187   if(!d->m_comment)
00188     return 0;
00189   else
00190     return Repositories::arrayFromItem(commentRepository.itemFromIndex(d->m_comment));
00191 }
00192 
00193 void Declaration::setComment(const QByteArray& str) {
00194   DUCHAIN_D_DYNAMIC(Declaration);
00195   if(str.isEmpty())
00196     d->m_comment = 0;
00197   else
00198     d->m_comment = commentRepository.index(Repositories::StringRepositoryItemRequest(str, IndexedString::hashString(str, str.length()), str.length()));
00199 }
00200 
00201 void Declaration::setComment(const QString& str) {
00202   setComment(str.toUtf8());
00203 }
00204 
00205 Identifier Declaration::identifier( ) const
00206 {
00207   //ENSURE_CAN_READ Commented out for performance reasons
00208   return d_func()->m_identifier.identifier();
00209 }
00210 
00211 IndexedIdentifier Declaration::indexedIdentifier( ) const
00212 {
00213   //ENSURE_CAN_READ Commented out for performance reasons
00214   return d_func()->m_identifier;
00215 }
00216 
00217 LocalIndexedDeclaration::LocalIndexedDeclaration(Declaration* decl) {
00218   if(!decl)
00219     m_declarationIndex = 0;
00220   else
00221     m_declarationIndex = decl->m_indexInTopContext;
00222 }
00223 
00224 LocalIndexedDeclaration::LocalIndexedDeclaration(uint declarationIndex) : m_declarationIndex(declarationIndex) {
00225 }
00226 
00227 Declaration* LocalIndexedDeclaration::data(TopDUContext* top) const {
00228   if(!m_declarationIndex)
00229     return 0;
00230   return top->m_dynamicData->getDeclarationForIndex(m_declarationIndex);
00231 }
00232 
00233 bool LocalIndexedDeclaration::isLoaded(TopDUContext* top) const {
00234   if(m_declarationIndex)
00235     return top->m_dynamicData->isDeclarationForIndexLoaded(m_declarationIndex);
00236   else
00237     return false;
00238 }
00239 
00240 IndexedDeclaration::IndexedDeclaration(uint topContext, uint declarationIndex) : m_topContext(topContext), m_declarationIndex(declarationIndex) {
00241 }
00242 
00243 IndexedDeclaration::IndexedDeclaration(Declaration* decl) {
00244   if(decl) {
00245     m_topContext = decl->topContext()->ownIndex();
00246     m_declarationIndex = decl->m_indexInTopContext;
00247   }else{
00248     m_topContext = 0;
00249     m_declarationIndex = 0;
00250   }
00251 }
00252 
00253 Declaration* IndexedDeclaration::declaration() const {
00254   if(isDummy())
00255     return 0;
00256 //   ENSURE_CHAIN_READ_LOCKED
00257   if(!m_topContext || !m_declarationIndex)
00258     return 0;
00259 
00260   TopDUContext* ctx = DUChain::self()->chainForIndex(m_topContext);
00261   if(!ctx)
00262     return 0;
00263 
00264   return ctx->m_dynamicData->getDeclarationForIndex(m_declarationIndex);
00265 }
00266 
00267 void Declaration::rebuildDynamicData(DUContext* parent, uint ownIndex)
00268 {
00269   DUChainBase::rebuildDynamicData(parent, ownIndex);
00270 
00271   m_context = parent;
00272   m_topContext = parent->topContext();
00273   m_indexInTopContext = ownIndex;
00274 
00275   parent->m_dynamicData->addDeclarationToHash(d_func()->m_identifier.identifier(), this);
00276 }
00277 
00278 void Declaration::setIdentifier(const Identifier& identifier)
00279 {
00280   ENSURE_CAN_WRITE
00281   DUCHAIN_D_DYNAMIC(Declaration);
00282   bool wasInSymbolTable = d->m_inSymbolTable;
00283 
00284   setInSymbolTable(false);
00285 
00286   if( m_context && !d->m_anonymousInContext )
00287     m_context->changingIdentifier( this, d->m_identifier, identifier );
00288 
00289   d->m_identifier = identifier;
00290 
00291   setInSymbolTable(wasInSymbolTable);
00292   //DUChain::declarationChanged(this, DUChainObserver::Change, DUChainObserver::Identifier);
00293 }
00294 
00295 IndexedType Declaration::indexedType() const
00296 {
00297   return d_func()->m_type;
00298 }
00299 
00300 AbstractType::Ptr Declaration::abstractType( ) const
00301 {
00302   //ENSURE_CAN_READ Commented out for performance reasons
00303   return d_func()->m_type.abstractType();
00304 }
00305 
00306 void Declaration::setAbstractType(AbstractType::Ptr type)
00307 {
00308   ENSURE_CAN_WRITE
00309   DUCHAIN_D_DYNAMIC(Declaration);
00310 
00311   //if (d->m_type)
00312     //DUChain::declarationChanged(this, DUChainObserver::Removal, DUChainObserver::DataType);
00313 
00314   d->m_type = type->indexed();
00315 
00316   updateCodeModel();
00317   //if (d->m_type)
00318     //DUChain::declarationChanged(this, DUChainObserver::Addition, DUChainObserver::DataType);
00319 }
00320 
00321 Declaration* Declaration::specialize(IndexedInstantiationInformation /*specialization*/, const TopDUContext* /*topContext*/, int /*upDistance*/)
00322 {
00323   return this;
00324 }
00325 
00326 QualifiedIdentifier Declaration::qualifiedIdentifier() const
00327 {
00328   ENSURE_CAN_READ
00329 
00330   QualifiedIdentifier ret;
00331   DUContext* ctx = m_context;
00332   if(ctx)
00333     ret = ctx->scopeIdentifier(true);
00334   ret.push(d_func()->m_identifier);
00335   return ret;
00336 }
00337 
00338 // QString Declaration::mangledIdentifier() const
00339 // {
00340 //   //GNU mangling specs from http://theory.uwinnipeg.ca/gnu/gcc/gxxint_15.html
00341 //
00342 //   if (abstractType())
00343 //     return abstractType()->mangled();
00344 //
00345 //   // Error...
00346 //   return qualifiedIdentifier().mangled();
00347 // }
00348 
00349 DUContext * Declaration::context() const
00350 {
00351   //ENSURE_CAN_READ Commented out for performance reasons
00352   return m_context;
00353 }
00354 
00355 bool Declaration::isAnonymous() const
00356 {
00357   return d_func()->m_anonymousInContext;
00358 }
00359 
00360 void Declaration::setContext(DUContext* context, bool anonymous)
00361 {
00362   Q_ASSERT(!context || context->topContext());
00364   if(!specialization().index()) {
00365     //problem: specialization() doesn't work during destructor
00366 //     ENSURE_CAN_WRITE
00367   }
00368 
00369   setInSymbolTable(false);
00370 
00371   //We don't need to clear, because it's not allowed to move from one top-context into another
00372 //   clearOwnIndex();
00373 
00374 
00375   DUCHAIN_D_DYNAMIC(Declaration);
00376   if (m_context && context) {
00377     Q_ASSERT(m_context->topContext() == context->topContext());
00378   }
00379 
00380   if (m_context) {
00381     if( !d->m_anonymousInContext ) {
00382       m_context->m_dynamicData->removeDeclaration(this);
00383         //DUChain::declarationChanged(this, DUChainObserver::Removal, DUChainObserver::Context, m_context);
00384     }
00385   }
00386 
00387   if(context)
00388     m_topContext = context->topContext();
00389   else
00390     m_topContext = 0;
00391 
00392   d->m_anonymousInContext = anonymous;
00393   m_context = context;
00394 
00395   if (context) {
00396     if(!m_indexInTopContext)
00397       allocateOwnIndex();
00398 
00399     if(!d->m_anonymousInContext) {
00400       context->m_dynamicData->addDeclaration(this);
00401       //DUChain::declarationChanged(this, DUChainObserver::Addition, DUChainObserver::Context, m_context);
00402     }
00403 
00404     if(context->inSymbolTable() && !anonymous)
00405       setInSymbolTable(true);
00406   }
00407 }
00408 
00409 void Declaration::clearOwnIndex() {
00410 
00411   if(!m_indexInTopContext)
00412     return;
00413 
00414   if(!context() || (!d_func()->m_anonymousInContext && !context()->isAnonymous())) {
00415     ENSURE_CAN_WRITE
00416   }
00417 
00418   if(m_indexInTopContext) {
00419     Q_ASSERT(m_topContext);
00420     m_topContext->m_dynamicData->clearDeclarationIndex(this);
00421   }
00422   m_indexInTopContext = 0;
00423 }
00424 
00425 void Declaration::allocateOwnIndex() {
00426 
00428 //   if(context() && (!context()->isAnonymous() && !d_func()->m_anonymousInContext)) {
00429 //     ENSURE_CAN_WRITE
00430 //   }
00431 
00432   Q_ASSERT(m_topContext);
00433 
00434   m_indexInTopContext = m_topContext->m_dynamicData->allocateDeclarationIndex(this, d_func()->m_anonymousInContext || !context() || context()->isAnonymous());
00435   Q_ASSERT(m_indexInTopContext);
00436 
00437   if(!m_topContext->m_dynamicData->getDeclarationForIndex(m_indexInTopContext))
00438     kFatal() << "Could not re-retrieve declaration" << "index:" << m_indexInTopContext;
00439 
00440 }
00441 
00442 const Declaration* Declaration::logicalDeclaration(const TopDUContext* topContext) const {
00443   ENSURE_CAN_READ
00444   if(isForwardDeclaration()) {
00445     const ForwardDeclaration* dec = toForwardDeclaration();
00446     Declaration* ret = dec->resolve(topContext);
00447     if(ret)
00448       return ret;
00449   }
00450   return this;
00451 }
00452 
00453 Declaration* Declaration::logicalDeclaration(const TopDUContext* topContext) {
00454   ENSURE_CAN_READ
00455   if(isForwardDeclaration()) {
00456     ForwardDeclaration* dec = toForwardDeclaration();
00457     Declaration* ret = dec->resolve(topContext);
00458     if(ret)
00459       return ret;
00460   }
00461   return this;
00462 }
00463 
00464 DUContext * Declaration::logicalInternalContext(const TopDUContext* topContext) const {
00465   ENSURE_CAN_READ
00466 
00467   if(!isDefinition()) {
00468     Declaration* def = FunctionDefinition::definition(this);
00469     if( def )
00470       return def->internalContext();
00471   }
00472 
00473   if( d_func()->m_isTypeAlias ) {
00475     TypeAliasType::Ptr t = type<TypeAliasType>();
00476     if(t) {
00477       AbstractType::Ptr target = t->type();
00478       
00479       IdentifiedType* idType = dynamic_cast<IdentifiedType*>(target.unsafeData());
00480       if( idType ) {
00481         Declaration* decl = idType->declaration(topContext);
00482         if(decl && decl != this) {
00483           return decl->logicalInternalContext( topContext );
00484         }
00485       }
00486     }
00487   }
00488 
00489   return internalContext();
00490 }
00491 
00492 DUContext * Declaration::internalContext() const
00493 {
00494 //   ENSURE_CAN_READ
00495   return d_func()->m_internalContext.context();
00496 }
00497 
00498 void Declaration::setInternalContext(DUContext* context)
00499 {
00500   if(this->context()) {
00501     ENSURE_CAN_WRITE
00502   }
00503   DUCHAIN_D_DYNAMIC(Declaration);
00504 
00505   if( context == d->m_internalContext.context() )
00506     return;
00507 
00508   if(!m_topContext) {
00509     //Take the top-context from the other side. We need to allocate an index, so we can safely call setOwner(..)
00510     m_topContext = context->topContext();
00511     allocateOwnIndex();
00512   }
00513 
00514   DUContext* oldInternalContext = d->m_internalContext.context();
00515 
00516   d->m_internalContext = context;
00517 
00518   //Q_ASSERT( !oldInternalContext || oldInternalContext->owner() == this );
00519   if( oldInternalContext && oldInternalContext->owner() == this )
00520     oldInternalContext->setOwner(0);
00521 
00522 
00523   if( context )
00524     context->setOwner(this);
00525 }
00526 
00527 
00528 bool Declaration::operator ==(const Declaration & other) const
00529 {
00530   ENSURE_CAN_READ
00531 
00532   return this == &other;
00533 }
00534 
00535 QString Declaration::toString() const
00536 {
00537   return QString("%3 %4").arg(abstractType() ? abstractType()->toString() : QString("<notype>")).arg(identifier().toString());
00538 }
00539 
00540 // kate: indent-width 2;
00541 
00542 bool Declaration::isDefinition() const
00543 {
00544   ENSURE_CAN_READ
00545   DUCHAIN_D(Declaration);
00546 
00547   return d->m_isDefinition;
00548 }
00549 
00550 void Declaration::setDeclarationIsDefinition(bool dd)
00551 {
00552   ENSURE_CAN_WRITE
00553   DUCHAIN_D_DYNAMIC(Declaration);
00554   d->m_isDefinition = dd;
00555 //   if (d->m_isDefinition && definition()) {
00556 //     setDefinition(0);
00557 //   }
00558 }
00559 
00560 bool Declaration::isFinal() const
00561 {
00562   return d_func()->m_isFinal;
00563 }
00564 
00565 void Declaration::setFinal(bool final)
00566 {
00567   d_func_dynamic()->m_isFinal = final;
00568 }
00569 
00571 bool Declaration::isTypeAlias() const {
00572   DUCHAIN_D(Declaration);
00573   return d->m_isTypeAlias;
00574 }
00575 
00576 void Declaration::setIsTypeAlias(bool isTypeAlias) {
00577   DUCHAIN_D_DYNAMIC(Declaration);
00578   d->m_isTypeAlias = isTypeAlias;
00579 }
00580 
00581 IndexedInstantiationInformation Declaration::specialization() const {
00582   return IndexedInstantiationInformation();
00583 }
00584 
00585 void Declaration::activateSpecialization()
00586 {
00587   if(specialization().index()) {
00588     DeclarationId baseId(id());
00589     baseId.setSpecialization(IndexedInstantiationInformation());
00590     SpecializationStore::self().set(baseId, specialization());
00591   }
00592 }
00593 
00594 DeclarationId Declaration::id(bool forceDirect) const
00595 {
00596   ENSURE_CAN_READ
00597   if(inSymbolTable() && !forceDirect)
00598     return DeclarationId(qualifiedIdentifier(), additionalIdentity(), specialization());
00599   else
00600     return DeclarationId(IndexedDeclaration(const_cast<Declaration*>(this)), specialization());
00601 }
00602 
00603 bool Declaration::inSymbolTable() const
00604 {
00605   DUCHAIN_D(Declaration);
00606   return d->m_inSymbolTable;
00607 }
00608 
00609 CodeModelItem::Kind kindForDeclaration(Declaration* decl) {
00610   CodeModelItem::Kind kind = CodeModelItem::Unknown;
00611 
00612   if(decl->kind() == Declaration::Namespace)
00613     return CodeModelItem::Namespace;
00614 
00615   if(decl->isFunctionDeclaration()) {
00616     kind = CodeModelItem::Function;
00617   }
00618 
00619   if(decl->kind() == Declaration::Type && decl->type<StructureType>())
00620     kind = CodeModelItem::Class;
00621 
00622   if(kind == CodeModelItem::Unknown && decl->kind() == Declaration::Instance)
00623     kind = CodeModelItem::Variable;
00624 
00625   if(decl->isForwardDeclaration())
00626     kind = (CodeModelItem::Kind)(kind | CodeModelItem::ForwardDeclaration);
00627 
00628   return kind;
00629 }
00630 
00631 void Declaration::updateCodeModel()
00632 {
00633   DUCHAIN_D(Declaration);
00634   if(!d->m_identifier.isEmpty() && d->m_inSymbolTable) {
00635     QualifiedIdentifier id(qualifiedIdentifier());
00636     CodeModel::self().updateItem(url(), id, kindForDeclaration(this));
00637   }
00638 }
00639 
00640 void Declaration::setInSymbolTable(bool inSymbolTable)
00641 {
00642   DUCHAIN_D_DYNAMIC(Declaration);
00643   if(!d->m_identifier.isEmpty()) {
00644     if(!d->m_inSymbolTable && inSymbolTable) {
00645       QualifiedIdentifier id(qualifiedIdentifier());
00646       PersistentSymbolTable::self().addDeclaration(id, this);
00647 
00648       CodeModel::self().addItem(url(), id, kindForDeclaration(this));
00649     }
00650 
00651     else if(d->m_inSymbolTable && !inSymbolTable) {
00652       QualifiedIdentifier id(qualifiedIdentifier());
00653       PersistentSymbolTable::self().removeDeclaration(id, this);
00654 
00655       CodeModel::self().removeItem(url(), id);
00656     }
00657   }
00658   d->m_inSymbolTable = inSymbolTable;
00659 }
00660 
00661 ForwardDeclaration* Declaration::toForwardDeclaration()
00662 {
00663   return static_cast<ForwardDeclaration*>(this);
00664 }
00665 
00666 const ForwardDeclaration* Declaration::toForwardDeclaration() const
00667 {
00668   return static_cast<const ForwardDeclaration*>(this);
00669 }
00670 
00671 TopDUContext * Declaration::topContext() const
00672 {
00673   return m_topContext;
00674 }
00675 
00676 Declaration* Declaration::clonePrivate() const  {
00677   return new Declaration(*this);
00678 }
00679 
00680 Declaration* Declaration::clone() const  {
00681   Declaration* ret = clonePrivate();
00682   ret->d_func_dynamic()->m_inSymbolTable = false;
00683   return ret;
00684 }
00685 
00686 bool Declaration::isForwardDeclaration() const
00687 {
00688   return false;
00689 }
00690 
00691 bool Declaration::isFunctionDeclaration() const
00692 {
00693   return false;
00694 }
00695 
00696 uint Declaration::additionalIdentity() const
00697 {
00698   return 0;
00699 }
00700 
00701 bool Declaration::equalQualifiedIdentifier(const Declaration* rhs) const {
00702   ENSURE_CAN_READ
00703   DUCHAIN_D(Declaration);
00704   if(d->m_identifier != rhs->d_func()->m_identifier)
00705     return false;
00706 
00707   return m_context->equalScopeIdentifier(m_context);
00708 }
00709 
00710 QList<KTextEditor::SmartRange*> Declaration::smartUses() const
00711 {
00712   Q_ASSERT(topContext());
00713   ENSURE_CAN_READ
00714   QSet<KTextEditor::SmartRange*> tempUses;
00715   //First, search for uses within the own context
00716   {
00717     foreach(KTextEditor::SmartRange* range, allSmartUses(topContext(), const_cast<Declaration*>(this)))
00718       tempUses.insert(range);
00719   }
00720 
00721   KDevVarLengthArray<IndexedTopDUContext> useContexts = DUChain::uses()->uses(id());
00722 
00723   FOREACH_ARRAY(IndexedTopDUContext indexedContext, useContexts) {
00724     if(!indexedContext.isLoaded())
00725       continue;
00726     TopDUContext* context = indexedContext.data();
00727     if(context) {
00728       foreach(KTextEditor::SmartRange* range, allSmartUses(context, const_cast<Declaration*>(this)))
00729         tempUses.insert(range);
00730     }
00731   }
00732 
00733   return tempUses.toList();
00734 }
00735 
00736 QMap<IndexedString, QList<SimpleRange> > Declaration::uses() const
00737 {
00738   ENSURE_CAN_READ
00739   QMap<IndexedString, QMap<SimpleRange, bool> > tempUses;
00740 
00741   //First, search for uses within the own context
00742   {
00743     QMap<SimpleRange, bool>& ranges(tempUses[topContext()->url()]);
00744     foreach(const SimpleRange& range, allUses(topContext(), const_cast<Declaration*>(this)))
00745       ranges[range] = true;
00746   }
00747 
00748   KDevVarLengthArray<IndexedTopDUContext> useContexts = DUChain::uses()->uses(id());
00749 
00750   FOREACH_ARRAY(IndexedTopDUContext indexedContext, useContexts) {
00751     TopDUContext* context = indexedContext.data();
00752     if(context) {
00753       QMap<SimpleRange, bool>& ranges(tempUses[context->url()]);
00754       foreach(const SimpleRange& range, allUses(context, const_cast<Declaration*>(this)))
00755         ranges[range] = true;
00756     }
00757   }
00758 
00759   QMap<IndexedString, QList<SimpleRange> > ret;
00760 
00761   for(QMap<IndexedString, QMap<SimpleRange, bool> >::const_iterator it = tempUses.constBegin(); it != tempUses.constEnd(); ++it) {
00762     if(!(*it).isEmpty()) {
00763       QList<SimpleRange>& list(ret[it.key()]);
00764       for(QMap<SimpleRange, bool>::const_iterator it2 = (*it).constBegin(); it2 != (*it).constEnd(); ++it2)
00765         list << it2.key();
00766     }
00767   }
00768   return ret;
00769 }
00770 
00771 }
00772 
00773 // kate: space-indent on; indent-width 2; tab-width 4; replace-tabs on; auto-insert-doxygen on
00774 
00775 

language/duchain

Skip menu "language/duchain"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDevelop Platform Libraries

Skip menu "KDevelop Platform Libraries"
  • interfaces
  • language
  •   codegen
  •   duchain
  •   editor
  • outputview
  • project
  • shell
  • sublime
  • util
  • vcs
Generated for KDevelop Platform Libraries by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal