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 @@
#include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/cpptoolsreuse.h>
#include <texteditor/textdocument.h>
#include <QTextCursor>
#include <QTextDocument>
......@@ -50,9 +52,7 @@ RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &s
{
}
void RefactoringEngine::startLocalRenaming(const QTextCursor &textCursor,
const Utils::FileName &filePath,
int revision,
void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback)
{
......@@ -62,21 +62,23 @@ void RefactoringEngine::startLocalRenaming(const QTextCursor &textCursor,
client.setLocalRenamingCallback(std::move(renameSymbolsCallback));
QString filePath = data.filePath().toString();
QTextCursor textCursor = data.cursor();
Utils::SmallStringVector commandLine{ClangCompilerOptionsBuilder::build(
projectPart,
fileKindInProjectPart(projectPart, filePath.toString()),
fileKindInProjectPart(projectPart, filePath),
CppTools::getPchUsage(),
CLANG_VERSION,
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.positionInBlock() + 1),
textCursor.document()->toPlainText(),
std::move(commandLine),
revision);
textCursor.document()->revision());
server.requestSourceLocationsForRenamingMessage(std::move(message));
......
......@@ -39,9 +39,7 @@ class RefactoringEngine : public CppTools::RefactoringEngineInterface
public:
RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server,
ClangBackEnd::RefactoringClientInterface &client);
void startLocalRenaming(const QTextCursor &textCursor,
const Utils::FileName &filePath,
int revision,
void startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) override;
......
......@@ -27,6 +27,7 @@ HEADERS += \
cppquickfix.h \
cppquickfixassistant.h \
cppquickfixes.h \
cpprefactoringengine.h \
cpptypehierarchy.h \
cppuseselectionsupdater.h \
cppvirtualfunctionassistprovider.h \
......@@ -56,6 +57,7 @@ SOURCES += \
cppquickfix.cpp \
cppquickfixassistant.cpp \
cppquickfixes.cpp \
cpprefactoringengine.cpp \
cpptypehierarchy.cpp \
cppuseselectionsupdater.cpp \
cppvirtualfunctionassistprovider.cpp \
......
......@@ -70,6 +70,8 @@ QtcPlugin {
"cppquickfixassistant.h",
"cppquickfixes.cpp",
"cppquickfixes.h",
"cpprefactoringengine.cpp",
"cpprefactoringengine.h",
"cpptypehierarchy.cpp",
"cpptypehierarchy.h",
"cppuseselectionsupdater.cpp",
......
......@@ -37,6 +37,7 @@
#include "cppminimizableinfobars.h"
#include "cpppreprocessordialog.h"
#include "cppquickfixassistant.h"
#include "cpprefactoringengine.h"
#include "cppuseselectionsupdater.h"
#include <clangsupport/sourcelocationscontainer.h>
......@@ -116,33 +117,30 @@ public:
CppEditorOutline *m_cppEditorOutline;
QTimer m_updateFunctionDeclDefLinkTimer;
CppLocalRenaming m_localRenaming;
SemanticInfo m_lastSemanticInfo;
CppUseSelectionsUpdater m_useSelectionsUpdater;
FunctionDeclDefLinkFinder *m_declDefLinkFinder;
QSharedPointer<FunctionDeclDefLink> m_declDefLink;
QScopedPointer<FollowSymbolUnderCursor> m_followSymbolUnderCursor;
QAction *m_parseContextAction = nullptr;
ParseContextWidget *m_parseContextWidget = nullptr;
QToolButton *m_preprocessorButton = nullptr;
MinimizableInfoBars::Actions m_showInfoBarActions;
CppLocalRenaming m_localRenaming;
CppUseSelectionsUpdater m_useSelectionsUpdater;
QScopedPointer<FollowSymbolUnderCursor> m_followSymbolUnderCursor;
CppSelectionChanger m_cppSelectionChanger;
CppRefactoringEngine m_builtinRefactoringEngine;
};
CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
: m_modelManager(CppModelManager::instance())
, m_cppEditorDocument(qobject_cast<CppEditorDocument *>(q->textDocument()))
, m_cppEditorOutline(new CppEditorOutline(q))
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
, m_localRenaming(q)
, m_useSelectionsUpdater(q)
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
, m_followSymbolUnderCursor(new FollowSymbolUnderCursor(q))
, m_cppSelectionChanger()
{}
......@@ -434,23 +432,6 @@ bool CppEditorWidget::isWidgetHighlighted(QWidget *widget)
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 {
QList<ProjectPart::Ptr> fetchProjectParts(CppTools::CppModelManager *modelManager,
......@@ -538,12 +519,14 @@ QList<QTextEdit::ExtraSelection> sourceLocationsToExtraSelections(
}
void CppEditorWidget::renameSymbolUnderCursorClang()
void CppEditorWidget::renameSymbolUnderCursor()
{
using ClangBackEnd::SourceLocationsContainer;
ProjectPart *theProjectPart = projectPart();
if (refactoringEngine()->isUsable() && theProjectPart) {
ProjectPart *projPart = projectPart();
if (!refactoringEngine()->isUsable() || !projPart)
return;
d->m_useSelectionsUpdater.abortSchedule();
QPointer<CppEditorWidget> cppEditorWidget = this;
......@@ -554,28 +537,27 @@ void CppEditorWidget::renameSymbolUnderCursorClang()
if (cppEditorWidget) {
viewport()->setCursor(Qt::IBeamCursor);
if (revision == document()->revision()) {
auto selections
if (revision != document()->revision())
return;
if (sourceLocations.hasContent()) {
QList<QTextEdit::ExtraSelection> selections
= sourceLocationsToExtraSelections(sourceLocations.sourceLocationContainers(),
symbolName.size(),
static_cast<uint>(symbolName.size()),
cppEditorWidget);
setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection,
selections);
setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections);
d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections);
if (!d->m_localRenaming.start())
renameUsages();
}
if (!d->m_localRenaming.start()) // Rename local symbol
renameUsages(); // Rename non-local symbol or macro
}
};
refactoringEngine()->startLocalRenaming(textCursor(),
viewport()->setCursor(Qt::BusyCursor);
refactoringEngine()->startLocalRenaming(CppTools::CursorInEditor{textCursor(),
textDocument()->filePath(),
document()->revision(),
theProjectPart,
this},
projPart,
std::move(renameSymbols));
viewport()->setCursor(Qt::BusyCursor);
}
}
void CppEditorWidget::updatePreprocessorButtonTooltip()
......@@ -700,7 +682,9 @@ RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() 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
......@@ -845,6 +829,12 @@ void CppEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
formatter.invalidateCache(document());
}
void CppEditorWidget::updateSemanticInfo()
{
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
/*updateUseSelectionSynchronously=*/ true);
}
void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo,
bool updateUseSelectionSynchronously)
{
......
......@@ -88,6 +88,7 @@ public:
static void updateWidgetHighlighting(QWidget *widget, bool highlight);
static bool isWidgetHighlighted(QWidget *widget);
void updateSemanticInfo();
protected:
bool event(QEvent *e) override;
void contextMenuEvent(QContextMenuEvent *) override;
......@@ -132,9 +133,6 @@ private:
CppTools::RefactoringEngineInterface *refactoringEngine() const;
void renameSymbolUnderCursorClang();
void renameSymbolUnderCursorBuiltin();
CppTools::ProjectPart *projectPart() const;
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 += \
cppprojectfilecategorizer.h \
clangcompileroptionsbuilder.h \
cppprojectpartchooser.h \
cppsymbolinfo.h
cppsymbolinfo.h \
cursorineditor.h
SOURCES += \
abstracteditorsupport.cpp \
......
......@@ -159,6 +159,7 @@ Project {
"cpptoolssettings.h",
"cppworkingcopy.cpp",
"cppworkingcopy.h",
"cursorineditor.h",
"doxygengenerator.cpp",
"doxygengenerator.h",
"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 @@
#pragma once
#include "cursorineditor.h"
#include <utils/fileutils.h>
#include <clangsupport/sourcelocationscontainer.h>
#include <clangsupport/refactoringclientinterface.h>
QT_BEGIN_NAMESPACE
class QTextCursor;
QT_END_NAMESPACE
namespace TextEditor {
class TextEditorWidget;
} // namespace TextEditor
namespace CppTools {
class CppEditorWidget;
class ProjectPart;
enum class CallType
......@@ -45,19 +45,17 @@ enum class CallType
Asynchronous
};
// NOTE: This interface is not supposed to be owned as an interface pointer
class RefactoringEngineInterface
{
public:
using RenameCallback = ClangBackEnd::RefactoringClientInterface::RenameCallback;
virtual void startLocalRenaming(const QTextCursor &textCursor,
const Utils::FileName &filePath,
int revision,
virtual void startLocalRenaming(const CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) = 0;
virtual bool isUsable() const = 0;
};
} // namespace CppTools
......@@ -125,9 +125,7 @@ TEST_F(RefactoringClient, AfterSourceLocationsForRenamingEngineIsUsableAgain)
TEST_F(RefactoringClient, AfterStartLocalRenameHasValidCallback)
{
engine.startLocalRenaming(cursor,
filePath,
textDocument.revision(),
engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath},
projectPart.data(),
[&] (const QString &,
const ClangBackEnd::SourceLocationsContainer &,
......
......@@ -86,14 +86,16 @@ TEST_F(RefactoringEngine, SendRequestSourceLocationsForRenamingMessage)
EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(message))
.Times(1);
engine.startLocalRenaming(cursor, filePath, textDocument.revision(), projectPart.data(), {});
engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath},
projectPart.data(), {});
}
TEST_F(RefactoringEngine, AfterSendRequestSourceLocationsForRenamingMessageIsUnusable)
{
EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(_));
engine.startLocalRenaming(cursor, filePath, textDocument.revision(), projectPart.data(), {});
engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath},
projectPart.data(), {});
ASSERT_FALSE(engine.isUsable());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment