• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdevelop API Reference
  • KDE Home
  • Contact Us
 

kdevplatform/language/duchain

  • sources
  • kfour-appscomplete
  • kdevelop
  • kdevplatform
  • language
  • duchain
declaration.cpp
Go to the documentation of this file.
1 /* This file is part of KDevelop
2  Copyright 2006 Hamish Rodda <[email protected]>
3  Copyright 2007 2008 David Nolden <[email protected]>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18  */
19 
20 #include "declaration.h"
21 #include "declarationdata.h"
22 
23 #include <QByteArray>
24 
25 #include <limits>
26 
27 #include "topducontext.h"
28 #include "topducontextdynamicdata.h"
29 #include "use.h"
30 #include "forwarddeclaration.h"
31 #include "duchain.h"
32 #include "duchainlock.h"
33 #include "ducontextdata.h"
34 #include "declarationid.h"
35 #include "uses.h"
36 #include <serialization/indexedstring.h>
37 #include "duchainregister.h"
38 #include "persistentsymboltable.h"
39 #include "types/identifiedtype.h"
40 #include "types/structuretype.h"
41 #include "functiondefinition.h"
42 #include "codemodel.h"
43 #include "specializationstore.h"
44 #include "types/typeutils.h"
45 #include "types/typealiastype.h"
46 #include "classdeclaration.h"
47 #include "serialization/stringrepository.h"
48 #include "ducontextdynamicdata.h"
49 
50 namespace KDevelop {
51 REGISTER_DUCHAIN_ITEM(Declaration);
52 
53 DeclarationData::DeclarationData()
54  : m_isDefinition(false)
55  , m_inSymbolTable(false)
56  , m_isTypeAlias(false)
57  , m_anonymousInContext(false)
58  , m_isDeprecated(false)
59  , m_alwaysForceDirect(false)
60  , m_isAutoDeclaration(false)
61  , m_isExplicitlyDeleted(false)
62  , m_isExplicitlyTyped(false)
63 {
64 }
65 
67 static Repositories::StringRepository& commentRepository()
68 {
69  static Repositories::StringRepository commentRepositoryObject(QStringLiteral("Comment Repository"));
70  return commentRepositoryObject;
71 }
72 
73 void initDeclarationRepositories()
74 {
75  commentRepository();
76 }
77 
78 Declaration::Kind Declaration::kind() const
79 {
80  DUCHAIN_D(Declaration);
81  return d->m_kind;
82 }
83 
84 void Declaration::setKind(Kind kind)
85 {
86  DUCHAIN_D_DYNAMIC(Declaration);
87  d->m_kind = kind;
88  updateCodeModel();
89 }
90 
91 bool Declaration::inDUChain() const
92 {
93  DUCHAIN_D(Declaration);
94  if (d->m_anonymousInContext)
95  return false;
96  if (!context())
97  return false;
98  TopDUContext* top = topContext();
99  return top && top->inDUChain();
100 }
101 
102 Declaration::Declaration(const RangeInRevision& range, DUContext* context)
103  : DUChainBase(*new DeclarationData, range)
104 {
105  d_func_dynamic()->setClassId(this);
106  m_topContext = nullptr;
107  m_context = nullptr;
108  m_indexInTopContext = 0;
109 
110  if (context)
111  setContext(context);
112 }
113 
114 uint Declaration::ownIndex() const
115 {
116  ENSURE_CAN_READ
117  return m_indexInTopContext;
118 }
119 
120 Declaration::Declaration(const Declaration& rhs)
121  : DUChainBase(*new DeclarationData(*rhs.d_func()))
122 {
123 }
124 
125 Declaration::Declaration(DeclarationData& dd) : DUChainBase(dd)
126 {
127 }
128 
129 Declaration::Declaration(DeclarationData& dd, const RangeInRevision& range)
130  : DUChainBase(dd, range)
131 {
132 }
133 
134 bool Declaration::persistentlyDestroying() const
135 {
136  TopDUContext* topContext = this->topContext();
137  return !topContext->deleting() || !topContext->isOnDisk();
138 }
139 
140 Declaration::~Declaration()
141 {
142  uint oldOwnIndex = m_indexInTopContext;
143 
144  TopDUContext* topContext = this->topContext();
145 
146  //Only perform the actions when the top-context isn't being deleted, or when it hasn't been stored to disk
147  if (persistentlyDestroying()) {
148  DUCHAIN_D_DYNAMIC(Declaration);
149 
150  // Inserted by the builder after construction has finished.
151  if (d->m_internalContext.context())
152  d->m_internalContext.context()->setOwner(nullptr);
153 
154  setInSymbolTable(false);
155  }
156 
157  // If the parent-context already has dynamic data, like for example any temporary context,
158  // always delete the declaration, to not create crashes within more complex code like C++ template stuff.
159  if (context() && !d_func()->m_anonymousInContext) {
160  if (!topContext->deleting() || !topContext->isOnDisk() || context()->d_func()->isDynamic())
161  context()->m_dynamicData->removeDeclaration(this);
162  }
163 
164  clearOwnIndex();
165 
166  if (!topContext->deleting() || !topContext->isOnDisk()) {
167  setContext(nullptr);
168 
169  setAbstractType(AbstractType::Ptr());
170  }
171  Q_ASSERT(d_func()->isDynamic() ==
172  (!topContext->deleting() || !topContext->isOnDisk() ||
173  topContext->m_dynamicData->isTemporaryDeclarationIndex(oldOwnIndex)));
174  Q_UNUSED(oldOwnIndex);
175 }
176 
177 QByteArray Declaration::comment() const
178 {
179  DUCHAIN_D(Declaration);
180  if (!d->m_comment)
181  return nullptr;
182  else
183  return Repositories::arrayFromItem(commentRepository().itemFromIndex(d->m_comment));
184 }
185 
186 void Declaration::setComment(const QByteArray& str)
187 {
188  DUCHAIN_D_DYNAMIC(Declaration);
189  if (str.isEmpty())
190  d->m_comment = 0;
191  else
192  d->m_comment =
193  commentRepository().index(Repositories::StringRepositoryItemRequest(str.constData(),
194  IndexedString::hashString(str.constData(),
195  str.length()),
196  str.length()));
197 }
198 
199 void Declaration::setComment(const QString& str)
200 {
201  setComment(str.toUtf8());
202 }
203 
204 Identifier Declaration::identifier() const
205 {
206  //ENSURE_CAN_READ Commented out for performance reasons
207  return d_func()->m_identifier.identifier();
208 }
209 
210 const IndexedIdentifier& Declaration::indexedIdentifier() const
211 {
212  //ENSURE_CAN_READ Commented out for performance reasons
213  return d_func()->m_identifier;
214 }
215 
216 void Declaration::rebuildDynamicData(DUContext* parent, uint ownIndex)
217 {
218  DUChainBase::rebuildDynamicData(parent, ownIndex);
219 
220  m_context = parent;
221  m_topContext = parent->topContext();
222  m_indexInTopContext = ownIndex;
223 }
224 
225 void Declaration::setIdentifier(const Identifier& identifier)
226 {
227  ENSURE_CAN_WRITE
228  DUCHAIN_D_DYNAMIC(Declaration);
229  bool wasInSymbolTable = d->m_inSymbolTable;
230 
231  setInSymbolTable(false);
232 
233  d->m_identifier = identifier;
234 
235  setInSymbolTable(wasInSymbolTable);
236 }
237 
238 IndexedType Declaration::indexedType() const
239 {
240  return d_func()->m_type;
241 }
242 
243 AbstractType::Ptr Declaration::abstractType() const
244 {
245  //ENSURE_CAN_READ Commented out for performance reasons
246  return d_func()->m_type.abstractType();
247 }
248 
249 void Declaration::setAbstractType(AbstractType::Ptr type)
250 {
251  ENSURE_CAN_WRITE
252  DUCHAIN_D_DYNAMIC(Declaration);
253 
254  d->m_type = type ? type->indexed() : IndexedType();
255 
256  updateCodeModel();
257 }
258 
259 Declaration* Declaration::specialize(const IndexedInstantiationInformation& /*specialization*/,
260  const TopDUContext* topContext, int /*upDistance*/)
261 {
262  if (!topContext)
263  return nullptr;
264  return this;
265 }
266 
267 QualifiedIdentifier Declaration::qualifiedIdentifier() const
268 {
269  ENSURE_CAN_READ
270 
271  QualifiedIdentifier ret;
272  DUContext* ctx = m_context;
273  if (ctx)
274  ret = ctx->scopeIdentifier(true);
275  ret.push(d_func()->m_identifier);
276  return ret;
277 }
278 
279 DUContext* Declaration::context() const
280 {
281  //ENSURE_CAN_READ Commented out for performance reasons
282  return m_context;
283 }
284 
285 bool Declaration::isAnonymous() const
286 {
287  return d_func()->m_anonymousInContext;
288 }
289 
290 void Declaration::setContext(DUContext* context, bool anonymous)
291 {
292  Q_ASSERT(!context || context->topContext());
293 
294  DUCHAIN_D_DYNAMIC(Declaration);
295 
296  if (context == m_context && anonymous == d->m_anonymousInContext) {
297  // skip costly operations below when the same context is set
298  // this happens often when updating a TopDUContext from the cache
299  return;
300  }
301 
302  setInSymbolTable(false);
303 
304  //We don't need to clear, because it's not allowed to move from one top-context into another
305 // clearOwnIndex();
306 
307  if (m_context && context) {
308  Q_ASSERT(m_context->topContext() == context->topContext());
309  }
310 
311  if (m_context) {
312  if (!d->m_anonymousInContext) {
313  m_context->m_dynamicData->removeDeclaration(this);
314  }
315  }
316 
317  if (context)
318  m_topContext = context->topContext();
319  else
320  m_topContext = nullptr;
321 
322  d->m_anonymousInContext = anonymous;
323  m_context = context;
324 
325  if (context) {
326  if (!m_indexInTopContext)
327  allocateOwnIndex();
328 
329  if (!d->m_anonymousInContext) {
330  context->m_dynamicData->addDeclaration(this);
331  }
332 
333  if (context->inSymbolTable() && !anonymous)
334  setInSymbolTable(true);
335  }
336 }
337 
338 void Declaration::clearOwnIndex()
339 {
340  if (!m_indexInTopContext)
341  return;
342 
343  if (!context() || (!d_func()->m_anonymousInContext && !context()->isAnonymous())) {
344  ENSURE_CAN_WRITE
345  }
346 
347  if (m_indexInTopContext) {
348  Q_ASSERT(m_topContext);
349  m_topContext->m_dynamicData->clearDeclarationIndex(this);
350  }
351  m_indexInTopContext = 0;
352 }
353 
354 void Declaration::allocateOwnIndex()
355 {
357 // if(context() && (!context()->isAnonymous() && !d_func()->m_anonymousInContext)) {
358 // ENSURE_CAN_WRITE
359 // }
360 
361  Q_ASSERT(m_topContext);
362 
363  m_indexInTopContext = m_topContext->m_dynamicData->allocateDeclarationIndex(this,
364  d_func()->m_anonymousInContext || !context() ||
365  context()->isAnonymous());
366  Q_ASSERT(m_indexInTopContext);
367 
368  if (!m_topContext->m_dynamicData->declarationForIndex(m_indexInTopContext))
369  qFatal("Could not re-retrieve declaration\nindex: %d", m_indexInTopContext);
370 }
371 
372 const Declaration* Declaration::logicalDeclaration(const TopDUContext* topContext) const
373 {
374  ENSURE_CAN_READ
375  if (isForwardDeclaration()) {
376  const auto dec = static_cast<const ForwardDeclaration*>(this);
377  Declaration* ret = dec->resolve(topContext);
378  if (ret)
379  return ret;
380  }
381  return this;
382 }
383 
384 Declaration* Declaration::logicalDeclaration(const TopDUContext* topContext)
385 {
386  ENSURE_CAN_READ
387  if (isForwardDeclaration()) {
388  const auto dec = static_cast<const ForwardDeclaration*>(this);
389  Declaration* ret = dec->resolve(topContext);
390  if (ret)
391  return ret;
392  }
393  return this;
394 }
395 
396 DUContext* Declaration::logicalInternalContext(const TopDUContext* topContext) const
397 {
398  ENSURE_CAN_READ
399 
400  if (!isDefinition()) {
401  Declaration* def = FunctionDefinition::definition(this);
402  if (def)
403  return def->internalContext();
404  }
405 
406  if (d_func()->m_isTypeAlias) {
408  TypeAliasType::Ptr t = type<TypeAliasType>();
409  if (t) {
410  AbstractType::Ptr target = t->type();
411 
412  auto* idType = dynamic_cast<IdentifiedType*>(target.data());
413  if (idType) {
414  Declaration* decl = idType->declaration(topContext);
415  if (decl && decl != this) {
416  return decl->logicalInternalContext(topContext);
417  }
418  }
419  }
420  }
421 
422  return internalContext();
423 }
424 
425 DUContext* Declaration::internalContext() const
426 {
427 // ENSURE_CAN_READ
428  return d_func()->m_internalContext.context();
429 }
430 
431 void Declaration::setInternalContext(DUContext* context)
432 {
433  if (this->context()) {
434  ENSURE_CAN_WRITE
435  }
436  DUCHAIN_D_DYNAMIC(Declaration);
437 
438  if (context == d->m_internalContext.context())
439  return;
440 
441  if (!m_topContext) {
442  //Take the top-context from the other side. We need to allocate an index, so we can safely call setOwner(..)
443  m_topContext = context->topContext();
444  allocateOwnIndex();
445  }
446 
447  DUContext* oldInternalContext = d->m_internalContext.context();
448 
449  d->m_internalContext = context;
450 
451  //Q_ASSERT( !oldInternalContext || oldInternalContext->owner() == this );
452  if (oldInternalContext && oldInternalContext->owner() == this)
453  oldInternalContext->setOwner(nullptr);
454 
455  if (context)
456  context->setOwner(this);
457 }
458 
459 bool Declaration::operator ==(const Declaration& other) const
460 {
461  ENSURE_CAN_READ
462 
463  return this == &other;
464 }
465 
466 QString Declaration::toString() const
467 {
468  return QStringLiteral("%3 %4").arg(abstractType() ? abstractType()->toString() : QStringLiteral(
469  "<notype>"), identifier().toString());
470 }
471 
472 bool Declaration::isDefinition() const
473 {
474  ENSURE_CAN_READ
475  DUCHAIN_D(Declaration);
476 
477  return d->m_isDefinition;
478 }
479 
480 void Declaration::setDeclarationIsDefinition(bool dd)
481 {
482  ENSURE_CAN_WRITE
483  DUCHAIN_D_DYNAMIC(Declaration);
484  d->m_isDefinition = dd;
485 }
486 
487 bool Declaration::isAutoDeclaration() const
488 {
489  return d_func()->m_isAutoDeclaration;
490 }
491 
492 void Declaration::setAutoDeclaration(bool _auto)
493 {
494  d_func_dynamic()->m_isAutoDeclaration = _auto;
495 }
496 
497 bool Declaration::isDeprecated() const
498 {
499  return d_func()->m_isDeprecated;
500 }
501 
502 void Declaration::setDeprecated(bool deprecated)
503 {
504  d_func_dynamic()->m_isDeprecated = deprecated;
505 }
506 
507 bool Declaration::alwaysForceDirect() const
508 {
509  return d_func()->m_alwaysForceDirect;
510 }
511 
512 void Declaration::setAlwaysForceDirect(bool direct)
513 {
514  d_func_dynamic()->m_alwaysForceDirect = direct;
515 }
516 
517 bool Declaration::isExplicitlyDeleted() const
518 {
519  return d_func()->m_isExplicitlyDeleted;
520 }
521 
522 void Declaration::setExplicitlyDeleted(bool deleted)
523 {
524  d_func_dynamic()->m_isExplicitlyDeleted = deleted;
525 }
526 
527 bool Declaration::isExplicitlyTyped() const
528 {
529  return d_func()->m_isExplicitlyTyped;
530 }
531 
532 void Declaration::setExplicitlyTyped(bool explicitlyTyped)
533 {
534  d_func_dynamic()->m_isExplicitlyTyped = explicitlyTyped;
535 }
536 
538 bool Declaration::isTypeAlias() const
539 {
540  DUCHAIN_D(Declaration);
541  return d->m_isTypeAlias;
542 }
543 
544 void Declaration::setIsTypeAlias(bool isTypeAlias)
545 {
546  DUCHAIN_D_DYNAMIC(Declaration);
547  d->m_isTypeAlias = isTypeAlias;
548 }
549 
550 IndexedInstantiationInformation Declaration::specialization() const
551 {
552  return IndexedInstantiationInformation();
553 }
554 
555 void Declaration::activateSpecialization()
556 {
557  if (specialization().index()) {
558  DeclarationId baseId(id());
559  baseId.setSpecialization(IndexedInstantiationInformation());
560  SpecializationStore::self().set(baseId, specialization());
561  }
562 }
563 
564 DeclarationId Declaration::id(bool forceDirect) const
565 {
566  ENSURE_CAN_READ
567  if (inSymbolTable() && !forceDirect && !alwaysForceDirect())
568  return DeclarationId(qualifiedIdentifier(), additionalIdentity(), specialization());
569  else
570  return DeclarationId(IndexedDeclaration(const_cast<Declaration*>(this)), specialization());
571 }
572 
573 bool Declaration::inSymbolTable() const
574 {
575  DUCHAIN_D(Declaration);
576  return d->m_inSymbolTable;
577 }
578 
579 CodeModelItem::Kind kindForDeclaration(Declaration* decl)
580 {
581  CodeModelItem::Kind kind = CodeModelItem::Unknown;
582 
583  if (decl->kind() == Declaration::Namespace)
584  return CodeModelItem::Namespace;
585 
586  if (decl->isFunctionDeclaration()) {
587  kind = CodeModelItem::Function;
588  }
589 
590  if (decl->kind() == Declaration::Type && (decl->type<StructureType>() || dynamic_cast<ClassDeclaration*>(decl)))
591  kind = CodeModelItem::Class;
592 
593  if (kind == CodeModelItem::Unknown && decl->kind() == Declaration::Instance)
594  kind = CodeModelItem::Variable;
595 
596  if (decl->isForwardDeclaration())
597  kind = ( CodeModelItem::Kind )(kind | CodeModelItem::ForwardDeclaration);
598 
599  if (decl->context() && decl->context()->type() == DUContext::Class)
600  kind = ( CodeModelItem::Kind )(kind | CodeModelItem::ClassMember);
601 
602  return kind;
603 }
604 
605 void Declaration::updateCodeModel()
606 {
607  DUCHAIN_D(Declaration);
608  if (!d->m_identifier.isEmpty() && d->m_inSymbolTable) {
609  QualifiedIdentifier id(qualifiedIdentifier());
610  CodeModel::self().updateItem(url(), id, kindForDeclaration(this));
611  }
612 }
613 
614 void Declaration::setInSymbolTable(bool inSymbolTable)
615 {
616  DUCHAIN_D_DYNAMIC(Declaration);
617  if (!d->m_identifier.isEmpty()) {
618  if (!d->m_inSymbolTable && inSymbolTable) {
619  QualifiedIdentifier id(qualifiedIdentifier());
620  PersistentSymbolTable::self().addDeclaration(id, this);
621 
622  CodeModel::self().addItem(url(), id, kindForDeclaration(this));
623  } else if (d->m_inSymbolTable && !inSymbolTable) {
624  QualifiedIdentifier id(qualifiedIdentifier());
625  PersistentSymbolTable::self().removeDeclaration(id, this);
626 
627  CodeModel::self().removeItem(url(), id);
628  }
629  }
630  d->m_inSymbolTable = inSymbolTable;
631 }
632 
633 TopDUContext* Declaration::topContext() const
634 {
635  return m_topContext;
636 }
637 
638 Declaration* Declaration::clonePrivate() const
639 {
640  return new Declaration(*this);
641 }
642 
643 Declaration* Declaration::clone() const
644 {
645  Declaration* ret = clonePrivate();
646  ret->d_func_dynamic()->m_inSymbolTable = false;
647  return ret;
648 }
649 
650 bool Declaration::isForwardDeclaration() const
651 {
652  return false;
653 }
654 
655 bool Declaration::isFunctionDeclaration() const
656 {
657  return false;
658 }
659 
660 uint Declaration::additionalIdentity() const
661 {
662  return 0;
663 }
664 
665 bool Declaration::equalQualifiedIdentifier(const Declaration* rhs) const
666 {
667  ENSURE_CAN_READ
668  DUCHAIN_D(Declaration);
669  if (d->m_identifier != rhs->d_func()->m_identifier)
670  return false;
671 
672  return m_context->equalScopeIdentifier(m_context);
673 }
674 
675 QMap<IndexedString, QVector<RangeInRevision>> Declaration::uses() const
676 {
677  ENSURE_CAN_READ
678  QMap<IndexedString, QMap<RangeInRevision, bool>> tempUses;
679 
680  //First, search for uses within the own context
681  {
682  QMap<RangeInRevision, bool>& ranges(tempUses[topContext()->url()]);
683  const auto useRanges = allUses(topContext(), const_cast<Declaration*>(this));
684  for (const RangeInRevision range : useRanges) {
685  ranges[range] = true;
686  }
687  }
688 
689  DeclarationId _id = id();
690  KDevVarLengthArray<IndexedTopDUContext> useContexts = DUChain::uses()->uses(_id);
691  if (!_id.isDirect()) { // also check uses based on direct IDs
692  KDevVarLengthArray<IndexedTopDUContext> directUseContexts = DUChain::uses()->uses(id(true));
693  useContexts.append(directUseContexts.data(), directUseContexts.size());
694  }
695 
696  for (const IndexedTopDUContext indexedContext : qAsConst(useContexts)) {
697  TopDUContext* context = indexedContext.data();
698  if (context) {
699  QMap<RangeInRevision, bool>& ranges(tempUses[context->url()]);
700  const auto useRanges = allUses(context, const_cast<Declaration*>(this));
701  for (const RangeInRevision range : useRanges) {
702  ranges[range] = true;
703  }
704  }
705  }
706 
707  QMap<IndexedString, QVector<RangeInRevision>> ret;
708 
709  for (QMap<IndexedString, QMap<RangeInRevision, bool>>::const_iterator it = tempUses.constBegin();
710  it != tempUses.constEnd(); ++it) {
711  if (!(*it).isEmpty()) {
712  auto& list = ret[it.key()];
713  list.reserve((*it).size());
714  for (QMap<RangeInRevision, bool>::const_iterator it2 = (*it).constBegin(); it2 != (*it).constEnd(); ++it2)
715  list << it2.key();
716  }
717  }
718 
719  return ret;
720 }
721 
722 bool hasDeclarationUse(DUContext* context, int declIdx)
723 {
724  bool ret = false;
725  int usescount = context->usesCount();
726  const Use* uses = context->uses();
727 
728  for (int i = 0; !ret && i < usescount; ++i) {
729  ret = uses[i].m_declarationIndex == declIdx;
730  }
731 
732  const auto childContexts = context->childContexts();
733  for (DUContext* child : childContexts) {
734  ret = ret || hasDeclarationUse(child, declIdx);
735  if (ret)
736  break;
737  }
738 
739  return ret;
740 }
741 
742 bool Declaration::hasUses() const
743 {
744  ENSURE_CAN_READ
745  int idx = topContext()->indexForUsedDeclaration(const_cast<Declaration*>(this), false);
746  bool ret = idx != std::numeric_limits<int>::max() && (idx >= 0 || hasDeclarationUse(topContext(), idx)); //hasLocalUses
747  DeclarationId myId = id();
748 
749  if (!ret && DUChain::uses()->hasUses(myId)) {
750  ret = true;
751  }
752 
753  if (!ret && !myId.isDirect() && DUChain::uses()->hasUses(id(true))) {
754  ret = true;
755  }
756 
757  return ret;
758 }
759 
760 QMap<IndexedString, QVector<KTextEditor::Range>> Declaration::usesCurrentRevision() const
761 {
762  ENSURE_CAN_READ
763  QMap<IndexedString, QMap<KTextEditor::Range, bool>> tempUses;
764 
765  //First, search for uses within the own context
766  {
767  QMap<KTextEditor::Range, bool>& ranges(tempUses[topContext()->url()]);
768  const auto useRanges = allUses(topContext(), const_cast<Declaration*>(this));
769  for (const RangeInRevision range : useRanges) {
770  ranges[topContext()->transformFromLocalRevision(range)] = true;
771  }
772  }
773 
774  DeclarationId _id = id();
775  KDevVarLengthArray<IndexedTopDUContext> useContexts = DUChain::uses()->uses(_id);
776  if (!_id.isDirect()) { // also check uses based on direct IDs
777  KDevVarLengthArray<IndexedTopDUContext> directUseContexts = DUChain::uses()->uses(id(true));
778  useContexts.append(directUseContexts.data(), directUseContexts.size());
779  }
780 
781  for (const IndexedTopDUContext indexedContext : qAsConst(useContexts)) {
782  TopDUContext* context = indexedContext.data();
783  if (context) {
784  QMap<KTextEditor::Range, bool>& ranges(tempUses[context->url()]);
785  const auto useRanges = allUses(context, const_cast<Declaration*>(this));
786  for (const RangeInRevision range : useRanges) {
787  ranges[context->transformFromLocalRevision(range)] = true;
788  }
789  }
790  }
791 
792  QMap<IndexedString, QVector<KTextEditor::Range>> ret;
793 
794  for (QMap<IndexedString, QMap<KTextEditor::Range, bool>>::const_iterator it = tempUses.constBegin();
795  it != tempUses.constEnd(); ++it) {
796  if (!(*it).isEmpty()) {
797  auto& list = ret[it.key()];
798  list.reserve((*it).size());
799  for (QMap<KTextEditor::Range, bool>::const_iterator it2 = (*it).constBegin(); it2 != (*it).constEnd();
800  ++it2)
801  list << it2.key();
802  }
803  }
804 
805  return ret;
806 }
807 }
duchainlock.h
KDevelop::IndexedTopDUContext
Allows simple indirect access to top-contexts with on-demand loading.
Definition: indexedtopducontext.h:35
QMap::constBegin
const_iterator constBegin() const
KDevelop::CodeModel::addItem
void addItem(const IndexedString &file, const IndexedQualifiedIdentifier &id, CodeModelItem::Kind kind)
There can only be one item for each identifier.
Definition: codemodel.cpp:196
KDevelop::DUContext::inSymbolTable
bool inSymbolTable() const
Returns whether this context is listed in the symbol table (Namespaces and classes)
Definition: ducontext.cpp:1448
KDevelop::Declaration::isDeprecated
bool isDeprecated() const
Determine whether the declaration is deprecated.
Definition: declaration.cpp:497
KDevelop::CodeModelItem::Class
Definition: codemodel.h:45
KDevelop::PersistentSymbolTable::self
static PersistentSymbolTable & self()
Definition: persistentsymboltable.cpp:494
KDevelop::Declaration::usesCurrentRevision
QMap< IndexedString, QVector< KTextEditor::Range > > usesCurrentRevision() const
Returns a map of files to use-ranges.
Definition: declaration.cpp:760
KDevelop::CodeModelItem::Variable
Definition: codemodel.h:44
KDevelop::DeclarationId::setSpecialization
void setSpecialization(const IndexedInstantiationInformation &spec)
Set the specialization index (see class documentation).
Definition: declarationid.cpp:87
KDevelop::DUChainBase
Base class for definition-use chain objects.
Definition: duchainbase.h:131
KDevelop::TopDUContext::indexForUsedDeclaration
int indexForUsedDeclaration(Declaration *declaration, bool create=true)
Retrieves or creates a local index that is to be used for referencing the given.
Definition: topducontext.cpp:1159
KDevelop::Declaration::Type
A type is declared, like a class-declaration or function-declaration, or a typedef("class MyClass {};...
Definition: declaration.h:64
KDevelop::REGISTER_DUCHAIN_ITEM
REGISTER_DUCHAIN_ITEM(AliasDeclaration)
KDevelop::Declaration::indexedIdentifier
const IndexedIdentifier & indexedIdentifier() const
Access this declaration's identifier.
Definition: declaration.cpp:210
ducontextdynamicdata.h
KDevelop::Declaration::Namespace
Declaration of a namespace.
Definition: declaration.h:68
KDevelop::Declaration::clearOwnIndex
void clearOwnIndex()
Clear the index for this declaration in the top context that was allocated with allocateOwnIndex().
Definition: declaration.cpp:338
KDevelop::initDeclarationRepositories
void initDeclarationRepositories()
Definition: declaration.cpp:73
KDevelop::Declaration::setContext
void setContext(DUContext *context, bool anonymous=false)
Set the context in which this declaration occurs.
Definition: declaration.cpp:290
KDevelop::commentRepository
static Repositories::StringRepository & commentRepository()
Definition: declaration.cpp:67
QExplicitlySharedDataPointer::data
T * data() const
KDevelop::Declaration::isAutoDeclaration
bool isAutoDeclaration() const
Determine whether this declaration is implicitly created or not.
Definition: declaration.cpp:487
KDevelop::Use::m_declarationIndex
int m_declarationIndex
Definition: use.h:61
KDevelop::SpecializationStore::self
static SpecializationStore & self()
Definition: specializationstore.cpp:33
KDevelop::Declaration::logicalDeclaration
const Declaration * logicalDeclaration(const TopDUContext *topContext) const
This is a convenience function to determine the resolved declaration, if this is a forward declaratio...
Definition: declaration.cpp:372
KDevelop::Declaration::isFunctionDeclaration
virtual bool isFunctionDeclaration() const
Determine whether this declaration is a function declaration.
Definition: declaration.cpp:655
KDevelop::DUChainBase::transformFromLocalRevision
KTextEditor::Cursor transformFromLocalRevision(const CursorInRevision &cursor) const
KDevelop::IndexedIdentifier
A helper-class to store an identifier by index in a type-safe way.
Definition: identifier.h:55
KDevelop::DeclarationId::isDirect
bool isDirect() const
Determine whether this DeclarationId directly references a Declaration by indices,...
Definition: declarationid.cpp:82
KDevelop::Declaration::identifier
Identifier identifier() const
Access this declaration's identifier.
Definition: declaration.cpp:204
KDevelop::Declaration::toString
virtual QString toString() const
Determine this declaration as a string.
Definition: declaration.cpp:466
KDevelop::TypePtr< AbstractType >
KDevelop::TopDUContextDynamicData::allocateDeclarationIndex
uint allocateDeclarationIndex(Declaration *decl, bool temporary)
Allocates an index for the given declaration in this top-context.
Definition: topducontextdynamicdata.cpp:801
KDevelop::TopDUContextDynamicData::declarationForIndex
Declaration * declarationForIndex(uint index) const
Definition: topducontextdynamicdata.cpp:848
topducontext.h
KDevelop::Declaration
Represents a single declaration in a definition-use chain.
Definition: declaration.h:51
KDevelop::DUContext::setOwner
void setOwner(Declaration *decl)
Sets the declaration/definition, and also updates it's internal context (they are strictly paired tog...
Definition: ducontext.cpp:492
KDevelop::Declaration::inDUChain
virtual bool inDUChain() const
Determine whether this declaration is accessible through the du-chain.
Definition: declaration.cpp:91
KDevelop::Uses::hasUses
bool hasUses(const DeclarationId &id) const
Checks whether the given DeclarationID is is used.
Definition: uses.cpp:189
forwarddeclaration.h
KDevelop::DUContext::equalScopeIdentifier
bool equalScopeIdentifier(const DUContext *rhs) const
Returns true if this context has the same scope identifier as the given one.
Definition: ducontext.cpp:1092
KDevelop::Declaration::setIsTypeAlias
void setIsTypeAlias(bool typeAlias)
Set whether this declaration is a type alias.
Definition: declaration.cpp:544
KDevelop::Declaration::comment
QByteArray comment() const
Returns the comment associated to this declaration in the source-code, or an invalid string if there ...
Definition: declaration.cpp:177
KDevelop::DUContext::topContext
TopDUContext * topContext() const override
Find the top context.
Definition: ducontext.cpp:1499
typeutils.h
KDevelop::Use
Represents a position in a document where a specific declaration is used.
Definition: use.h:47
KDevelop::Declaration::isTypeAlias
bool isTypeAlias() const
Determine if this declaration is a type-alias (in c++ typedef).
Definition: declaration.cpp:538
KDevelop::Declaration::isAnonymous
bool isAnonymous() const
Whether this declaration has been inserted anonymously into its parent-context.
Definition: declaration.cpp:285
KDevelop::Declaration::isExplicitlyDeleted
bool isExplicitlyDeleted() const
Determine whether this declaration is "explicitly deleted" or not.
Definition: declaration.cpp:517
typealiastype.h
KDevelop::Declaration::IndexedDeclaration
friend class IndexedDeclaration
Definition: declaration.h:580
ENSURE_CAN_WRITE
#define ENSURE_CAN_WRITE
Like the ENSURE_CHAIN_WRITE_LOCKED and .._READ_LOCKED, except that this should be used in items that ...
Definition: duchainlock.h:184
KDevelop::allUses
QVector< RangeInRevision > allUses(DUContext *context, int declarationIndex, bool noEmptyUses)
Collects all uses of the given declarationIndex.
Definition: ducontext.cpp:1519
KDevelop::Declaration::kind
Kind kind() const
Returns the kind of this declaration.
Definition: declaration.cpp:78
KDevelop::DUContextDynamicData::addDeclaration
void addDeclaration(Declaration *declaration)
Definition: ducontext.cpp:204
declaration.h
ducontextdata.h
declarationdata.h
KDevelop::Declaration::indexedType
IndexedType indexedType() const
Return an indexed form of this declaration's type.
Definition: declaration.cpp:238
KDevelop::DeclarationData::DeclarationData
DeclarationData()
Definition: declaration.cpp:53
KDevelop::Declaration::Kind
Kind
Enumeration of the types of declarations.
Definition: declaration.h:63
KDevelop::Identifier::identifier
const IndexedString identifier() const
Definition: identifier.cpp:520
KDevelop::Declaration::equalQualifiedIdentifier
bool equalQualifiedIdentifier(const Declaration *rhs) const
Compares the qualified identifier of this declaration with the other one, without needing to compute ...
Definition: declaration.cpp:665
KDevelop::DUChainBase::url
virtual IndexedString url() const
Definition: duchainbase.cpp:68
QString
KDevelop::Declaration::setDeclarationIsDefinition
void setDeclarationIsDefinition(bool dd)
Set whether this declaration is also a definition.
Definition: declaration.cpp:480
KDevelop::Declaration::Instance
An instance of a type is declared("MyClass m;")
Definition: declaration.h:65
structuretype.h
DUCHAIN_D
#define DUCHAIN_D(Class)
Definition: duchainbase.h:47
KDevelop::DUChainBase::range
RangeInRevision range() const
Returns the range assigned to this object, in the document revision when this document was last parse...
Definition: duchainbase.cpp:152
KDevVarLengthArray
QString::toUtf8
QByteArray toUtf8() const
KDevelop::Declaration::type
TypePtr< T > type() const
Convenience function to return this declaration's type dynamically casted to T.
Definition: declaration.h:305
KDevelop::Declaration::topContext
TopDUContext * topContext() const override
Determine the top context to which this object belongs.
Definition: declaration.cpp:633
KDevelop::TopDUContextDynamicData::clearDeclarationIndex
void clearDeclarationIndex(Declaration *decl)
Definition: topducontextdynamicdata.cpp:864
KDevelop::Declaration::inSymbolTable
bool inSymbolTable() const
Access whether this declaration is in the symbol table.
Definition: declaration.cpp:573
KDevelop::TopDUContext
The top context in a definition-use chain for one source file.
Definition: topducontext.h:113
KDevelop::Declaration::specialization
virtual IndexedInstantiationInformation specialization() const
TODO document.
Definition: declaration.cpp:550
KDevelop::DUChain::uses
static Uses * uses()
Returns the structure that manages mapping between declarations, and which top level contexts contain...
Definition: duchain.cpp:1689
KDevelop::CodeModel::removeItem
void removeItem(const IndexedString &file, const IndexedQualifiedIdentifier &id)
Definition: codemodel.cpp:305
use.h
KDevelop::Declaration::context
DUContext * context() const
Access the parent context of this declaration.
Definition: declaration.cpp:279
KDevelop::Declaration::setAlwaysForceDirect
void setAlwaysForceDirect(bool direct)
Changes whether this declaration must be direct in all cases or not.
Definition: declaration.cpp:512
KDevelop::Declaration::setExplicitlyTyped
void setExplicitlyTyped(bool explicitlyTyped)
Changes whether this declaration is explicitly typed.
Definition: declaration.cpp:532
KDevelop::CodeModel::self
static CodeModel & self()
Definition: codemodel.cpp:392
KDevelop::Uses::uses
KDevVarLengthArray< IndexedTopDUContext > uses(const DeclarationId &id) const
Gets the top-contexts of all users assigned to the declaration-id.
Definition: uses.cpp:198
KDevelop::DeclarationId
Allows clearly identifying a Declaration.
Definition: declarationid.h:50
KDevelop::CodeModelItem::ClassMember
Definition: codemodel.h:48
KDevelop::PersistentSymbolTable::removeDeclaration
void removeDeclaration(const IndexedQualifiedIdentifier &id, const IndexedDeclaration &declaration)
Adds declaration declaration with id id to the symbol table.
Definition: persistentsymboltable.cpp:259
KDevelop::Declaration::setInternalContext
void setInternalContext(DUContext *context)
Set the internal context for this declaration.
Definition: declaration.cpp:431
KDevelop::Identifier
Represents a single unqualified identifier.
Definition: identifier.h:150
KDevelop::DUContext::Class
A context that declares class members.
Definition: ducontext.h:105
QMap::key
const Key key(const T &value) const
KDevelop::TopDUContextDynamicData::isTemporaryDeclarationIndex
bool isTemporaryDeclarationIndex(uint index) const
Definition: topducontextdynamicdata.cpp:831
KDevelop::Declaration::id
virtual DeclarationId id(bool forceDirect=false) const
Definition: declaration.cpp:564
KDevelop::DeclarationData
Definition: declarationdata.h:35
KDevelop::QualifiedIdentifier::push
void push(const IndexedIdentifier &id)
Append id to this qualified identifier.
Definition: identifier.cpp:995
KDevelop::DUContext::childContexts
QVector< DUContext * > childContexts() const
Returns the list of immediate child contexts for this context.
Definition: ducontext.cpp:479
KDevelop::Declaration::setKind
void setKind(Kind kind)
Set the kind.
Definition: declaration.cpp:84
declarationid.h
KDevelop::TopDUContext::inDUChain
bool inDUChain() const override
Returns true if this object is registered in the du-chain. If it is not, all sub-objects(context,...
Definition: topducontext.cpp:1114
KDevelop::Declaration::ownIndex
uint ownIndex() const
Returns an index that uniquely identifies this declaration within its surrounding top-context.
Definition: declaration.cpp:114
persistentsymboltable.h
QMap
KDevelop::Declaration::clone
Declaration * clone() const
Returns a clone of this declaration, with the difference that the returned declaration has no context...
Definition: declaration.cpp:643
KDevelop::Declaration::~Declaration
~Declaration() override
Destructor.
Definition: declaration.cpp:140
KDevelop::CodeModelItem::Kind
Kind
Definition: codemodel.h:41
KDevelop::Declaration::qualifiedIdentifier
QualifiedIdentifier qualifiedIdentifier() const
Determine the global qualified identifier of this declaration.
Definition: declaration.cpp:267
KDevelop::Declaration::setAutoDeclaration
void setAutoDeclaration(bool _auto)
Changes whether this declaration is "implicitly created".
Definition: declaration.cpp:492
QByteArray::isEmpty
bool isEmpty() const
KDevelop::Declaration::allocateOwnIndex
void allocateOwnIndex()
Create an index to this declaration from the topContext().
Definition: declaration.cpp:354
KDevelop::Declaration::isForwardDeclaration
virtual bool isForwardDeclaration() const
Determine whether this declaration is a forward declaration.
Definition: declaration.cpp:650
KDevelop::Declaration::operator==
bool operator==(const Declaration &other) const
Equivalence operator.
Definition: declaration.cpp:459
KDevelop::CodeModelItem::Unknown
Definition: codemodel.h:42
KDevelop::QualifiedIdentifier
Represents a qualified identifier.
Definition: identifier.h:245
KDevelop::kindForDeclaration
CodeModelItem::Kind kindForDeclaration(Declaration *decl)
Definition: declaration.cpp:579
QByteArray::constData
const char * constData() const
functiondefinition.h
topducontextdynamicdata.h
duchain.h
KDevelop::IndexedType
Indexed type pointer.
Definition: indexedtype.h:36
QMap::const_iterator
KDevelop::Declaration::hasUses
bool hasUses() const
Determines whether the declaration has any uses or not.
Definition: declaration.cpp:742
KDevelop::Declaration::logicalInternalContext
virtual DUContext * logicalInternalContext(const TopDUContext *topContext) const
Determine the logical internal context for the resolved form of this declaration.
Definition: declaration.cpp:396
KDevelop::Declaration::setIdentifier
void setIdentifier(const Identifier &identifier)
Set this declaration's identifier.
Definition: declaration.cpp:225
KDevelop::Declaration::setComment
void setComment(const QByteArray &str)
Sets the comment for this declaration.
Definition: declaration.cpp:186
uses.h
KDevelop
Definition: abstractfunctiondeclaration.cpp:27
KDevelop::DUContext
A single context in source code, represented as a node in a directed acyclic graph.
Definition: ducontext.h:72
KDevelop::Declaration::persistentlyDestroying
bool persistentlyDestroying() const
Returns true if this declaration is being currently destroyed persistently, which means that it shoul...
Definition: declaration.cpp:134
KDevelop::TopDUContext::deleting
bool deleting() const
Returns true if this object is being deleted, otherwise false.
Definition: topducontext.cpp:958
KDevelop::DUContext::usesCount
int usesCount() const
Returns the count of uses that can be accessed through uses()
Definition: ducontext.cpp:1333
identifiedtype.h
KDevelop::hasDeclarationUse
bool hasDeclarationUse(DUContext *context, int declIdx)
Definition: declaration.cpp:722
KDevelop::Declaration::activateSpecialization
virtual void activateSpecialization()
Signalized that among multiple possible specializations, this one should be used in the UI from now o...
Definition: declaration.cpp:555
KDevelop::FunctionDefinition::definition
static Declaration * definition(const Declaration *decl)
Find the definition for the given declaration, if one exists.
Definition: functiondefinition.cpp:85
specializationstore.h
KDevelop::Declaration::setInSymbolTable
virtual void setInSymbolTable(bool inSymbolTable)
Adds or removes this declaration to/from the symbol table.
Definition: declaration.cpp:614
ENSURE_CAN_READ
#define ENSURE_CAN_READ
Definition: duchainlock.h:185
KDevelop::CodeModelItem::Function
Definition: codemodel.h:43
KDevelop::Declaration::internalContext
DUContext * internalContext() const
Retrieve the context that is opened by this declaration, if one exists.
Definition: declaration.cpp:425
KDevelop::PersistentSymbolTable::addDeclaration
void addDeclaration(const IndexedQualifiedIdentifier &id, const IndexedDeclaration &declaration)
Adds declaration declaration with id id to the symbol table.
Definition: persistentsymboltable.cpp:208
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QByteArray::length
int length() const
KDevelop::Declaration::abstractType
AbstractType::Ptr abstractType() const
Access this declaration's type.
Definition: declaration.cpp:243
KDevelop::DUContext::owner
Declaration * owner() const
If this context was opened by a declaration or definition, this returns that item.
Definition: ducontext.cpp:486
KDevelop::DUContext::uses
const Use * uses() const
Uses: A "Use" represents any position in a document where a Declaration is used literally.
Definition: ducontext.cpp:1321
KDevelop::SpecializationStore::set
void set(const DeclarationId &declaration, const IndexedInstantiationInformation &specialization)
Adds/updates the current specialization for the given declaration-id.
Definition: specializationstore.cpp:39
duchainregister.h
codemodel.h
KDevelop::Declaration::specialize
virtual Declaration * specialize(const IndexedInstantiationInformation &specialization, const TopDUContext *topContext, int upDistance=0)
Retrieve the declaration which is specialized with the given specialization index as seen from topCon...
Definition: declaration.cpp:259
KDevelop::DUContext::type
ContextType type() const
Definition: ducontext.cpp:1134
KDevelop::CodeModelItem::ForwardDeclaration
Definition: codemodel.h:46
classdeclaration.h
KDevelop::Declaration::setExplicitlyDeleted
void setExplicitlyDeleted(bool deleted)
Changes whether this declaration is "explicitly deleted", i.e.
Definition: declaration.cpp:522
KDevelop::TopDUContext::isOnDisk
bool isOnDisk() const
Whether this top-context has a stored version on disk.
Definition: topducontext.cpp:1125
KDevelop::Declaration::uses
QMap< IndexedString, QVector< RangeInRevision > > uses() const
Returns a map of files to use-ranges.
Definition: declaration.cpp:675
KDevelop::Declaration::setDeprecated
void setDeprecated(bool deprecated)
Set whether the declaration is deprecated.
Definition: declaration.cpp:502
KDevelop::Declaration::setAbstractType
virtual void setAbstractType(AbstractType::Ptr type)
Set this declaration's type.
Definition: declaration.cpp:249
KDevelop::TopDUContext::m_dynamicData
class TopDUContextDynamicData * m_dynamicData
Definition: topducontext.h:381
KDevelop::Declaration::additionalIdentity
virtual uint additionalIdentity() const
This hash-value should differentiate between multiple different declarations that have the same quali...
Definition: declaration.cpp:660
KDevelop::CodeModelItem::Namespace
Definition: codemodel.h:47
KDevelop::Declaration::isExplicitlyTyped
bool isExplicitlyTyped() const
Determine whether this declaration is explicitly typed.
Definition: declaration.cpp:527
KDevelop::Declaration::alwaysForceDirect
bool alwaysForceDirect() const
Determine whether this declaration must always be direct.
Definition: declaration.cpp:507
KDevelop::CodeModel::updateItem
void updateItem(const IndexedString &file, const IndexedQualifiedIdentifier &id, CodeModelItem::Kind kind)
Updates the kind for the given item.
Definition: codemodel.cpp:264
QByteArray
KDevelop::DUContext::scopeIdentifier
QualifiedIdentifier scopeIdentifier(bool includeClasses=false) const
Calculate the fully qualified scope identifier.
Definition: ducontext.cpp:1082
KDevelop::Declaration::isDefinition
bool isDefinition() const
Determine whether this declaration is also a definition.
Definition: declaration.cpp:472
KDevelop::StructureType
A type representing structure types.
Definition: structuretype.h:38
KDevelop::DUChainBase::rebuildDynamicData
virtual void rebuildDynamicData(DUContext *parent, uint ownIndex)
Called after loading to rebuild the dynamic data. If this is a context, this should recursively work ...
Definition: duchainbase.cpp:126
DUCHAIN_D_DYNAMIC
#define DUCHAIN_D_DYNAMIC(Class)
Definition: duchainbase.h:48
KDevelop::Declaration::Declaration
Declaration(const RangeInRevision &range, DUContext *parentContext)
Constructor.
Definition: declaration.cpp:102
KDevelop::DUContextDynamicData::removeDeclaration
bool removeDeclaration(Declaration *declaration)
Removes the declaration from localDeclarations.
Definition: ducontext.cpp:241
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Mar 3 2021 00:37:28 by doxygen 1.8.16 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kdevplatform/language/duchain

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

kdevelop API Reference

Skip menu "kdevelop API Reference"
  • kdevplatform
  •   debugger
  •   documentation
  •   interfaces
  •   language
  •     assistant
  •     backgroundparser
  •     checks
  •     classmodel
  •     codecompletion
  •     codegen
  •     duchain
  •     editor
  •     highlighting
  •     interfaces
  •     util
  •   outputview
  •   project
  •   serialization
  •   shell
  •   sublime
  •   tests
  •   util
  •   vcs

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal