aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2023-11-28 14:40:53 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2023-11-30 12:42:04 +0000
commita6150da07668759382701546695eea53d9ec102e (patch)
tree680bac0375bf053636b76120ebe6b0a4426026dc
parent2bb29fd9b03b090f896ff2e61a1436bb73843298 (diff)
CppEditor: Adapt function declaration
... when changing the name of a function parameter from a point of use, rather than from the definition. The normal function decl/def link mechanism only covers editing in the signature. Task-number: QTCREATORBUG-29925 Change-Id: I34ff90117685184b9fc72937b401976274f4876c Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
-rw-r--r--src/plugins/cppeditor/CMakeLists.txt1
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs4
-rw-r--r--src/plugins/cppeditor/cppeditorwidget.cpp4
-rw-r--r--src/plugins/cppeditor/cppfunctionparamrenaminghandler.cpp112
-rw-r--r--src/plugins/cppeditor/cppfunctionparamrenaminghandler.h25
-rw-r--r--src/plugins/cppeditor/cpplocalrenaming.cpp1
-rw-r--r--src/plugins/cppeditor/cpplocalrenaming.h1
7 files changed, 146 insertions, 2 deletions
diff --git a/src/plugins/cppeditor/CMakeLists.txt b/src/plugins/cppeditor/CMakeLists.txt
index 49fe02c17e..66e25f08fe 100644
--- a/src/plugins/cppeditor/CMakeLists.txt
+++ b/src/plugins/cppeditor/CMakeLists.txt
@@ -48,6 +48,7 @@ add_qtc_plugin(CppEditor
cppfindreferences.cpp cppfindreferences.h
cppfollowsymbolundercursor.cpp cppfollowsymbolundercursor.h
cppfunctiondecldeflink.cpp cppfunctiondecldeflink.h
+ cppfunctionparamrenaminghandler.cpp cppfunctionparamrenaminghandler.h
cpphighlighter.cpp cpphighlighter.h
cppincludehierarchy.cpp cppincludehierarchy.h
cppincludesfilter.cpp cppincludesfilter.h
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index 45a7901817..2e8581a50c 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -108,6 +108,8 @@ QtcPlugin {
"cppfollowsymbolundercursor.h",
"cppfunctiondecldeflink.cpp",
"cppfunctiondecldeflink.h",
+ "cppfunctionparamrenaminghandler.cpp",
+ "cppfunctionparamrenaminghandler.h",
"cpphighlighter.cpp",
"cpphighlighter.h",
"cppincludehierarchy.cpp",
@@ -226,7 +228,7 @@ QtcPlugin {
"symbolsfindfilter.h",
"typehierarchybuilder.cpp",
"typehierarchybuilder.h",
- "wrappablelineedit.cpp", // FIXME: Is this used?
+ "wrappablelineedit.cpp",
"wrappablelineedit.h",
]
diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp
index dd49bbec90..aa112e0b48 100644
--- a/src/plugins/cppeditor/cppeditorwidget.cpp
+++ b/src/plugins/cppeditor/cppeditorwidget.cpp
@@ -11,13 +11,13 @@
#include "cppeditorplugin.h"
#include "cppeditortr.h"
#include "cppfunctiondecldeflink.h"
+#include "cppfunctionparamrenaminghandler.h"
#include "cpplocalrenaming.h"
#include "cppmodelmanager.h"
#include "cpppreprocessordialog.h"
#include "cppquickfixassistant.h"
#include "cppselectionchanger.h"
#include "cppsemanticinfo.h"
-#include "cpptoolssettings.h"
#include "cppuseselectionsupdater.h"
#include "doxygengenerator.h"
@@ -396,6 +396,7 @@ public:
QToolButton *m_preprocessorButton = nullptr;
CppLocalRenaming m_localRenaming;
+ CppFunctionParamRenamingHandler m_paramRenamingHandler;
CppUseSelectionsUpdater m_useSelectionsUpdater;
CppSelectionChanger m_cppSelectionChanger;
bool inTestMode = false;
@@ -405,6 +406,7 @@ CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
: m_cppEditorDocument(qobject_cast<CppEditorDocument *>(q->textDocument()))
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
, m_localRenaming(q)
+ , m_paramRenamingHandler(*q, m_localRenaming)
, m_useSelectionsUpdater(q)
, m_cppSelectionChanger()
{}
diff --git a/src/plugins/cppeditor/cppfunctionparamrenaminghandler.cpp b/src/plugins/cppeditor/cppfunctionparamrenaminghandler.cpp
new file mode 100644
index 0000000000..092e216b2d
--- /dev/null
+++ b/src/plugins/cppeditor/cppfunctionparamrenaminghandler.cpp
@@ -0,0 +1,112 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "cppfunctionparamrenaminghandler.h"
+
+#include "cppeditorwidget.h"
+#include "cpplocalrenaming.h"
+#include "cppfunctiondecldeflink.h"
+
+#include <cplusplus/AST.h>
+#include <cplusplus/ASTPath.h>
+#include <texteditor/textdocument.h>
+
+#include <memory>
+
+using namespace CPlusPlus;
+
+namespace CppEditor::Internal {
+
+using DeclDefLinkPtr = QSharedPointer<FunctionDeclDefLink>;
+
+class CppFunctionParamRenamingHandler::Private
+{
+public:
+ Private(CppEditorWidget &editorWidget, CppLocalRenaming &localRenaming);
+
+ void handleRenamingStarted();
+ void handleRenamingFinished();
+ void handleLinkFound(const DeclDefLinkPtr &link);
+ void findLink(FunctionDefinitionAST &func, const SemanticInfo &semanticInfo);
+
+ CppEditorWidget &editorWidget;
+ CppLocalRenaming &localRenaming;
+ std::unique_ptr<FunctionDeclDefLinkFinder> linkFinder;
+ DeclDefLinkPtr link;
+};
+
+CppFunctionParamRenamingHandler::CppFunctionParamRenamingHandler(
+ CppEditorWidget &editorWidget, CppLocalRenaming &localRenaming)
+ : d(new Private(editorWidget, localRenaming)) {}
+
+CppFunctionParamRenamingHandler::~CppFunctionParamRenamingHandler() { delete d; }
+
+CppFunctionParamRenamingHandler::Private::Private(
+ CppEditorWidget &editorWidget, CppLocalRenaming &localRenaming)
+ : editorWidget(editorWidget), localRenaming(localRenaming)
+{
+ QObject::connect(&localRenaming, &CppLocalRenaming::started,
+ &editorWidget, [this] { handleRenamingStarted(); });
+ QObject::connect(&localRenaming, &CppLocalRenaming::finished,
+ &editorWidget, [this] { handleRenamingFinished(); });
+}
+
+void CppFunctionParamRenamingHandler::Private::handleRenamingStarted()
+{
+ linkFinder.reset();
+ link.clear();
+
+ // Are we currently on the function signature? In this case, the normal decl/def link
+ // mechanism kicks in and we don't have to do anything.
+ if (editorWidget.declDefLink())
+ return;
+
+ // If we find a surrounding function definition, start up the decl/def link finder.
+ const SemanticInfo semanticInfo = editorWidget.semanticInfo();
+ if (!semanticInfo.doc || !semanticInfo.doc->translationUnit())
+ return;
+ const QList<AST *> astPath = ASTPath(semanticInfo.doc)(editorWidget.textCursor());
+ for (auto it = astPath.rbegin(); it != astPath.rend(); ++it) {
+ if (const auto func = (*it)->asFunctionDefinition()) {
+ findLink(*func, semanticInfo);
+ return;
+ }
+ }
+}
+
+void CppFunctionParamRenamingHandler::Private::handleRenamingFinished()
+{
+ if (link) {
+ link->apply(&editorWidget, false);
+ link.clear();
+ }
+}
+
+void CppFunctionParamRenamingHandler::Private::handleLinkFound(const DeclDefLinkPtr &link)
+{
+ if (localRenaming.isActive())
+ this->link = link;
+ linkFinder.reset();
+}
+
+void CppFunctionParamRenamingHandler::Private::findLink(FunctionDefinitionAST &func,
+ const SemanticInfo &semanticInfo)
+{
+ if (!func.declarator)
+ return;
+
+ // The finder needs a cursor that points to the signature, so provide one.
+ QTextDocument * const doc = editorWidget.textDocument()->document();
+ const int pos = semanticInfo.doc->translationUnit()->getTokenEndPositionInDocument(
+ func.declarator->firstToken(), doc);
+ QTextCursor cursor(doc);
+ cursor.setPosition(pos);
+ linkFinder.reset(new FunctionDeclDefLinkFinder);
+ QObject::connect(linkFinder.get(), &FunctionDeclDefLinkFinder::foundLink,
+ &editorWidget, [this](const DeclDefLinkPtr &link) {
+ handleLinkFound(link);
+ });
+ linkFinder->startFindLinkAt(cursor, semanticInfo.doc, semanticInfo.snapshot);
+}
+
+} // namespace CppEditor::Internal
diff --git a/src/plugins/cppeditor/cppfunctionparamrenaminghandler.h b/src/plugins/cppeditor/cppfunctionparamrenaminghandler.h
new file mode 100644
index 0000000000..e923855ca6
--- /dev/null
+++ b/src/plugins/cppeditor/cppfunctionparamrenaminghandler.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+namespace CppEditor {
+class CppEditorWidget;
+
+namespace Internal {
+class CppLocalRenaming;
+
+// Watches local renamings and adapts the declaration if a function parameter was renamed.
+class CppFunctionParamRenamingHandler
+{
+public:
+ CppFunctionParamRenamingHandler(CppEditorWidget &editorWidget, CppLocalRenaming &localRenaming);
+ ~CppFunctionParamRenamingHandler();
+
+private:
+ class Private;
+ Private * const d;
+};
+
+} // namespace Internal
+} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cpplocalrenaming.cpp b/src/plugins/cppeditor/cpplocalrenaming.cpp
index f23b9d80a6..5bad16a0b6 100644
--- a/src/plugins/cppeditor/cpplocalrenaming.cpp
+++ b/src/plugins/cppeditor/cpplocalrenaming.cpp
@@ -62,6 +62,7 @@ bool CppLocalRenaming::start()
updateRenamingSelectionFormat(textCharFormat(TextEditor::C_OCCURRENCES_RENAME));
m_firstRenameChangeExpected = true;
updateEditorWidgetWithSelections();
+ emit started();
return true;
}
diff --git a/src/plugins/cppeditor/cpplocalrenaming.h b/src/plugins/cppeditor/cpplocalrenaming.h
index 082d4648a8..56ff153044 100644
--- a/src/plugins/cppeditor/cpplocalrenaming.h
+++ b/src/plugins/cppeditor/cpplocalrenaming.h
@@ -41,6 +41,7 @@ public:
bool isSameSelection(int cursorPosition) const;
signals:
+ void started();
void finished();
void processKeyPressNormally(QKeyEvent *e);