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