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

0001 /*
0002     SPDX-FileCopyrightText: 2014 Miquel Sabaté <mikisabate@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef BASICREFACTORING_H_
0008 #define BASICREFACTORING_H_
0009 
0010 #include <QObject>
0011 #include <QSharedPointer>
0012 #include <language/languageexport.h>
0013 #include <language/codegen/documentchangeset.h>
0014 #include <language/duchain/navigation/useswidget.h>
0015 
0016 class CppLanguageSupport;
0017 
0018 namespace KDevelop {
0019 class ContextMenuExtension;
0020 class IndexedDeclaration;
0021 class Context;
0022 class Declaration;
0023 class DUContext;
0024 
0025 /**
0026  * A widget that show the uses that it has collected for
0027  * the given declaration.
0028  */
0029 class KDEVPLATFORMLANGUAGE_EXPORT BasicRefactoringCollector
0030     : public UsesWidget::UsesWidgetCollector
0031 {
0032     Q_OBJECT
0033 
0034 public:
0035     explicit BasicRefactoringCollector(const IndexedDeclaration& decl);
0036     QVector<IndexedTopDUContext> allUsingContexts() const;
0037 
0038 protected:
0039     /// Process the uses for the given TopDUContext.
0040     void processUses(KDevelop::ReferencedTopDUContext topContext) override;
0041 
0042 private:
0043     QVector<IndexedTopDUContext> m_allUsingContexts;
0044 };
0045 
0046 /// The base class for Refactoring classes from Language plugins.
0047 class KDEVPLATFORMLANGUAGE_EXPORT BasicRefactoring
0048     : public QObject
0049 {
0050     Q_OBJECT
0051 
0052 public:
0053     explicit BasicRefactoring(QObject* parent = nullptr);
0054 
0055     /// Update the context menu with the "Rename" action.
0056     virtual void fillContextMenu(KDevelop::ContextMenuExtension& extension, KDevelop::Context* context,
0057                                  QWidget* parent);
0058 
0059     struct NameAndCollector
0060     {
0061         QString newName;
0062         QSharedPointer<BasicRefactoringCollector> collector;
0063     };
0064 
0065     /**
0066      * @return Suggestion for new filename based on the current file's name @p current and new identifier @p newName
0067      */
0068     virtual QString newFileName(const QUrl& current, const QString& newName);
0069 
0070     /**
0071      * Add the change(s) related to renaming @p file to @p newName to @p changes and return the result.
0072      *
0073      * @param current The URL for the file you want to rename.
0074      * @param newName The new name of the file *without* the file extension.
0075      * @param changes The change set to add the rename changes to.
0076      */
0077     virtual KDevelop::DocumentChangeSet::ChangeResult addRenameFileChanges(const QUrl& current,
0078                                                                            const QString& newName,
0079                                                                            KDevelop::DocumentChangeSet* changes);
0080 
0081     virtual bool shouldRenameUses(Declaration* declaration) const;
0082 
0083     /**
0084      * @return true if the declaration's file should be renamed if the declaration
0085      *         was renamed.
0086      */
0087     virtual bool shouldRenameFile(KDevelop::Declaration* declaration);
0088 
0089 public Q_SLOTS:
0090     void executeRenameAction();
0091 
0092 protected:
0093     /**
0094      * Apply the changes to the uses that can be found inside the given
0095      * context and its children.
0096      * NOTE: the DUChain must be locked.
0097      */
0098     virtual DocumentChangeSet::ChangeResult applyChanges(const QString& oldName, const QString& newName,
0099                                                          DocumentChangeSet& changes, DUContext* context,
0100                                                          int usedDeclarationIndex);
0101 
0102     /**
0103      * Apply the changes to the given declarations.
0104      * NOTE: the DUChain must be locked.
0105      */
0106     virtual DocumentChangeSet::ChangeResult applyChangesToDeclarations(const QString& oldName, const QString& newName,
0107                                                                        DocumentChangeSet& changes,
0108                                                                        const QList<IndexedDeclaration>& declarations);
0109 
0110     /**
0111      * Get the declaration under the current position of the cursor.
0112      *
0113      * @param allowUse Set to false if the declarations to be returned
0114      * cannot come from uses.
0115      */
0116     virtual IndexedDeclaration declarationUnderCursor(bool allowUse = true);
0117 
0118     /**
0119      * Start the renaming of a declaration.
0120      * This function retrieves the new name for declaration @p decl and if approved renames all instances of it.
0121      */
0122     virtual void startInteractiveRename(const KDevelop::IndexedDeclaration& decl);
0123 
0124     /**
0125      * Asks user to input a new name for @p declaration
0126      * @return new name or empty string if user changed his mind or new name contains inappropriate symbols (e.g. spaces, points, braces e.t.c) and the collector used for collecting information about @p declaration.
0127      * NOTE: unlock the DUChain before calling this.
0128      */
0129     virtual BasicRefactoring::NameAndCollector newNameForDeclaration(const KDevelop::DeclarationPointer& declaration);
0130 
0131     /**
0132      * Renames all declarations collected by @p collector from @p oldName to @p newName
0133      * @param apply - if changes should be applied immediately
0134      * @return all changes if @p apply is false and empty set otherwise.
0135      */
0136     DocumentChangeSet renameCollectedDeclarations(KDevelop::BasicRefactoringCollector* collector,
0137                                                   const QString& replacementName, const QString& originalName,
0138                                                   bool apply = true);
0139 
0140     /**
0141      * @returns true if we can show the interactive rename widget for the
0142      * given declaration. The default implementation just returns true.
0143      */
0144     virtual bool acceptForContextMenu(const Declaration* decl);
0145 };
0146 } // End of namespace KDevelop
0147 
0148 #endif /* BASICREFACTORING_H_ */