Commit 76d12dc2 authored by Ivan Donchevskii's avatar Ivan Donchevskii

CppEditor: add default RefactoringEngine

..and use it when we don't have refactoring plug-in

Change-Id: Ibe317a9728d439b9c5e05271d92a330d22eaacb9
Reviewed-by: Nikolai Kosjar's avatarNikolai Kosjar <nikolai.kosjar@qt.io>
parent 62ada960
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <cpptools/clangcompileroptionsbuilder.h> #include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
#include <texteditor/textdocument.h>
#include <QTextCursor> #include <QTextCursor>
#include <QTextDocument> #include <QTextDocument>
...@@ -50,9 +52,7 @@ RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &s ...@@ -50,9 +52,7 @@ RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &s
{ {
} }
void RefactoringEngine::startLocalRenaming(const QTextCursor &textCursor, void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
const Utils::FileName &filePath,
int revision,
CppTools::ProjectPart *projectPart, CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) RenameCallback &&renameSymbolsCallback)
{ {
...@@ -62,21 +62,23 @@ void RefactoringEngine::startLocalRenaming(const QTextCursor &textCursor, ...@@ -62,21 +62,23 @@ void RefactoringEngine::startLocalRenaming(const QTextCursor &textCursor,
client.setLocalRenamingCallback(std::move(renameSymbolsCallback)); client.setLocalRenamingCallback(std::move(renameSymbolsCallback));
QString filePath = data.filePath().toString();
QTextCursor textCursor = data.cursor();
Utils::SmallStringVector commandLine{ClangCompilerOptionsBuilder::build( Utils::SmallStringVector commandLine{ClangCompilerOptionsBuilder::build(
projectPart, projectPart,
fileKindInProjectPart(projectPart, filePath.toString()), fileKindInProjectPart(projectPart, filePath),
CppTools::getPchUsage(), CppTools::getPchUsage(),
CLANG_VERSION, CLANG_VERSION,
CLANG_RESOURCE_DIR)}; CLANG_RESOURCE_DIR)};
commandLine.push_back(filePath.toString()); commandLine.push_back(filePath);
RequestSourceLocationsForRenamingMessage message(ClangBackEnd::FilePath(filePath.toString()), RequestSourceLocationsForRenamingMessage message(ClangBackEnd::FilePath(filePath),
uint(textCursor.blockNumber() + 1), uint(textCursor.blockNumber() + 1),
uint(textCursor.positionInBlock() + 1), uint(textCursor.positionInBlock() + 1),
textCursor.document()->toPlainText(), textCursor.document()->toPlainText(),
std::move(commandLine), std::move(commandLine),
revision); textCursor.document()->revision());
server.requestSourceLocationsForRenamingMessage(std::move(message)); server.requestSourceLocationsForRenamingMessage(std::move(message));
......
...@@ -39,9 +39,7 @@ class RefactoringEngine : public CppTools::RefactoringEngineInterface ...@@ -39,9 +39,7 @@ class RefactoringEngine : public CppTools::RefactoringEngineInterface
public: public:
RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server, RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server,
ClangBackEnd::RefactoringClientInterface &client); ClangBackEnd::RefactoringClientInterface &client);
void startLocalRenaming(const QTextCursor &textCursor, void startLocalRenaming(const CppTools::CursorInEditor &data,
const Utils::FileName &filePath,
int revision,
CppTools::ProjectPart *projectPart, CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) override; RenameCallback &&renameSymbolsCallback) override;
......
...@@ -27,6 +27,7 @@ HEADERS += \ ...@@ -27,6 +27,7 @@ HEADERS += \
cppquickfix.h \ cppquickfix.h \
cppquickfixassistant.h \ cppquickfixassistant.h \
cppquickfixes.h \ cppquickfixes.h \
cpprefactoringengine.h \
cpptypehierarchy.h \ cpptypehierarchy.h \
cppuseselectionsupdater.h \ cppuseselectionsupdater.h \
cppvirtualfunctionassistprovider.h \ cppvirtualfunctionassistprovider.h \
...@@ -56,6 +57,7 @@ SOURCES += \ ...@@ -56,6 +57,7 @@ SOURCES += \
cppquickfix.cpp \ cppquickfix.cpp \
cppquickfixassistant.cpp \ cppquickfixassistant.cpp \
cppquickfixes.cpp \ cppquickfixes.cpp \
cpprefactoringengine.cpp \
cpptypehierarchy.cpp \ cpptypehierarchy.cpp \
cppuseselectionsupdater.cpp \ cppuseselectionsupdater.cpp \
cppvirtualfunctionassistprovider.cpp \ cppvirtualfunctionassistprovider.cpp \
......
...@@ -70,6 +70,8 @@ QtcPlugin { ...@@ -70,6 +70,8 @@ QtcPlugin {
"cppquickfixassistant.h", "cppquickfixassistant.h",
"cppquickfixes.cpp", "cppquickfixes.cpp",
"cppquickfixes.h", "cppquickfixes.h",
"cpprefactoringengine.cpp",
"cpprefactoringengine.h",
"cpptypehierarchy.cpp", "cpptypehierarchy.cpp",
"cpptypehierarchy.h", "cpptypehierarchy.h",
"cppuseselectionsupdater.cpp", "cppuseselectionsupdater.cpp",
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "cppminimizableinfobars.h" #include "cppminimizableinfobars.h"
#include "cpppreprocessordialog.h" #include "cpppreprocessordialog.h"
#include "cppquickfixassistant.h" #include "cppquickfixassistant.h"
#include "cpprefactoringengine.h"
#include "cppuseselectionsupdater.h" #include "cppuseselectionsupdater.h"
#include <clangsupport/sourcelocationscontainer.h> #include <clangsupport/sourcelocationscontainer.h>
...@@ -116,33 +117,30 @@ public: ...@@ -116,33 +117,30 @@ public:
CppEditorOutline *m_cppEditorOutline; CppEditorOutline *m_cppEditorOutline;
QTimer m_updateFunctionDeclDefLinkTimer; QTimer m_updateFunctionDeclDefLinkTimer;
CppLocalRenaming m_localRenaming;
SemanticInfo m_lastSemanticInfo; SemanticInfo m_lastSemanticInfo;
CppUseSelectionsUpdater m_useSelectionsUpdater;
FunctionDeclDefLinkFinder *m_declDefLinkFinder; FunctionDeclDefLinkFinder *m_declDefLinkFinder;
QSharedPointer<FunctionDeclDefLink> m_declDefLink; QSharedPointer<FunctionDeclDefLink> m_declDefLink;
QScopedPointer<FollowSymbolUnderCursor> m_followSymbolUnderCursor;
QAction *m_parseContextAction = nullptr; QAction *m_parseContextAction = nullptr;
ParseContextWidget *m_parseContextWidget = nullptr; ParseContextWidget *m_parseContextWidget = nullptr;
QToolButton *m_preprocessorButton = nullptr; QToolButton *m_preprocessorButton = nullptr;
MinimizableInfoBars::Actions m_showInfoBarActions; MinimizableInfoBars::Actions m_showInfoBarActions;
CppLocalRenaming m_localRenaming;
CppUseSelectionsUpdater m_useSelectionsUpdater;
QScopedPointer<FollowSymbolUnderCursor> m_followSymbolUnderCursor;
CppSelectionChanger m_cppSelectionChanger; CppSelectionChanger m_cppSelectionChanger;
CppRefactoringEngine m_builtinRefactoringEngine;
}; };
CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q) CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
: m_modelManager(CppModelManager::instance()) : m_modelManager(CppModelManager::instance())
, m_cppEditorDocument(qobject_cast<CppEditorDocument *>(q->textDocument())) , m_cppEditorDocument(qobject_cast<CppEditorDocument *>(q->textDocument()))
, m_cppEditorOutline(new CppEditorOutline(q)) , m_cppEditorOutline(new CppEditorOutline(q))
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
, m_localRenaming(q) , m_localRenaming(q)
, m_useSelectionsUpdater(q) , m_useSelectionsUpdater(q)
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
, m_followSymbolUnderCursor(new FollowSymbolUnderCursor(q)) , m_followSymbolUnderCursor(new FollowSymbolUnderCursor(q))
, m_cppSelectionChanger() , m_cppSelectionChanger()
{} {}
...@@ -434,23 +432,6 @@ bool CppEditorWidget::isWidgetHighlighted(QWidget *widget) ...@@ -434,23 +432,6 @@ bool CppEditorWidget::isWidgetHighlighted(QWidget *widget)
return widget ? widget->property("highlightWidget").toBool() : false; return widget ? widget->property("highlightWidget").toBool() : false;
} }
void CppEditorWidget::renameSymbolUnderCursor()
{
if (refactoringEngine())
renameSymbolUnderCursorClang();
else
renameSymbolUnderCursorBuiltin();
}
void CppEditorWidget::renameSymbolUnderCursorBuiltin()
{
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
/*updateUseSelectionSynchronously=*/true);
if (!d->m_localRenaming.start()) // Rename local symbol
renameUsages(); // Rename non-local symbol or macro
}
namespace { namespace {
QList<ProjectPart::Ptr> fetchProjectParts(CppTools::CppModelManager *modelManager, QList<ProjectPart::Ptr> fetchProjectParts(CppTools::CppModelManager *modelManager,
...@@ -538,44 +519,45 @@ QList<QTextEdit::ExtraSelection> sourceLocationsToExtraSelections( ...@@ -538,44 +519,45 @@ QList<QTextEdit::ExtraSelection> sourceLocationsToExtraSelections(
} }
void CppEditorWidget::renameSymbolUnderCursorClang() void CppEditorWidget::renameSymbolUnderCursor()
{ {
using ClangBackEnd::SourceLocationsContainer; using ClangBackEnd::SourceLocationsContainer;
ProjectPart *theProjectPart = projectPart(); ProjectPart *projPart = projectPart();
if (refactoringEngine()->isUsable() && theProjectPart) { if (!refactoringEngine()->isUsable() || !projPart)
d->m_useSelectionsUpdater.abortSchedule(); return;
QPointer<CppEditorWidget> cppEditorWidget = this;
auto renameSymbols = [=](const QString &symbolName,
const SourceLocationsContainer &sourceLocations,
int revision) {
if (cppEditorWidget) {
viewport()->setCursor(Qt::IBeamCursor);
if (revision == document()->revision()) {
auto selections
= sourceLocationsToExtraSelections(sourceLocations.sourceLocationContainers(),
symbolName.size(),
cppEditorWidget);
setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection,
selections);
d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections);
if (!d->m_localRenaming.start())
renameUsages();
}
}
};
refactoringEngine()->startLocalRenaming(textCursor(), d->m_useSelectionsUpdater.abortSchedule();
textDocument()->filePath(),
document()->revision(), QPointer<CppEditorWidget> cppEditorWidget = this;
theProjectPart,
std::move(renameSymbols)); auto renameSymbols = [=](const QString &symbolName,
const SourceLocationsContainer &sourceLocations,
int revision) {
if (cppEditorWidget) {
viewport()->setCursor(Qt::IBeamCursor);
if (revision != document()->revision())
return;
if (sourceLocations.hasContent()) {
QList<QTextEdit::ExtraSelection> selections
= sourceLocationsToExtraSelections(sourceLocations.sourceLocationContainers(),
static_cast<uint>(symbolName.size()),
cppEditorWidget);
setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections);
d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections);
}
if (!d->m_localRenaming.start()) // Rename local symbol
renameUsages(); // Rename non-local symbol or macro
}
};
viewport()->setCursor(Qt::BusyCursor); viewport()->setCursor(Qt::BusyCursor);
} refactoringEngine()->startLocalRenaming(CppTools::CursorInEditor{textCursor(),
textDocument()->filePath(),
this},
projPart,
std::move(renameSymbols));
} }
void CppEditorWidget::updatePreprocessorButtonTooltip() void CppEditorWidget::updatePreprocessorButtonTooltip()
...@@ -700,7 +682,9 @@ RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() const ...@@ -700,7 +682,9 @@ RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() const
RefactoringEngineInterface *CppEditorWidget::refactoringEngine() const RefactoringEngineInterface *CppEditorWidget::refactoringEngine() const
{ {
return CppTools::CppModelManager::refactoringEngine(); RefactoringEngineInterface *engine = CppTools::CppModelManager::refactoringEngine();
return engine ? engine
: static_cast<RefactoringEngineInterface *>(&d->m_builtinRefactoringEngine);
} }
bool CppEditorWidget::isSemanticInfoValidExceptLocalUses() const bool CppEditorWidget::isSemanticInfoValidExceptLocalUses() const
...@@ -845,6 +829,12 @@ void CppEditorWidget::slotCodeStyleSettingsChanged(const QVariant &) ...@@ -845,6 +829,12 @@ void CppEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
formatter.invalidateCache(document()); formatter.invalidateCache(document());
} }
void CppEditorWidget::updateSemanticInfo()
{
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
/*updateUseSelectionSynchronously=*/ true);
}
void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo, void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo,
bool updateUseSelectionSynchronously) bool updateUseSelectionSynchronously)
{ {
......
...@@ -88,6 +88,7 @@ public: ...@@ -88,6 +88,7 @@ public:
static void updateWidgetHighlighting(QWidget *widget, bool highlight); static void updateWidgetHighlighting(QWidget *widget, bool highlight);
static bool isWidgetHighlighted(QWidget *widget); static bool isWidgetHighlighted(QWidget *widget);
void updateSemanticInfo();
protected: protected:
bool event(QEvent *e) override; bool event(QEvent *e) override;
void contextMenuEvent(QContextMenuEvent *) override; void contextMenuEvent(QContextMenuEvent *) override;
...@@ -132,9 +133,6 @@ private: ...@@ -132,9 +133,6 @@ private:
CppTools::RefactoringEngineInterface *refactoringEngine() const; CppTools::RefactoringEngineInterface *refactoringEngine() const;
void renameSymbolUnderCursorClang();
void renameSymbolUnderCursorBuiltin();
CppTools::ProjectPart *projectPart() const; CppTools::ProjectPart *projectPart() const;
private: private:
......
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "cpprefactoringengine.h"
#include "cppeditorwidget.h"
#include "utils/qtcassert.h"
namespace CppEditor {
namespace Internal {
void CppRefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *,
RenameCallback &&renameSymbolsCallback)
{
CppEditorWidget *editorWidget = static_cast<CppEditorWidget *>(data.editorWidget());
QTC_ASSERT(editorWidget, renameSymbolsCallback(QString(),
ClangBackEnd::SourceLocationsContainer(),
0); return;);
editorWidget->updateSemanticInfo();
// Call empty callback
renameSymbolsCallback(QString(),
ClangBackEnd::SourceLocationsContainer(),
editorWidget->document()->revision());
}
} // namespace Internal
} // namespace CppEditor
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <cpptools/refactoringengineinterface.h>
namespace CppEditor {
namespace Internal {
class CppEditorWidget;
class CppRefactoringEngine : public CppTools::RefactoringEngineInterface
{
public:
void startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) override;
bool isUsable() const override { return true; }
};
} // namespace Internal
} // namespace CppEditor
...@@ -87,7 +87,8 @@ HEADERS += \ ...@@ -87,7 +87,8 @@ HEADERS += \
cppprojectfilecategorizer.h \ cppprojectfilecategorizer.h \
clangcompileroptionsbuilder.h \ clangcompileroptionsbuilder.h \
cppprojectpartchooser.h \ cppprojectpartchooser.h \
cppsymbolinfo.h cppsymbolinfo.h \
cursorineditor.h
SOURCES += \ SOURCES += \
abstracteditorsupport.cpp \ abstracteditorsupport.cpp \
......
...@@ -159,6 +159,7 @@ Project { ...@@ -159,6 +159,7 @@ Project {
"cpptoolssettings.h", "cpptoolssettings.h",
"cppworkingcopy.cpp", "cppworkingcopy.cpp",
"cppworkingcopy.h", "cppworkingcopy.h",
"cursorineditor.h",
"doxygengenerator.cpp", "doxygengenerator.cpp",
"doxygengenerator.h", "doxygengenerator.h",
"editordocumenthandle.cpp", "editordocumenthandle.cpp",
......
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QTextCursor>
#include <utils/fileutils.h>
namespace TextEditor {
class TextEditorWidget;
} // namespace TextEditor
namespace CppTools {
class CursorInEditor
{
public:
CursorInEditor(const QTextCursor &cursor, const Utils::FileName &filePath,
TextEditor::TextEditorWidget *editorWidget = nullptr)
: m_cursor(cursor)
, m_filePath(filePath)
, m_editorWidget(editorWidget)
{}
TextEditor::TextEditorWidget *editorWidget() const { return m_editorWidget; }
const QTextCursor &cursor() const { return m_cursor; }
const Utils::FileName &filePath() const { return m_filePath; }
private:
QTextCursor m_cursor;
Utils::FileName m_filePath;
TextEditor::TextEditorWidget *m_editorWidget = nullptr;
};
} // namespace CppTools
...@@ -25,18 +25,18 @@ ...@@ -25,18 +25,18 @@
#pragma once #pragma once
#include "cursorineditor.h"
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <clangsupport/sourcelocationscontainer.h> #include <clangsupport/sourcelocationscontainer.h>
#include <clangsupport/refactoringclientinterface.h> #include <clangsupport/refactoringclientinterface.h>
QT_BEGIN_NAMESPACE namespace TextEditor {
class QTextCursor; class TextEditorWidget;
QT_END_NAMESPACE } // namespace TextEditor
namespace CppTools { namespace CppTools {
class CppEditorWidget;
class ProjectPart; class ProjectPart;
enum class CallType enum class CallType
...@@ -45,19 +45,17 @@ enum class CallType ...@@ -45,19 +45,17 @@ enum class CallType
Asynchronous Asynchronous
}; };
// NOTE: This interface is not supposed to be owned as an interface pointer
class RefactoringEngineInterface class RefactoringEngineInterface
{ {
public: public:
using RenameCallback = ClangBackEnd::RefactoringClientInterface::RenameCallback; using RenameCallback = ClangBackEnd::RefactoringClientInterface::RenameCallback;
virtual void startLocalRenaming(const QTextCursor &textCursor, virtual void startLocalRenaming(const CursorInEditor &data,
const Utils::FileName &filePath,
int revision,
CppTools::ProjectPart *projectPart, CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) = 0; RenameCallback &&renameSymbolsCallback) = 0;
virtual bool isUsable() const = 0; virtual bool isUsable() const = 0;
}; };
} // namespace CppTools } // namespace CppTools
...@@ -125,9 +125,7 @@ TEST_F(RefactoringClient, AfterSourceLocationsForRenamingEngineIsUsableAgain) ...@@ -125,9 +125,7 @@ TEST_F(RefactoringClient, AfterSourceLocationsForRenamingEngineIsUsableAgain)
TEST_F(RefactoringClient, AfterStartLocalRenameHasValidCallback) TEST_F(RefactoringClient, AfterStartLocalRenameHasValidCallback)
{ {
engine.startLocalRenaming(cursor, engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath},
filePath,
textDocument.revision(),