File indexing completed on 2024-05-12 04:37:47

0001 /*
0002     SPDX-FileCopyrightText: 2008 Hamish Rodda <rodda@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KDEVPLATFORM_DUCHAINCHANGESET_H
0008 #define KDEVPLATFORM_DUCHAINCHANGESET_H
0009 
0010 #include <QVariant>
0011 
0012 #include "../duchain/identifier.h"
0013 #include "../duchain/topducontext.h"
0014 #include "../duchain/declaration.h"
0015 
0016 namespace KDevelop {
0017 class DUChainChangeSet;
0018 class DUChainChange;
0019 class DUChainBase;
0020 class DUContextRef;
0021 
0022 template <typename AstNode>
0023 class AstNodeRef;
0024 
0025 /**
0026  * \short A reference to an existing read-only DUChain object.
0027  *
0028  * This class represents a duchain object (eg, a KDevelop::DUContext),
0029  * and allows changes to be planned for that object.
0030  *
0031  * \todo Evaluate usefulness of changing child contexts - needed?
0032  *
0033  * \warning you must not create cyclic references.
0034  * \author Hamish Rodda <rodda@kde.org>
0035  */
0036 class KDEVPLATFORMLANGUAGE_EXPORT DUChainRef
0037 {
0038     friend class DUChainChangeSet;
0039 
0040 public:
0041     /*virtual ~DUChainRef();
0042 
0043        virtual const DUChainBase* object() const;
0044        virtual const DUContext* context() const;
0045        virtual const Declaration* declaration() const;
0046 
0047        virtual DUChainRef* objectRef() const;
0048 
0049        virtual DUChainBase* newObject() const;
0050        virtual DUContext* newContext() const;
0051        virtual Declaration* newDeclaration() const;
0052 
0053        const QList<DUChainChange*>& changes() const;
0054 
0055        /// Rename this object, if applicable
0056        void renameObject(const QualifiedIdentifier& newIdentifier);
0057        /// Change the access policy
0058        void setAccessPolicy(Declaration::AccessPolicy newPolicy);
0059 
0060        void deleteChildContext(DUContext* child);
0061        void insertChildContext(DUContextRef* newChild);
0062 
0063        void deleteDeclaration(Declaration* declaration);
0064        void insertDeclaration(Declaration* declaration, DUChainBase* afterObject);
0065        void appendDeclaration(Declaration* declaration);
0066 
0067        AbstractType::Ptr currentType() const;
0068        void changeType(AbstractType::Ptr newType);
0069      */
0070     /**
0071      * Rewrite the AST which created this duchain object. Eg:
0072      * - for declarations, the entire declaration.
0073      * - for contexts, the contents of the context.
0074      * - for types, the type declaration.
0075      *
0076      * \returns a reference to the AST which represents this object as it currently
0077      *          exists (after any existing duchain changes are applied).  Changes
0078      *          made to the AST will be applied along with the duchain change set.
0079      */
0080 /*    template <typename AstNode>
0081     AstNodeRef<AstNode> * rewriteAst();
0082 
0083     /// Removes a change from this object reference, and deletes it.
0084     void deleteChange(DUChainChange* change);
0085 
0086    protected:
0087     /// Constructor.  Either takes an existing \a object (\a newObject = false), or a newly created \a object (\a newObject = true)
0088     DUChainRef(DUChainChangeSet* set, DUChainBase* object, bool newObject);
0089     /// Constructor.  Takes another object reference.
0090     DUChainRef(DUChainChangeSet* set, DUChainRef* original);
0091 
0092     /// Adds a change to this object reference. Takes ownership of the \a change.
0093     DUChainChange* addChange(DUChainChange* change);
0094 
0095    private:
0096     DUChainChangeSet* m_changeSet;
0097     DUChainBase* m_object;
0098     DUChainRef* m_objectRef;
0099     bool m_newObject;
0100 
0101     QList<DUChainChange*> m_changes;*/
0102 };
0103 
0104 using DUChainBaseList = QList<DUChainRef*>;
0105 
0106 /**
0107  * \short Container class for a change to a duchain object.
0108  *
0109  * \author Hamish Rodda <rodda@kde.org>
0110  */
0111 class KDEVPLATFORMLANGUAGE_EXPORT DUChainChange
0112 {
0113 public:
0114     enum ChangeTypes {
0115         Rename,
0116         ListInsert,
0117         ListRemove,
0118         ListClear,
0119         ItemReplace,
0120         ItemMove,
0121         TypeChange
0122     } type;
0123 
0124     explicit DUChainChange(ChangeTypes t) : type(t) {}
0125 
0126     enum ItemToChange {
0127         ContextChildren,
0128         ContextDeclarations
0129     } itemToChange;
0130 
0131     /// New local identifier (eg. for contexts, the new DUContext::localScopeIdentifier() )
0132     QualifiedIdentifier newIdentifier;
0133 
0134     /// The new object to occupy this position, if relevant
0135     DUChainRef* newObject;
0136     /// The list of objects to occupy this position, if relevant
0137     DUChainBaseList newList;
0138     /// The position to apply the object(s) in the list, if relevant
0139     int listOffset;
0140     /// The value of the position, if relevant
0141     QVariant newValue;
0142 
0143     AbstractType::Ptr newType;
0144 };
0145 
0146 /**
0147  * \short A set of changes to a DUChain.
0148  *
0149  * This class holds a set of all changes to a DU Chain, and provides an interface
0150  * to convenience functions provided by the specific language support involved.
0151  *
0152  * \author Hamish Rodda <rodda@kde.org>
0153  */
0154 class KDEVPLATFORMLANGUAGE_EXPORT DUChainChangeSet
0155 {
0156 public:
0157     /**
0158      * Constructor.
0159      *
0160      * \param topContext the top context of the read-only DUChain to modify, or set to null if creating
0161      *                   a new DUChain from scratch.
0162      */
0163     explicit DUChainChangeSet(const ReferencedTopDUContext& topContext);
0164 
0165     /**
0166      * Destructor, deletes all objects, references and changes owned by this change set.
0167      */
0168     virtual ~DUChainChangeSet();
0169 
0170     /**
0171      * Create a new declaration to be managed by this change set.
0172      *
0173      * \returns the new declaration reference
0174      */
0175     virtual DUChainRef* newDeclaration() = 0;
0176 
0177     /**
0178      * Create a new class to be managed by this change set.
0179      *
0180      * \returns the new declaration reference
0181      */
0182     virtual DUChainRef* newClass() = 0;
0183 
0184     /**
0185      * Create a new function to be managed by this change set.
0186      *
0187      * \returns the new declaration reference
0188      */
0189     virtual DUChainRef* newFunction() = 0;
0190 
0191     /**
0192      * Copy an existing object from a change set.
0193      *
0194      * This change set takes ownership, so that
0195      * the new object will be deleted when the change set is no longer needed.
0196      *
0197      * \returns the new object reference
0198      */
0199     DUChainRef* copyRef(DUChainRef* ref);
0200 
0201     /**
0202      * Merge another changeset with this one. This changeset
0203      * takes ownership of all the objects in the other changeset.
0204      * After the merge, the merged object becomes empty.
0205      *
0206      * Both changesets must reference the same TopDuContext.
0207      */
0208     DUChainChangeSet& operator<<(DUChainChangeSet& rhs);
0209 
0210     /**
0211      * Produce a reference to an existing object in this chain, and replace the
0212      * object with the reference so that modifications to the reference are already
0213      * integrated into the change set.
0214      *
0215      * You may then modify this reference, and the modifications will be applied
0216      * to the chain when the change set is finalised.
0217      *
0218      * \returns a reference to \a source, which you may modify directly.
0219      */
0220     DUChainRef* modifyObject(DUChainBase* source);
0221 
0222     /**
0223      * Copy an existing object (whether from the DUChain or from the change set).
0224      * Does not insert the object into the chain.
0225      *
0226      * You may then modify this reference, and the modifications will be applied to the object when the change set is finalised.
0227      *
0228      * \returns a copy of \a source, which you may modify directly.
0229      */
0230     DUChainRef* copyObject(DUChainBase* source);
0231 
0232     /**
0233      * Retrieve the list of object references and changes.
0234      */
0235     QList<DUChainRef*> objectRefs() const;
0236 
0237     const ReferencedTopDUContext& topDuContext() const;
0238 
0239 private:
0240     ReferencedTopDUContext m_topContext;
0241 
0242     QList<DUChainRef*> m_objectRefs;
0243 };
0244 }
0245 
0246 #endif // KDEVPLATFORM_DUCHAINCHANGESET_H