File indexing completed on 2024-05-12 04:37:57
0001 /* 0002 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0003 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #ifndef KDEVPLATFORM_DECLARATION_H 0009 #define KDEVPLATFORM_DECLARATION_H 0010 0011 #include <QList> 0012 #include <QMap> 0013 0014 #include "types/abstracttype.h" 0015 #include "duchainbase.h" 0016 #include "identifier.h" 0017 #include "indexeddeclaration.h" 0018 0019 class QByteArray; 0020 0021 namespace KDevelop { 0022 class AbstractType; 0023 class DUContext; 0024 class IndexedString; 0025 class DeclarationData; 0026 class DeclarationId; 0027 class Declaration; 0028 class IndexedTopDUContext; 0029 class TopDUContext; 0030 class IndexedInstantiationInformation; 0031 0032 /** 0033 * \short Represents a single declaration in a definition-use chain. 0034 * 0035 * \note A du-context can be freely edited as long as it's parent-context is zero. 0036 * In the moment the parent-context is set, the context may only be edited when it 0037 * is allowed to edited it's top-level context (@see TopLevelContext::inDUChain()) 0038 */ 0039 class KDEVPLATFORMLANGUAGE_EXPORT Declaration 0040 : public DUChainBase 0041 { 0042 public: 0043 /// Access types 0044 enum AccessPolicy : quint8 { 0045 Public /**< a public declaration */, 0046 Protected /**< a protected declaration */, 0047 Private /**< a private declaration */, 0048 DefaultAccess /**<a declaration with default access; in java, only package-level access. */ 0049 }; 0050 /// Enumeration of the types of declarations 0051 enum Kind : quint8 { 0052 Type /**< A type is declared, like a class-declaration or function-declaration, or a typedef("class MyClass {};") */, 0053 Instance /**< An instance of a type is declared("MyClass m;") */, 0054 NamespaceAlias /**< This is a namespace-alias. You can safely cast this object to NamespaceAliasDeclaration. */, 0055 Alias, /**<This is an alias-declaration. You can safely cast this object to AliasDeclaration. */ 0056 Namespace, /**< Declaration of a namespace. */ 0057 Import, /**< Declaration marks the Import of a file. */ 0058 Macro /**< Declaration of a macro such as "#define FOO 1". */ 0059 }; 0060 0061 /** 0062 * Constructor. 0063 * 0064 * If \a parentContext is in the symbol table, the declaration will automatically 0065 * be added into the symbol table. 0066 * 0067 * \param range range of the alias declaration's identifier 0068 * \param parentContext context in which this declaration occurred 0069 * */ 0070 Declaration(const RangeInRevision& range, DUContext* parentContext); 0071 ///Copy-constructor for cloning 0072 Declaration(const Declaration& rhs); 0073 /// Destructor 0074 ~Declaration() override; 0075 /// Uses the given data 0076 explicit Declaration(DeclarationData& dd); 0077 0078 Declaration& operator=(const Declaration& rhs) = delete; 0079 0080 TopDUContext* topContext() const override; 0081 0082 /** 0083 * Determine whether this declaration is a forward declaration. 0084 * 0085 * \returns true if this is a forward declaration, otherwise returns false. 0086 */ 0087 virtual bool isForwardDeclaration() const; 0088 0089 /** 0090 * Determine whether this declaration is a function declaration. 0091 * 0092 * \returns true if this is a function declaration, otherwise returns false. 0093 */ 0094 virtual bool isFunctionDeclaration() const; 0095 0096 /** 0097 * Determine whether this declaration is accessible through the du-chain. 0098 * If it is, it cannot be edited without holding the du-chain write lock. 0099 * 0100 * \sa DUChain::lock() 0101 * \sa DUChainWriteLocker 0102 * 0103 * \returns true if the Declaration is already inserted into a duchain. 0104 */ 0105 virtual bool inDUChain() const; 0106 0107 /** 0108 * Determine whether this declaration is also a definition. 0109 * 0110 * \returns true if this declaration is also a definition, otherwise false. 0111 */ 0112 bool isDefinition() const; 0113 /** 0114 * Set whether this declaration is also a definition. 0115 * 0116 * \param dd set this to true if this declaration is also a definition, otherwise false. 0117 */ 0118 void setDeclarationIsDefinition(bool dd); 0119 0120 /** 0121 * Determine if this declaration is a type-alias (in c++ typedef). 0122 * 0123 * \returns true if the declaration is a type alias, otherwise false. 0124 */ 0125 bool isTypeAlias() const; 0126 /** 0127 * Set whether this declaration is a type alias. 0128 * 0129 * \param typeAlias true if the declaration is a type alias, otherwise false. 0130 */ 0131 void setIsTypeAlias(bool typeAlias); 0132 0133 /** 0134 * Determine whether the declaration is deprecated. 0135 */ 0136 bool isDeprecated() const; 0137 /** 0138 * Set whether the declaration is deprecated. 0139 * 0140 * \param deprecated true if the declaration is deprecated, otherwise false. 0141 */ 0142 void setDeprecated(bool deprecated); 0143 0144 /** 0145 * Changes whether this declaration must be direct in all cases or not. 0146 * 0147 * By default this is set to false. 0148 * 0149 * \param direct true to force direct, false otherwise. 0150 */ 0151 void setAlwaysForceDirect(bool direct); 0152 /** 0153 * Determine whether this declaration must always be direct. 0154 */ 0155 bool alwaysForceDirect() const; 0156 0157 /** 0158 * Changes whether this declaration is "implicitly created". 0159 * 0160 * An implicit declaration is not declared in the class context, 0161 * but written somewhere else outside. 0162 * 0163 * Declarations are by default not implicitly declared. 0164 * 0165 * \param _auto true for implicit, false for default behaviour 0166 */ 0167 void setAutoDeclaration(bool _auto); 0168 /** 0169 * Determine whether this declaration is implicitly created or not. 0170 */ 0171 bool isAutoDeclaration() const; 0172 0173 /** 0174 * Changes whether this declaration is "explicitly deleted", i.e. not implicitly declared or accessible. 0175 * 0176 * \param deleted true for deleted, false for default behaviour 0177 * */ 0178 void setExplicitlyDeleted(bool deleted); 0179 /** 0180 * Determine whether this declaration is "explicitly deleted" or not. 0181 */ 0182 bool isExplicitlyDeleted() const; 0183 0184 /** 0185 * Changes whether this declaration is explicitly typed. 0186 * 0187 * Explicitly typed declaration has the type written as part of the 0188 * declaration. The opposite, implicitly typed declaration, has the type 0189 * deduced by the compiler. 0190 * 0191 * E.g. in C++ variable declarations are explicitly typed unless the "auto" 0192 * keyword is used. 0193 * 0194 * \param explicitlyTyped true for explicitly typed, false for implicitly typed 0195 */ 0196 void setExplicitlyTyped(bool explicitlyTyped); 0197 /** 0198 * Determine whether this declaration is explicitly typed. 0199 */ 0200 bool isExplicitlyTyped() const; 0201 0202 /** 0203 * Retrieve the declaration which is specialized with the given 0204 * \a specialization index as seen from \a topContext. 0205 * 0206 * \param specialization the specialization index (see DeclarationId) 0207 * \param topContext the top context representing the perspective from which to specialize. 0208 * if @p topContext is zero, only already existing specializations are returned, 0209 * and if none exists, zero is returned. 0210 * \param upDistance upwards distance in the context-structure of the 0211 * given specialization-info. This allows specializing children. 0212 */ 0213 virtual Declaration* specialize(const IndexedInstantiationInformation& specialization, 0214 const TopDUContext* topContext, int upDistance = 0); 0215 0216 /** 0217 * Retrieve the context that is opened by this declaration, if one exists. 0218 * 0219 * For example, a class will have a declaration which is contained within the context in which 0220 * it is declared, and a new context will be created to hold class members. This function returns 0221 * that context. 0222 * The declaration has to be part of the same top-context. 0223 * 0224 * \returns the internal context for this declaration or, if none exists, nullptr 0225 */ 0226 DUContext* internalContext() const; 0227 0228 /** 0229 * Set the internal \a context for this declaration. 0230 * 0231 * \param context the internal context 0232 */ 0233 void setInternalContext(DUContext* context); 0234 0235 /** 0236 * Determine the logical internal context for the resolved form of this declaration. 0237 * 0238 * \li If this declaration has a definition, and the definition is resolved, 0239 * it returns the internal context of the definition. 0240 * \li If this declaration is a forward-declaration, the forward-declaration is 0241 * resolved, it returns the internal context of the resolved declaration. 0242 * \li If this is a type-alias, it returns the internal context of the actual type. 0243 * \li Otherwise, it returns the same as internalContext(). 0244 * 0245 * \param topContext Needed to resolve forward-declarations. 0246 * \returns the resolved internal context, as described above 0247 */ 0248 virtual DUContext* logicalInternalContext(const TopDUContext* topContext) const; 0249 0250 /** 0251 * This is a convenience function to determine the resolved declaration, if this is a forward declaration. 0252 * Otherwise, it just returns this declaration. 0253 * \param topContext Context within which to search for the resolved declaration. 0254 * \returns the resolved declaration if one was found, otherwise this declaration. 0255 * */ 0256 const Declaration* logicalDeclaration(const TopDUContext* topContext) const; 0257 0258 /// \copydoc 0259 Declaration* logicalDeclaration(const TopDUContext* topContext); 0260 0261 /** 0262 * Access the parent context of this declaration. 0263 * \returns the parent context of this declaration. 0264 */ 0265 DUContext* context() const; 0266 0267 /** 0268 * Set the context in which this declaration occurs. 0269 * 0270 * When setContext() is called, this declaration is inserted into the given context. 0271 * You only need to be able to write this declaration. You do not need write-privileges 0272 * for the context, because addDeclaration(..) works separately to that. 0273 * 0274 * If the given context is not in the symbol-table, or if the declaration is inserted anonymously, 0275 * or if the context is zero, this declaration is removed from the symbol-table. 0276 * Else it is added to the symbol table with the new scope. See TopDUContext for information 0277 * about the symbol table. 0278 * 0279 * \param context New context which contains this declaration. The context must have a 0280 * top-context if it is not zero. 0281 * \param anonymous If this is set, this declaration will be added anonymously into the parent-context. 0282 * This way it can never be found through any of the context's functions, and will 0283 * not be deleted when the context is deleted, so it must be deleted from elsewhere. 0284 */ 0285 void setContext(DUContext* context, bool anonymous = false); 0286 0287 /** 0288 * Convenience function to return this declaration's type dynamically casted to \a T. 0289 * 0290 * \returns this declaration's type as \a T, or null if there is no type or it is not of type \a T. 0291 */ 0292 template<class T> 0293 TypePtr<T> type() const 0294 { 0295 return abstractType().dynamicCast<T>(); 0296 } 0297 0298 /** 0299 * Access this declaration's type. 0300 * 0301 * \note You should not compare or permanently store instances of AbstractType::Ptr. Use IndexedType instead. 0302 * \returns this declaration's type, or null if none has been assigned. 0303 */ 0304 AbstractType::Ptr abstractType() const; 0305 0306 /** 0307 * Set this declaration's type. 0308 * 0309 * \param type the type to assign. 0310 */ 0311 void setType(AbstractType::Ptr type) 0312 { 0313 setAbstractType(std::move(type)); 0314 } 0315 0316 /** 0317 * Set this declaration's \a type. 0318 * 0319 * \param type this declaration's new type. 0320 */ 0321 virtual void setAbstractType(AbstractType::Ptr type); 0322 0323 /** 0324 * Return an indexed form of this declaration's type. 0325 * Should be preferred, this is the fastest way, and the correct way for doing equality-comparison. 0326 * 0327 * \returns the declaration's type. 0328 */ 0329 IndexedType indexedType() const; 0330 0331 /** 0332 * Set this declaration's \a identifier. 0333 * 0334 * \param identifier this declaration's new identifier 0335 */ 0336 void setIdentifier(const Identifier& identifier); 0337 0338 /** 0339 * Access this declaration's \a identifier. 0340 * 0341 * \returns this declaration's identifier. 0342 */ 0343 Identifier identifier() const; 0344 0345 /** 0346 * Access this declaration's \a identifier. 0347 * 0348 * \return this declaration's identifier in indexed form. This is faster than identifier(), because it 0349 * equals the internal representation. Use this for example to do equality-comparison. 0350 */ 0351 const IndexedIdentifier& indexedIdentifier() const; 0352 0353 /** 0354 * Determine the global qualified identifier of this declaration. 0355 * 0356 * \note This function is expensive, equalQualifiedIdentifier() is preferred if you 0357 * just want to compare equality. 0358 */ 0359 QualifiedIdentifier qualifiedIdentifier() const; 0360 0361 /** 0362 * Compares the qualified identifier of this declaration with the other one, without needing to compute it. 0363 * This is more efficient than comparing the results of qualifiedIdentifier(). 0364 * 0365 * \param rhs declaration to compare identifiers with 0366 * \returns true if the identifiers are equal, otherwise false. 0367 */ 0368 bool equalQualifiedIdentifier(const Declaration* rhs) const; 0369 0370 /** 0371 * Returns the kind of this declaration. @see Kind 0372 */ 0373 Kind kind() const; 0374 0375 /** 0376 * Set the kind. 0377 * 0378 * \param kind new kind 0379 */ 0380 void setKind(Kind kind); 0381 0382 /** 0383 * Returns the comment associated to this declaration in the source-code, 0384 * or an invalid string if there is none. 0385 * 0386 * Stored in utf-8 encoding. 0387 */ 0388 QByteArray comment() const; 0389 0390 /** 0391 * Sets the comment for this declaration. 0392 * 0393 * @note Should be utf-8 encoded. 0394 */ 0395 void setComment(const QByteArray& str); 0396 /** 0397 * Sets the comment for this declaration. 0398 */ 0399 void setComment(const QString& str); 0400 0401 /** 0402 * Access whether this declaration is in the symbol table. 0403 * 0404 * \returns true if this declaration is in the symbol table, otherwise false. 0405 */ 0406 bool inSymbolTable() const; 0407 0408 /** 0409 * Adds or removes this declaration to/from the symbol table. 0410 * 0411 * \param inSymbolTable true to add this declaration to the symbol table, false to remove it. 0412 */ 0413 virtual void setInSymbolTable(bool inSymbolTable); 0414 0415 /** 0416 * Equivalence operator. 0417 * 0418 * \param other Other declaration to compare. 0419 * \returns true if the declarations are equal, otherwise false. 0420 */ 0421 bool operator==(const Declaration& other) const; 0422 0423 /** 0424 * Determine this declaration as a string. \returns this declaration as a string. 0425 */ 0426 virtual QString toString() const; 0427 0428 /** 0429 * Returns a map of files to use-ranges. 0430 * 0431 * The key of the returned map is an url of a file. The value 0432 * is a list with all use-ranges of this declaration in that file. 0433 * 0434 * \note The ranges are in the documents local revision, 0435 * use \c DUChainUtils::transformFromRevision or \c usesCurrentRevision() 0436 * 0437 * \note The uses are unique, no 2 uses are returned that have the same range within the same file. 0438 * 0439 * \note This is a non-trivial operation and hence expensive. 0440 */ 0441 QMap<IndexedString, QVector<RangeInRevision>> uses() const; 0442 0443 /** 0444 * Determines whether the declaration has any uses or not. 0445 * 0446 * Cheaper than calling uses(). 0447 */ 0448 bool hasUses() const; 0449 0450 /** 0451 * Returns a map of files to use-ranges. 0452 * 0453 * The key of the returned map is an url of a file. The value 0454 * is a list with all use-ranges of this declaration in that file. 0455 * 0456 * \note The uses are unique, no 2 uses are returned that have the same range within the same file. 0457 * 0458 * \warning This must be called only from within the foreground, or with the foreground lock locked. 0459 * 0460 * \note This is a non-trivial operation and hence expensive. 0461 */ 0462 QMap<IndexedString, QVector<KTextEditor::Range>> usesCurrentRevision() const; 0463 0464 /** 0465 * This hash-value should differentiate between multiple different 0466 * declarations that have the same qualifiedIdentifier, but should have a different 0467 * identity, and thus own Definitions and own Uses assigned. 0468 * 0469 * Affected by function-arguments, whether this is a template-declaration, etc.. 0470 */ 0471 virtual uint additionalIdentity() const; 0472 0473 /** 0474 * TODO document 0475 * */ 0476 virtual IndexedInstantiationInformation specialization() const; 0477 0478 /** 0479 * \see DeclarationId 0480 * 0481 * \param forceDirect When this is true, the DeclarationId is force to be direct, 0482 * and can be resolved without a symbol-table and top-context. 0483 * The same goes for Declarations that have \c alwaysForceDirect() 0484 * set to true. 0485 */ 0486 virtual DeclarationId id(bool forceDirect = false) const; 0487 0488 /** 0489 * Returns an index that uniquely identifies this declaration within its surrounding top-context. 0490 * 0491 * That index can be passed to \c TopDUContext::declarationFromIndex(index) to get the declaration. 0492 * This is only valid when the declaration is not a specialization (\c specialization() returns 0), 0493 * and if it is not anonymous in its context. 0494 * 0495 * \note for this to be valid, allocateOwnIndex() must have been called first. 0496 * \note the highest big of the index is always zero! 0497 * \returns the index of the declaration within its TopDUContext. 0498 */ 0499 uint ownIndex() const; 0500 0501 /** 0502 * Whether this declaration has been inserted anonymously into its parent-context 0503 */ 0504 bool isAnonymous() const; 0505 0506 /** 0507 * Clear the index for this declaration in the top context that was allocated with allocateOwnIndex(). 0508 */ 0509 void clearOwnIndex(); 0510 0511 /** 0512 * Create an index to this declaration from the topContext(). Needed to be able to retrieve ownIndex(). 0513 */ 0514 void allocateOwnIndex(); 0515 0516 /** 0517 * Returns a clone of this declaration, with the difference that the returned declaration 0518 * has no context set, i.e. \c context() returns zero. 0519 * 0520 * The declaration will not be registered anywhere, so you must care about its deletion. 0521 * 0522 * This declaration's text-range will be referenced from the clone, so the clone must not 0523 * live longer than the original. 0524 */ 0525 Declaration* clone() const; 0526 0527 /** 0528 * Signalized that among multiple possible specializations, this one should be used in the UI from now on. 0529 * 0530 * Currently mainly used in C++ for template support. The default-implementation registers the current 0531 * specialization of this declaration to SpecializationStore if it is nonzero. 0532 */ 0533 virtual void activateSpecialization(); 0534 0535 enum { 0536 Identity = 7 0537 }; 0538 0539 protected: 0540 0541 /** 0542 * Constructor for copy constructors in subclasses. 0543 * 0544 * \param dd data to copy. 0545 * \param range text range which this object covers. 0546 */ 0547 Declaration(DeclarationData& dd, const RangeInRevision& range); 0548 0549 /** 0550 * Returns true if this declaration is being currently destroyed persistently, 0551 * which means that it should eventually deregister itself from persistent storage facilities. 0552 * 0553 * Only call this from destructors. 0554 */ 0555 bool persistentlyDestroying() const; 0556 0557 DUCHAIN_DECLARE_DATA(Declaration) 0558 0559 private: 0560 /** 0561 * Sub-classes should implement this and should copy as much information into the clone as possible without breaking the du-chain. 0562 * Sub-classes should also implement a public copy-constructor that can be used for cloning by sub-classes. 0563 * 0564 * \note You do not have to implement this for your language if you are not going to use it(the du-chain itself does not and should not depend on it). 0565 * */ 0566 virtual Declaration* clonePrivate() const; 0567 0568 void updateCodeModel(); 0569 0570 void rebuildDynamicData(DUContext* parent, uint ownIndex) override; 0571 0572 friend class DUContext; 0573 friend class IndexedDeclaration; 0574 friend class LocalIndexedDeclaration; 0575 friend class TopDUContextDynamicData; 0576 0577 DUContext* m_context = nullptr; 0578 TopDUContext* m_topContext = nullptr; 0579 int m_indexInTopContext = 0; 0580 }; 0581 } 0582 0583 #endif // KDEVPLATFORM_DECLARATION_H