1 /* 2 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 3 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 4 5 SPDX-License-Identifier: LGPL-2.0-only 6 */ 7 8 #ifndef KDEVPLATFORM_DECLARATION_H 9 #define KDEVPLATFORM_DECLARATION_H 10 11 #include <QList> 12 #include <QMap> 13 14 #include "types/abstracttype.h" 15 #include "duchainbase.h" 16 #include "instantiationinformation.h" 17 #include "identifier.h" 18 #include "indexeddeclaration.h" 19 20 class QByteArray; 21 22 namespace KDevelop { 23 class AbstractType; 24 class DUContext; 25 class IndexedString; 26 class DeclarationData; 27 class DeclarationId; 28 class Declaration; 29 class IndexedTopDUContext; 30 class TopDUContext; 31 32 /** 33 * \short Represents a single declaration in a definition-use chain. 34 * 35 * \note A du-context can be freely edited as long as it's parent-context is zero. 36 * In the moment the parent-context is set, the context may only be edited when it 37 * is allowed to edited it's top-level context (@see TopLevelContext::inDUChain()) 38 */ 39 class KDEVPLATFORMLANGUAGE_EXPORT Declaration 40 : public DUChainBase 41 { 42 public: 43 /// Access types 44 enum AccessPolicy : quint8 { 45 Public /**< a public declaration */, 46 Protected /**< a protected declaration */, 47 Private /**< a private declaration */, 48 DefaultAccess /**<a declaration with default access; in java, only package-level access. */ 49 }; 50 /// Enumeration of the types of declarations 51 enum Kind : quint8 { 52 Type /**< A type is declared, like a class-declaration or function-declaration, or a typedef("class MyClass {};") */, 53 Instance /**< An instance of a type is declared("MyClass m;") */, 54 NamespaceAlias /**< This is a namespace-alias. You can safely cast this object to NamespaceAliasDeclaration. */, 55 Alias, /**<This is an alias-declaration. You can safely cast this object to AliasDeclaration. */ 56 Namespace, /**< Declaration of a namespace. */ 57 Import, /**< Declaration marks the Import of a file. */ 58 Macro /**< Declaration of a macro such as "#define FOO 1". */ 59 }; 60 61 /** 62 * Constructor. 63 * 64 * If \a parentContext is in the symbol table, the declaration will automatically 65 * be added into the symbol table. 66 * 67 * \param range range of the alias declaration's identifier 68 * \param parentContext context in which this declaration occurred 69 * */ 70 Declaration(const RangeInRevision& range, DUContext* parentContext); 71 ///Copy-constructor for cloning 72 Declaration(const Declaration& rhs); 73 /// Destructor 74 ~Declaration() override; 75 /// Uses the given data 76 explicit Declaration(DeclarationData& dd); 77 78 Declaration& operator=(const Declaration& rhs) = delete; 79 80 TopDUContext* topContext() const override; 81 82 /** 83 * Determine whether this declaration is a forward declaration. 84 * 85 * \returns true if this is a forward declaration, otherwise returns false. 86 */ 87 virtual bool isForwardDeclaration() const; 88 89 /** 90 * Determine whether this declaration is a function declaration. 91 * 92 * \returns true if this is a function declaration, otherwise returns false. 93 */ 94 virtual bool isFunctionDeclaration() const; 95 96 /** 97 * Determine whether this declaration is accessible through the du-chain. 98 * If it is, it cannot be edited without holding the du-chain write lock. 99 * 100 * \sa DUChain::lock() 101 * \sa DUChainWriteLocker 102 * 103 * \returns true if the Declaration is already inserted into a duchain. 104 */ 105 virtual bool inDUChain() const; 106 107 /** 108 * Determine whether this declaration is also a definition. 109 * 110 * \returns true if this declaration is also a definition, otherwise false. 111 */ 112 bool isDefinition() const; 113 /** 114 * Set whether this declaration is also a definition. 115 * 116 * \param dd set this to true if this declaration is also a definition, otherwise false. 117 */ 118 void setDeclarationIsDefinition(bool dd); 119 120 /** 121 * Determine if this declaration is a type-alias (in c++ typedef). 122 * 123 * \returns true if the declaration is a type alias, otherwise false. 124 */ 125 bool isTypeAlias() const; 126 /** 127 * Set whether this declaration is a type alias. 128 * 129 * \param typeAlias true if the declaration is a type alias, otherwise false. 130 */ 131 void setIsTypeAlias(bool typeAlias); 132 133 /** 134 * Determine whether the declaration is deprecated. 135 */ 136 bool isDeprecated() const; 137 /** 138 * Set whether the declaration is deprecated. 139 * 140 * \param deprecated true if the declaration is deprecated, otherwise false. 141 */ 142 void setDeprecated(bool deprecated); 143 144 /** 145 * Changes whether this declaration must be direct in all cases or not. 146 * 147 * By default this is set to false. 148 * 149 * \param direct true to force direct, false otherwise. 150 */ 151 void setAlwaysForceDirect(bool direct); 152 /** 153 * Determine whether this declaration must always be direct. 154 */ 155 bool alwaysForceDirect() const; 156 157 /** 158 * Changes whether this declaration is "implicitly created". 159 * 160 * An implicit declaration is not declared in the class context, 161 * but written somewhere else outside. 162 * 163 * Declarations are by default not implicitly declared. 164 * 165 * \param _auto true for implicit, false for default behaviour 166 */ 167 void setAutoDeclaration(bool _auto); 168 /** 169 * Determine whether this declaration is implicitly created or not. 170 */ 171 bool isAutoDeclaration() const; 172 173 /** 174 * Changes whether this declaration is "explicitly deleted", i.e. not implicitly declared or accessible. 175 * 176 * \param deleted true for deleted, false for default behaviour 177 * */ 178 void setExplicitlyDeleted(bool deleted); 179 /** 180 * Determine whether this declaration is "explicitly deleted" or not. 181 */ 182 bool isExplicitlyDeleted() const; 183 184 /** 185 * Changes whether this declaration is explicitly typed. 186 * 187 * Explicitly typed declaration has the type written as part of the 188 * declaration. The opposite, implicitly typed declaration, has the type 189 * deduced by the compiler. 190 * 191 * E.g. in C++ variable declarations are explicitly typed unless the "auto" 192 * keyword is used. 193 * 194 * \param explicitlyTyped true for explicitly typed, false for implicitly typed 195 */ 196 void setExplicitlyTyped(bool explicitlyTyped); 197 /** 198 * Determine whether this declaration is explicitly typed. 199 */ 200 bool isExplicitlyTyped() const; 201 202 /** 203 * Retrieve the declaration which is specialized with the given 204 * \a specialization index as seen from \a topContext. 205 * 206 * \param specialization the specialization index (see DeclarationId) 207 * \param topContext the top context representing the perspective from which to specialize. 208 * if @p topContext is zero, only already existing specializations are returned, 209 * and if none exists, zero is returned. 210 * \param upDistance upwards distance in the context-structure of the 211 * given specialization-info. This allows specializing children. 212 */ 213 virtual Declaration* specialize(const IndexedInstantiationInformation& specialization, 214 const TopDUContext* topContext, int upDistance = 0); 215 216 /** 217 * Retrieve the context that is opened by this declaration, if one exists. 218 * 219 * For example, a class will have a declaration which is contained within the context in which 220 * it is declared, and a new context will be created to hold class members. This function returns 221 * that context. 222 * The declaration has to be part of the same top-context. 223 * 224 * \returns the internal context for this declaration or, if none exists, nullptr 225 */ 226 DUContext* internalContext() const; 227 228 /** 229 * Set the internal \a context for this declaration. 230 * 231 * \param context the internal context 232 */ 233 void setInternalContext(DUContext* context); 234 235 /** 236 * Determine the logical internal context for the resolved form of this declaration. 237 * 238 * \li If this declaration has a definition, and the definition is resolved, 239 * it returns the internal context of the definition. 240 * \li If this declaration is a forward-declaration, the forward-declaration is 241 * resolved, it returns the internal context of the resolved declaration. 242 * \li If this is a type-alias, it returns the internal context of the actual type. 243 * \li Otherwise, it returns the same as internalContext(). 244 * 245 * \param topContext Needed to resolve forward-declarations. 246 * \returns the resolved internal context, as described above 247 */ 248 virtual DUContext* logicalInternalContext(const TopDUContext* topContext) const; 249 250 /** 251 * This is a convenience function to determine the resolved declaration, if this is a forward declaration. 252 * Otherwise, it just returns this declaration. 253 * \param topContext Context within which to search for the resolved declaration. 254 * \returns the resolved declaration if one was found, otherwise this declaration. 255 * */ 256 const Declaration* logicalDeclaration(const TopDUContext* topContext) const; 257 258 /// \copydoc 259 Declaration* logicalDeclaration(const TopDUContext* topContext); 260 261 /** 262 * Access the parent context of this declaration. 263 * \returns the parent context of this declaration. 264 */ 265 DUContext* context() const; 266 267 /** 268 * Set the context in which this declaration occurs. 269 * 270 * When setContext() is called, this declaration is inserted into the given context. 271 * You only need to be able to write this declaration. You do not need write-privileges 272 * for the context, because addDeclaration(..) works separately to that. 273 * 274 * If the given context is not in the symbol-table, or if the declaration is inserted anonymously, 275 * or if the context is zero, this declaration is removed from the symbol-table. 276 * Else it is added to the symbol table with the new scope. See TopDUContext for information 277 * about the symbol table. 278 * 279 * \param context New context which contains this declaration. The context must have a 280 * top-context if it is not zero. 281 * \param anonymous If this is set, this declaration will be added anonymously into the parent-context. 282 * This way it can never be found through any of the context's functions, and will 283 * not be deleted when the context is deleted, so it must be deleted from elsewhere. 284 */ 285 void setContext(DUContext* context, bool anonymous = false); 286 287 /** 288 * Convenience function to return this declaration's type dynamically casted to \a T. 289 * 290 * \returns this declaration's type as \a T, or null if there is no type or it is not of type \a T. 291 */ 292 template <class T> type()293 TypePtr<T> type() const { return TypePtr<T>::dynamicCast(abstractType()); } 294 295 /** 296 * Access this declaration's type. 297 * 298 * \note You should not compare or permanently store instances of AbstractType::Ptr. Use IndexedType instead. 299 * \returns this declaration's type, or null if none has been assigned. 300 */ 301 AbstractType::Ptr abstractType() const; 302 303 /** 304 * Set this declaration's type. 305 * 306 * \param type the type to assign. 307 */ 308 template <class T> setType(TypePtr<T> type)309 void setType(TypePtr<T> type) { setAbstractType(AbstractType::Ptr::staticCast(type)); } 310 311 /** 312 * Set this declaration's \a type. 313 * 314 * \param type this declaration's new type. 315 */ 316 virtual void setAbstractType(AbstractType::Ptr type); 317 318 /** 319 * Return an indexed form of this declaration's type. 320 * Should be preferred, this is the fastest way, and the correct way for doing equality-comparison. 321 * 322 * \returns the declaration's type. 323 */ 324 IndexedType indexedType() const; 325 326 /** 327 * Set this declaration's \a identifier. 328 * 329 * \param identifier this declaration's new identifier 330 */ 331 void setIdentifier(const Identifier& identifier); 332 333 /** 334 * Access this declaration's \a identifier. 335 * 336 * \returns this declaration's identifier. 337 */ 338 Identifier identifier() const; 339 340 /** 341 * Access this declaration's \a identifier. 342 * 343 * \return this declaration's identifier in indexed form. This is faster than identifier(), because it 344 * equals the internal representation. Use this for example to do equality-comparison. 345 */ 346 const IndexedIdentifier& indexedIdentifier() const; 347 348 /** 349 * Determine the global qualified identifier of this declaration. 350 * 351 * \note This function is expensive, equalQualifiedIdentifier() is preferred if you 352 * just want to compare equality. 353 */ 354 QualifiedIdentifier qualifiedIdentifier() const; 355 356 /** 357 * Compares the qualified identifier of this declaration with the other one, without needing to compute it. 358 * This is more efficient than comparing the results of qualifiedIdentifier(). 359 * 360 * \param rhs declaration to compare identifiers with 361 * \returns true if the identifiers are equal, otherwise false. 362 */ 363 bool equalQualifiedIdentifier(const Declaration* rhs) const; 364 365 /** 366 * Returns the kind of this declaration. @see Kind 367 */ 368 Kind kind() const; 369 370 /** 371 * Set the kind. 372 * 373 * \param kind new kind 374 */ 375 void setKind(Kind kind); 376 377 /** 378 * Returns the comment associated to this declaration in the source-code, 379 * or an invalid string if there is none. 380 * 381 * Stored in utf-8 encoding. 382 */ 383 QByteArray comment() const; 384 385 /** 386 * Sets the comment for this declaration. 387 * 388 * @note Should be utf-8 encoded. 389 */ 390 void setComment(const QByteArray& str); 391 /** 392 * Sets the comment for this declaration. 393 */ 394 void setComment(const QString& str); 395 396 /** 397 * Access whether this declaration is in the symbol table. 398 * 399 * \returns true if this declaration is in the symbol table, otherwise false. 400 */ 401 bool inSymbolTable() const; 402 403 /** 404 * Adds or removes this declaration to/from the symbol table. 405 * 406 * \param inSymbolTable true to add this declaration to the symbol table, false to remove it. 407 */ 408 virtual void setInSymbolTable(bool inSymbolTable); 409 410 /** 411 * Equivalence operator. 412 * 413 * \param other Other declaration to compare. 414 * \returns true if the declarations are equal, otherwise false. 415 */ 416 bool operator==(const Declaration& other) const; 417 418 /** 419 * Determine this declaration as a string. \returns this declaration as a string. 420 */ 421 virtual QString toString() const; 422 423 /** 424 * Returns a map of files to use-ranges. 425 * 426 * The key of the returned map is an url of a file. The value 427 * is a list with all use-ranges of this declaration in that file. 428 * 429 * \note The ranges are in the documents local revision, 430 * use \c DUChainUtils::transformFromRevision or \c usesCurrentRevision() 431 * 432 * \note The uses are unique, no 2 uses are returned that have the same range within the same file. 433 * 434 * \note This is a non-trivial operation and hence expensive. 435 */ 436 QMap<IndexedString, QVector<RangeInRevision>> uses() const; 437 438 /** 439 * Determines whether the declaration has any uses or not. 440 * 441 * Cheaper than calling uses(). 442 */ 443 bool hasUses() const; 444 445 /** 446 * Returns a map of files to use-ranges. 447 * 448 * The key of the returned map is an url of a file. The value 449 * is a list with all use-ranges of this declaration in that file. 450 * 451 * \note The uses are unique, no 2 uses are returned that have the same range within the same file. 452 * 453 * \warning This must be called only from within the foreground, or with the foreground lock locked. 454 * 455 * \note This is a non-trivial operation and hence expensive. 456 */ 457 QMap<IndexedString, QVector<KTextEditor::Range>> usesCurrentRevision() const; 458 459 /** 460 * This hash-value should differentiate between multiple different 461 * declarations that have the same qualifiedIdentifier, but should have a different 462 * identity, and thus own Definitions and own Uses assigned. 463 * 464 * Affected by function-arguments, whether this is a template-declaration, etc.. 465 */ 466 virtual uint additionalIdentity() const; 467 468 /** 469 * TODO document 470 * */ 471 virtual IndexedInstantiationInformation specialization() const; 472 473 /** 474 * \see DeclarationId 475 * 476 * \param forceDirect When this is true, the DeclarationId is force to be direct, 477 * and can be resolved without a symbol-table and top-context. 478 * The same goes for Declarations that have \c alwaysForceDirect() 479 * set to true. 480 */ 481 virtual DeclarationId id(bool forceDirect = false) const; 482 483 /** 484 * Returns an index that uniquely identifies this declaration within its surrounding top-context. 485 * 486 * That index can be passed to \c TopDUContext::declarationFromIndex(index) to get the declaration. 487 * This is only valid when the declaration is not a specialization (\c specialization() returns 0), 488 * and if it is not anonymous in its context. 489 * 490 * \note for this to be valid, allocateOwnIndex() must have been called first. 491 * \note the highest big of the index is always zero! 492 * \returns the index of the declaration within its TopDUContext. 493 */ 494 uint ownIndex() const; 495 496 /** 497 * Whether this declaration has been inserted anonymously into its parent-context 498 */ 499 bool isAnonymous() const; 500 501 /** 502 * Clear the index for this declaration in the top context that was allocated with allocateOwnIndex(). 503 */ 504 void clearOwnIndex(); 505 506 /** 507 * Create an index to this declaration from the topContext(). Needed to be able to retrieve ownIndex(). 508 */ 509 void allocateOwnIndex(); 510 511 /** 512 * Returns a clone of this declaration, with the difference that the returned declaration 513 * has no context set, i.e. \c context() returns zero. 514 * 515 * The declaration will not be registered anywhere, so you must care about its deletion. 516 * 517 * This declaration's text-range will be referenced from the clone, so the clone must not 518 * live longer than the original. 519 */ 520 Declaration* clone() const; 521 522 /** 523 * Signalized that among multiple possible specializations, this one should be used in the UI from now on. 524 * 525 * Currently mainly used in C++ for template support. The default-implementation registers the current 526 * specialization of this declaration to SpecializationStore if it is nonzero. 527 */ 528 virtual void activateSpecialization(); 529 530 enum { 531 Identity = 7 532 }; 533 534 protected: 535 536 /** 537 * Constructor for copy constructors in subclasses. 538 * 539 * \param dd data to copy. 540 * \param range text range which this object covers. 541 */ 542 Declaration(DeclarationData& dd, const RangeInRevision& range); 543 544 /** 545 * Returns true if this declaration is being currently destroyed persistently, 546 * which means that it should eventually deregister itself from persistent storage facilities. 547 * 548 * Only call this from destructors. 549 */ 550 bool persistentlyDestroying() const; 551 552 DUCHAIN_DECLARE_DATA(Declaration) 553 554 private: 555 /** 556 * Sub-classes should implement this and should copy as much information into the clone as possible without breaking the du-chain. 557 * Sub-classes should also implement a public copy-constructor that can be used for cloning by sub-classes. 558 * 559 * \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). 560 * */ 561 virtual Declaration* clonePrivate() const; 562 563 void updateCodeModel(); 564 565 void rebuildDynamicData(DUContext* parent, uint ownIndex) override; 566 567 friend class DUContext; 568 friend class IndexedDeclaration; 569 friend class LocalIndexedDeclaration; 570 friend class TopDUContextDynamicData; 571 572 DUContext* m_context = nullptr; 573 TopDUContext* m_topContext = nullptr; 574 int m_indexInTopContext = 0; 575 }; 576 } 577 578 #endif // KDEVPLATFORM_DECLARATION_H 579