diff --git a/language/CMakeLists.txt b/language/CMakeLists.txt index 72ab78e368..d5f29c13c9 100644 --- a/language/CMakeLists.txt +++ b/language/CMakeLists.txt @@ -1,356 +1,358 @@ add_definitions( -DKDE_DEFAULT_DEBUG_AREA=9505 ) add_subdirectory(highlighting/tests) add_subdirectory(duchain/tests) add_subdirectory(backgroundparser/tests) add_subdirectory(codegen/tests) set(kdevplatformlanguage_LIB_SRCS editor/persistentmovingrangeprivate.cpp editor/persistentmovingrange.cpp editor/modificationrevisionset.cpp editor/modificationrevision.cpp backgroundparser/backgroundparser.cpp backgroundparser/parsejob.cpp backgroundparser/parserdependencypolicy.cpp backgroundparser/documentchangetracker.cpp backgroundparser/parseprojectjob.cpp backgroundparser/urlparselock.cpp duchain/referencecounting.cpp duchain/specializationstore.cpp duchain/codemodel.cpp duchain/duchain.cpp duchain/waitforupdate.cpp duchain/duchainpointer.cpp duchain/ducontext.cpp duchain/indexedducontext.cpp duchain/indexedtopducontext.cpp duchain/localindexedducontext.cpp duchain/indexeddeclaration.cpp duchain/localindexeddeclaration.cpp duchain/topducontext.cpp duchain/topducontextdynamicdata.cpp duchain/functiondefinition.cpp duchain/declaration.cpp duchain/classmemberdeclaration.cpp duchain/classfunctiondeclaration.cpp duchain/classdeclaration.cpp duchain/use.cpp duchain/forwarddeclaration.cpp duchain/duchainbase.cpp duchain/duchainlock.cpp duchain/identifier.cpp duchain/parsingenvironment.cpp duchain/abstractfunctiondeclaration.cpp duchain/functiondeclaration.cpp duchain/stringhelpers.cpp duchain/namespacealiasdeclaration.cpp duchain/aliasdeclaration.cpp duchain/dumpdotgraph.cpp duchain/duchainobserver.cpp duchain/duchainutils.cpp duchain/declarationid.cpp duchain/definitions.cpp duchain/uses.cpp duchain/importers.cpp duchain/dumpchain.cpp duchain/indexedstring.cpp duchain/duchainregister.cpp duchain/persistentsymboltable.cpp duchain/instantiationinformation.cpp duchain/types/typesystem.cpp duchain/types/typeregister.cpp duchain/types/identifiedtype.cpp duchain/types/abstracttype.cpp duchain/types/integraltype.cpp duchain/types/functiontype.cpp duchain/types/structuretype.cpp duchain/types/pointertype.cpp duchain/types/referencetype.cpp duchain/types/delayedtype.cpp duchain/types/arraytype.cpp duchain/types/indexedtype.cpp duchain/types/enumerationtype.cpp duchain/types/constantintegraltype.cpp duchain/types/enumeratortype.cpp duchain/types/typeutils.cpp duchain/types/typealiastype.cpp duchain/types/unsuretype.cpp duchain/repositories/abstractitemrepository.cpp duchain/repositories/itemrepositoryregistry.cpp duchain/repositories/typerepository.cpp duchain/navigation/problemnavigationcontext.cpp duchain/navigation/abstractnavigationwidget.cpp duchain/navigation/abstractnavigationcontext.cpp duchain/navigation/usesnavigationcontext.cpp duchain/navigation/abstractdeclarationnavigationcontext.cpp duchain/navigation/abstractincludenavigationcontext.cpp duchain/navigation/useswidget.cpp duchain/navigation/usescollector.cpp interfaces/iastcontainer.cpp interfaces/ilanguagesupport.cpp interfaces/quickopendataprovider.cpp interfaces/iproblem.cpp interfaces/iquickopen.cpp interfaces/editorcontext.cpp interfaces/codecontext.cpp interfaces/icreateclasshelper.cpp interfaces/icontextbrowser.cpp codecompletion/codecompletion.cpp codecompletion/codecompletionworker.cpp codecompletion/codecompletionmodel.cpp codecompletion/codecompletionitem.cpp codecompletion/codecompletioncontext.cpp codecompletion/codecompletionitemgrouper.cpp codecompletion/codecompletionhelper.cpp codecompletion/normaldeclarationcompletionitem.cpp codegen/applychangeswidget.cpp codegen/coderepresentation.cpp codegen/documentchangeset.cpp codegen/duchainchangeset.cpp codegen/utilities.cpp codegen/templatesmodel.cpp codegen/templateclassgenerator.cpp codegen/codedescription.cpp codegen/sourcefiletemplate.cpp codegen/templaterenderer.cpp codegen/templateengine.cpp codegen/archivetemplateloader.cpp + codegen/basicrefactoring.cpp util/setrepository.cpp util/includeitem.cpp util/navigationtooltip.cpp highlighting/colorcache.cpp highlighting/configurablecolors.cpp highlighting/codehighlighting.cpp checks/dataaccessrepository.cpp checks/dataaccess.cpp checks/controlflowgraph.cpp checks/controlflownode.cpp ) kde4_add_library(kdevplatformlanguage SHARED ${kdevplatformlanguage_LIB_SRCS}) target_link_libraries(kdevplatformlanguage LINK_PUBLIC kdevplatforminterfaces ) target_link_libraries(kdevplatformlanguage LINK_PRIVATE ${KDE4_KPARTS_LIBS} ${KDE4_KTEXTEDITOR_LIBS} ${KDE4_THREADWEAVER_LIBRARIES} ${KDE4_KNEWSTUFF3_LIBS} kdevplatformutil ${Grantlee_CORE_LIBRARIES} ) set_target_properties(kdevplatformlanguage PROPERTIES VERSION ${KDEVPLATFORM_LIB_VERSION} SOVERSION ${KDEVPLATFORM_LIB_SOVERSION}) install(TARGETS kdevplatformlanguage EXPORT KDevPlatformTargets ${INSTALL_TARGETS_DEFAULT_ARGS} ) ########### install files ############### install(FILES languageexport.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language COMPONENT Devel ) install(FILES interfaces/ilanguagesupport.h interfaces/icodehighlighting.h interfaces/quickopendataprovider.h interfaces/quickopenfilter.h interfaces/iquickopen.h interfaces/iproblem.h interfaces/codecontext.h interfaces/editorcontext.h interfaces/iastcontainer.h interfaces/icreateclasshelper.h interfaces/icontextbrowser.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/interfaces COMPONENT Devel ) install(FILES editor/persistentmovingrange.h editor/documentrange.h editor/documentcursor.h editor/simplecursor.h editor/simplerange.h editor/cursorinrevision.h editor/rangeinrevision.h editor/modificationrevision.h editor/modificationrevisionset.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/editor COMPONENT Devel ) install(FILES backgroundparser/backgroundparser.h backgroundparser/parsejob.h backgroundparser/parseprojectjob.h backgroundparser/urlparselock.h backgroundparser/documentchangetracker.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/backgroundparser COMPONENT Devel ) install(FILES util/navigationtooltip.h util/setrepository.h util/basicsetrepository.h util/includeitem.h util/debuglanguageparserhelper.h util/kdevhash.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/util COMPONENT Devel ) install(FILES duchain/referencecounting.h duchain/parsingenvironment.h duchain/duchain.h duchain/codemodel.h duchain/ducontext.h duchain/ducontextdata.h duchain/topducontext.h duchain/topducontextutils.h duchain/topducontextdata.h duchain/declaration.h duchain/declarationdata.h duchain/classmemberdeclaration.h duchain/classmemberdeclarationdata.h duchain/classfunctiondeclaration.h duchain/classdeclaration.h duchain/functiondefinition.h duchain/use.h duchain/forwarddeclaration.h duchain/duchainbase.h duchain/duchainpointer.h duchain/duchainobserver.h duchain/duchainlock.h duchain/identifier.h duchain/abstractfunctiondeclaration.h duchain/functiondeclaration.h duchain/stringhelpers.h duchain/safetycounter.h duchain/namespacealiasdeclaration.h duchain/aliasdeclaration.h duchain/dumpdotgraph.h duchain/duchainutils.h duchain/dumpchain.h duchain/indexedstring.h duchain/declarationid.h duchain/appendedlist.h duchain/duchainregister.h duchain/persistentsymboltable.h duchain/instantiationinformation.h duchain/specializationstore.h duchain/persistentsetmap.h duchain/indexedducontext.h duchain/indexedtopducontext.h duchain/localindexedducontext.h duchain/indexeddeclaration.h duchain/localindexeddeclaration.h duchain/definitions.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/duchain COMPONENT Devel ) install(FILES duchain/types/unsuretype.h duchain/types/identifiedtype.h duchain/types/typesystem.h duchain/types/typeregister.h duchain/types/typepointer.h duchain/types/typesystemdata.h duchain/types/abstracttype.h duchain/types/integraltype.h duchain/types/functiontype.h duchain/types/structuretype.h duchain/types/pointertype.h duchain/types/referencetype.h duchain/types/delayedtype.h duchain/types/arraytype.h duchain/types/indexedtype.h duchain/types/enumerationtype.h duchain/types/constantintegraltype.h duchain/types/enumeratortype.h duchain/types/alltypes.h duchain/types/typeutils.h duchain/types/typealiastype.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/duchain/types COMPONENT Devel ) install(FILES duchain/builders/abstractcontextbuilder.h duchain/builders/abstractdeclarationbuilder.h duchain/builders/abstracttypebuilder.h duchain/builders/abstractusebuilder.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/duchain/builders COMPONENT Devel ) install(FILES duchain/repositories/itemrepositoryexampleitem.h duchain/repositories/abstractitemrepository.h duchain/repositories/itemrepositoryregistry.h duchain/repositories/repositorymanager.h duchain/repositories/itemrepository.h duchain/repositories/typerepository.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/duchain/repositories COMPONENT Devel ) install(FILES codecompletion/codecompletion.h codecompletion/codecompletionworker.h codecompletion/codecompletionmodel.h codecompletion/codecompletionitem.h codecompletion/codecompletioncontext.h codecompletion/codecompletionitemgrouper.h codecompletion/codecompletionhelper.h codecompletion/normaldeclarationcompletionitem.h codecompletion/abstractincludefilecompletionitem.h codecompletion/codecompletiontesthelper.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/codecompletion COMPONENT Devel ) install(FILES codegen/applychangeswidget.h codegen/astchangeset.h codegen/duchainchangeset.h codegen/documentchangeset.h codegen/coderepresentation.h codegen/utilities.h codegen/templatesmodel.h codegen/templaterenderer.h codegen/templateengine.h codegen/sourcefiletemplate.h codegen/templateclassgenerator.h codegen/codedescription.h + codegen/basicrefactoring.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/codegen COMPONENT Devel ) install(FILES duchain/navigation/usesnavigationcontext.h duchain/navigation/abstractnavigationcontext.h duchain/navigation/abstractdeclarationnavigationcontext.h duchain/navigation/abstractincludenavigationcontext.h duchain/navigation/abstractnavigationwidget.h duchain/navigation/navigationaction.h duchain/navigation/useswidget.h duchain/navigation/usescollector.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/duchain/navigation COMPONENT Devel ) install(FILES highlighting/codehighlighting.h highlighting/colorcache.h highlighting/configurablecolors.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/highlighting COMPONENT Devel ) install(FILES checks/dataaccess.h checks/dataaccessrepository.h checks/controlflowgraph.h checks/controlflownode.h DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/language/checks COMPONENT Devel ) diff --git a/language/codegen/basicrefactoring.cpp b/language/codegen/basicrefactoring.cpp new file mode 100644 index 0000000000..3c584d2742 --- /dev/null +++ b/language/codegen/basicrefactoring.cpp @@ -0,0 +1,290 @@ +/* This file is part of KDevelop + * + * Copyright 2014 Miquel Sabaté + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +// Qt +#include +#include +#include +#include +#include +#include + +// KDE / KDevelop +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace KDevelop +{ + +//BEGIN: BasicRefactoringCollector + +BasicRefactoringCollector::BasicRefactoringCollector(const IndexedDeclaration &decl) + : UsesWidgetCollector(decl) +{ + setCollectConstructors(true); + setCollectDefinitions(true); + setCollectOverloads(true); +} + +QVector BasicRefactoringCollector::allUsingContexts() const +{ + return m_allUsingContexts; +} + +void BasicRefactoringCollector::processUses(KDevelop::ReferencedTopDUContext topContext) +{ + m_allUsingContexts << IndexedTopDUContext(topContext.data()); + UsesWidgetCollector::processUses(topContext); +} + +//END: BasicRefactoringCollector + +//BEGIN: BasicRefactoring + +BasicRefactoring::BasicRefactoring(QObject *parent) + : QObject(parent) +{ + /* There's nothing to do here. */ +} + +void BasicRefactoring::fillContextMenu(ContextMenuExtension &extension, Context *context) +{ + DeclarationContext *declContext = dynamic_cast(context); + if (!declContext) + return; + + DUChainReadLocker lock; + Declaration *declaration = declContext->declaration().data(); + if (declaration && acceptForContextMenu(declaration)) { + QFileInfo finfo(declaration->topContext()->url().str()); + if (finfo.isWritable()) { + QAction *action = new QAction(i18n("Rename \"%1\"...", declaration->qualifiedIdentifier().toString()), 0); + action->setData(QVariant::fromValue(IndexedDeclaration(declaration))); + action->setIcon(KIcon("edit-rename")); + connect(action, SIGNAL(triggered(bool)), this, SLOT(executeRenameAction())); + extension.addAction(ContextMenuExtension::RefactorGroup, action); + } + } +} + +DocumentChangeSet::ChangeResult BasicRefactoring::applyChanges(const QString &oldName, const QString &newName, + DocumentChangeSet &changes, DUContext *context, + int usedDeclarationIndex) +{ + if (usedDeclarationIndex == std::numeric_limits::max()) + return DocumentChangeSet::ChangeResult(true); + + for (int a = 0; a < context->usesCount(); ++a) { + const Use &use(context->uses()[a]); + if (use.m_declarationIndex != usedDeclarationIndex) + continue; + if (use.m_range.isEmpty()) { + kDebug() << "found empty use"; + continue; + } + DocumentChangeSet::ChangeResult result = changes.addChange(DocumentChange(context->url(), context->transformFromLocalRevision(use.m_range), oldName, newName)); + if (!result) + return result; + } + + foreach (DUContext *child, context->childContexts()) { + DocumentChangeSet::ChangeResult result = applyChanges(oldName, newName, changes, child, usedDeclarationIndex); + if (!result) + return result; + } + return DocumentChangeSet::ChangeResult(true); +} + +DocumentChangeSet::ChangeResult BasicRefactoring::applyChangesToDeclarations(const QString &oldName, + const QString &newName, + DocumentChangeSet &changes, + const QList &declarations) +{ + foreach (const IndexedDeclaration &decl, declarations) { + Declaration *declaration = decl.data(); + if (!declaration) + continue; + if (declaration->range().isEmpty()) + kDebug() << "found empty declaration"; + + TopDUContext *top = declaration->topContext(); + DocumentChangeSet::ChangeResult result = changes.addChange(DocumentChange(top->url(), declaration->rangeInCurrentRevision(), oldName, newName)); + if (!result) + return result; + } + return DocumentChangeSet::ChangeResult(true); +} + +KDevelop::IndexedDeclaration BasicRefactoring::declarationUnderCursor(bool allowUse) +{ + KDevelop::IDocument *doc = ICore::self()->documentController()->activeDocument(); + if (doc && doc->textDocument() && doc->textDocument()->activeView()) { + DUChainReadLocker lock; + if (allowUse) + return DUChainUtils::itemUnderCursor(doc->url(), SimpleCursor(doc->textDocument()->activeView()->cursorPosition())); + else + return DUChainUtils::declarationInLine(SimpleCursor(doc->textDocument()->activeView()->cursorPosition()), DUChainUtils::standardContextForUrl(doc->url())); + } + + return KDevelop::IndexedDeclaration(); +} + +void BasicRefactoring::startInteractiveRename(const KDevelop::IndexedDeclaration &decl) +{ + DUChainReadLocker lock(DUChain::lock()); + + Declaration *declaration = decl.data(); + if (!declaration) { + KMessageBox::error(ICore::self()->uiController()->activeMainWindow(), i18n("No declaration under cursor")); + return; + } + QFileInfo info(declaration->topContext()->url().str()); + if (!info.isWritable()) { + KMessageBox::error(ICore::self()->uiController()->activeMainWindow(), + i18n("Declaration is located in non-writeable file %1.", declaration->topContext()->url().str())); + return; + } + + QString originalName = declaration->identifier().identifier().str(); + QString replacementName; + + BasicRefactoringCollector *collector = new BasicRefactoringCollector(decl); + QPointer dialog = new QDialog(); + QTabWidget tabWidget; + UsesWidget uses(declaration, collector); + + //So the context-links work + QWidget *navigationWidget = declaration->context()->createNavigationWidget(declaration); + AbstractNavigationWidget* abstractNavigationWidget = dynamic_cast(navigationWidget); + if (abstractNavigationWidget) + connect(&uses, SIGNAL(navigateDeclaration(KDevelop::IndexedDeclaration)), abstractNavigationWidget, SLOT(navigateDeclaration(KDevelop::IndexedDeclaration))); + + QVBoxLayout verticalLayout; + QHBoxLayout actionsLayout; + dialog->setLayout(&verticalLayout); + dialog->setWindowTitle(i18n("Rename %1", declaration->toString())); + + QLabel newNameLabel(i18n("New name:")); + actionsLayout.addWidget(&newNameLabel); + + QLineEdit edit(declaration->identifier().identifier().str()); + newNameLabel.setBuddy(&edit); + + actionsLayout.addWidget(&edit); + edit.setText(originalName); + edit.setFocus(); + edit.selectAll(); + QPushButton goButton(i18n("Rename")); + goButton.setToolTip(i18n("Note: All overloaded functions, overloads, forward-declarations, etc. will be renamed too")); + actionsLayout.addWidget(&goButton); + connect(&goButton, SIGNAL(clicked(bool)), dialog, SLOT(accept())); + + QPushButton cancelButton(i18n("Cancel")); + actionsLayout.addWidget(&cancelButton); + verticalLayout.addLayout(&actionsLayout); + + tabWidget.addTab(&uses, i18n("Uses")); + if (navigationWidget) + tabWidget.addTab(navigationWidget, i18n("Declaration Info")); + + verticalLayout.addWidget(&tabWidget); + + connect(&cancelButton, SIGNAL(clicked(bool)), dialog, SLOT(reject())); + + lock.unlock(); + dialog->resize(750, 550); + if (dialog->exec() != QDialog::Accepted) + return; + + replacementName = edit.text(); + if (replacementName == originalName || replacementName.isEmpty()) + return; + + DocumentChangeSet changes; + lock.lock(); + foreach (const KDevelop::IndexedTopDUContext &collected, collector->allUsingContexts()) { + QSet hadIndices; + foreach (const IndexedDeclaration &decl, collector->declarations()) { + uint usedDeclarationIndex = collected.data()->indexForUsedDeclaration(decl.data(), false); + if (hadIndices.contains(usedDeclarationIndex)) + continue; + hadIndices.insert(usedDeclarationIndex); + DocumentChangeSet::ChangeResult result = applyChanges(originalName, replacementName, changes, collected.data(), usedDeclarationIndex); + if (!result) { + KMessageBox::error(0, i18n("Applying changes failed: %1", result.m_failureReason)); + return; + } + } + } + + DocumentChangeSet::ChangeResult result = applyChangesToDeclarations(originalName, replacementName, changes, collector->declarations()); + if(!result) { + KMessageBox::error(0, i18n("Applying changes failed: %1", result.m_failureReason)); + return; + } + + ///We have to ignore failed changes for now, since uses of a constructor or of operator() may be created on "(" parens + changes.setReplacementPolicy(DocumentChangeSet::IgnoreFailedChange); + result = changes.applyAllChanges(); + if(!result) { + KMessageBox::error(0, i18n("Applying changes failed: %1", result.m_failureReason)); + return; + } +} + +bool BasicRefactoring::acceptForContextMenu(const Declaration *decl) +{ + // Default implementation. Some language plugins might override it to + // handle some cases. + Q_UNUSED(decl); + return true; +} + +void BasicRefactoring::executeRenameAction() +{ + QAction *action = qobject_cast(sender()); + if (action) { + IndexedDeclaration decl = action->data().value(); + if(!decl.isValid()) + decl = declarationUnderCursor(); + startInteractiveRename(decl); + } +} + +//END: BasicRefactoring + +} // End of namespace KDevelop + +#include "basicrefactoring.moc" diff --git a/language/codegen/basicrefactoring.h b/language/codegen/basicrefactoring.h new file mode 100644 index 0000000000..06606a5b87 --- /dev/null +++ b/language/codegen/basicrefactoring.h @@ -0,0 +1,112 @@ +/* This file is part of KDevelop + * + * Copyright 2014 Miquel Sabaté + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef BASICREFACTORING_H_ +#define BASICREFACTORING_H_ + + +#include +#include +#include +#include +#include + + +namespace KDevelop +{ +class ContextMenuExtension; +class IndexedDeclaration; +class Context; +class Declaration; +class DUContext; + + +/** + * A widget that show the uses that it has collected for + * the given declaration. + */ +class KDEVPLATFORMLANGUAGE_EXPORT BasicRefactoringCollector : public UsesWidget::UsesWidgetCollector +{ +public: + BasicRefactoringCollector(const IndexedDeclaration &decl); + QVector allUsingContexts() const; + +protected: + /// Process the uses for the given TopDUContext. + virtual void processUses(KDevelop::ReferencedTopDUContext topContext) override; + +private: + QVector m_allUsingContexts; +}; + +/// The base class for Refactoring classes from Language plugins. +class KDEVPLATFORMLANGUAGE_EXPORT BasicRefactoring : public QObject +{ + Q_OBJECT + +public: + explicit BasicRefactoring(QObject *parent = NULL); + + /// Update the context menu with the "Rename" action. + virtual void fillContextMenu(KDevelop::ContextMenuExtension &extension, KDevelop::Context *context); + +protected: + /** + * Apply the changes to the uses that can be found inside the given + * context and its children. + * NOTE: the DUChain must be locked. + */ + virtual DocumentChangeSet::ChangeResult applyChanges(const QString &oldName, const QString &newName, + DocumentChangeSet &changes, DUContext *context, + int usedDeclarationIndex); + + /** + * Apply the changes to the given declarations. + * NOTE: the DUChain must be locked. + */ + virtual DocumentChangeSet::ChangeResult applyChangesToDeclarations(const QString &oldName, const QString &newName, + DocumentChangeSet &changes, + const QList &declarations); + + /** + * Get the declaration under the current position of the cursor. + * + * @param allowUse Set to false if the declarations to be returned + * cannot come from uses. + */ + virtual IndexedDeclaration declarationUnderCursor(bool allowUse = true); + + /// Start the renaming of a declaration. + virtual void startInteractiveRename(const KDevelop::IndexedDeclaration &decl); + + /** + * @returns true if we can show the interactive rename widget for the + * given declaration. The default implementation just returns true. + */ + virtual bool acceptForContextMenu(const Declaration *decl); + +private slots: + void executeRenameAction(); +}; + +} // End of namespace KDevelop + +#endif /* BASICREFACTORING_H_ */