Clang: use local renaming based on ClangCodeModel

Provide refactoring engine for ClangCodeModel and
implement missing methods.

Change-Id: If5c913e0c5a7941cd2ced54d0fcfa4d625eadc93
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Ivan Donchevskii
2017-09-26 16:00:30 +02:00
parent 94e818dc82
commit 32bae7ef6c
30 changed files with 275 additions and 21 deletions

View File

@@ -41,6 +41,7 @@ QDebug operator<<(QDebug debug, const RequestReferencesMessage &message)
debug.nospace() << message.m_ticketNumber << ", "; debug.nospace() << message.m_ticketNumber << ", ";
debug.nospace() << message.m_line << ", "; debug.nospace() << message.m_line << ", ";
debug.nospace() << message.m_column << ", "; debug.nospace() << message.m_column << ", ";
debug.nospace() << message.m_local << ", ";
debug.nospace() << ")"; debug.nospace() << ")";
@@ -54,6 +55,7 @@ std::ostream &operator<<(std::ostream &os, const RequestReferencesMessage &messa
<< message.m_ticketNumber << ", " << message.m_ticketNumber << ", "
<< message.m_line << ", " << message.m_line << ", "
<< message.m_column << ", " << message.m_column << ", "
<< message.m_local << ", "
<< ")"; << ")";
return os; return os;

View File

@@ -39,11 +39,13 @@ public:
RequestReferencesMessage() = default; RequestReferencesMessage() = default;
RequestReferencesMessage(const FileContainer &fileContainer, RequestReferencesMessage(const FileContainer &fileContainer,
quint32 line, quint32 line,
quint32 column) quint32 column,
bool local = false)
: m_fileContainer(fileContainer) : m_fileContainer(fileContainer)
, m_ticketNumber(++ticketCounter) , m_ticketNumber(++ticketCounter)
, m_line(line) , m_line(line)
, m_column(column) , m_column(column)
, m_local(local)
{ {
} }
@@ -67,12 +69,18 @@ public:
return m_ticketNumber; return m_ticketNumber;
} }
bool local() const
{
return m_local;
}
friend QDataStream &operator<<(QDataStream &out, const RequestReferencesMessage &message) friend QDataStream &operator<<(QDataStream &out, const RequestReferencesMessage &message)
{ {
out << message.m_fileContainer; out << message.m_fileContainer;
out << message.m_ticketNumber; out << message.m_ticketNumber;
out << message.m_line; out << message.m_line;
out << message.m_column; out << message.m_column;
out << message.m_local;
return out; return out;
} }
@@ -83,6 +91,7 @@ public:
in >> message.m_ticketNumber; in >> message.m_ticketNumber;
in >> message.m_line; in >> message.m_line;
in >> message.m_column; in >> message.m_column;
in >> message.m_local;
return in; return in;
} }
@@ -93,7 +102,8 @@ public:
return first.m_ticketNumber == second.m_ticketNumber return first.m_ticketNumber == second.m_ticketNumber
&& first.m_line == second.m_line && first.m_line == second.m_line
&& first.m_column == second.m_column && first.m_column == second.m_column
&& first.m_fileContainer == second.m_fileContainer; && first.m_fileContainer == second.m_fileContainer
&& first.m_local == second.m_local;
} }
friend CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const RequestReferencesMessage &message); friend CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const RequestReferencesMessage &message);
@@ -104,6 +114,7 @@ private:
quint64 m_ticketNumber = 0; quint64 m_ticketNumber = 0;
quint32 m_line = 0; quint32 m_line = 0;
quint32 m_column = 0; quint32 m_column = 0;
bool m_local = false;
static CLANGSUPPORT_EXPORT quint64 ticketCounter; static CLANGSUPPORT_EXPORT quint64 ticketCounter;
}; };

View File

@@ -380,6 +380,18 @@ QFuture<CppTools::CursorInfo> BackendCommunicator::requestReferences(
localUses); localUses);
} }
QFuture<CppTools::CursorInfo> BackendCommunicator::requestLocalReferences(
const FileContainer &fileContainer,
quint32 line,
quint32 column,
QTextDocument *textDocument)
{
const RequestReferencesMessage message(fileContainer, line, column, true);
m_sender->requestReferences(message);
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument);
}
QFuture<CppTools::SymbolInfo> BackendCommunicator::requestFollowSymbol( QFuture<CppTools::SymbolInfo> BackendCommunicator::requestFollowSymbol(
const FileContainer &curFileContainer, const FileContainer &curFileContainer,
const QVector<Utf8String> &dependentFiles, const QVector<Utf8String> &dependentFiles,

View File

@@ -57,6 +57,7 @@ public:
using FileContainer = ClangBackEnd::FileContainer; using FileContainer = ClangBackEnd::FileContainer;
using FileContainers = QVector<ClangBackEnd::FileContainer>; using FileContainers = QVector<ClangBackEnd::FileContainer>;
using ProjectPartContainers = QVector<ClangBackEnd::ProjectPartContainer>; using ProjectPartContainers = QVector<ClangBackEnd::ProjectPartContainer>;
using LocalUseMap = CppTools::SemanticInfo::LocalUseMap;
public: public:
BackendCommunicator(); BackendCommunicator();
@@ -75,7 +76,12 @@ public:
quint32 line, quint32 line,
quint32 column, quint32 column,
QTextDocument *textDocument, QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses); const LocalUseMap &localUses);
QFuture<CppTools::CursorInfo> requestLocalReferences(
const FileContainer &fileContainer,
quint32 line,
quint32 column,
QTextDocument *textDocument);
QFuture<CppTools::SymbolInfo> requestFollowSymbol(const FileContainer &curFileContainer, QFuture<CppTools::SymbolInfo> requestFollowSymbol(const FileContainer &curFileContainer,
const QVector<Utf8String> &dependentFiles, const QVector<Utf8String> &dependentFiles,
quint32 line, quint32 line,

View File

@@ -56,7 +56,8 @@ public:
QFuture<CppTools::CursorInfo> QFuture<CppTools::CursorInfo>
addExpectedReferencesMessage(quint64 ticket, addExpectedReferencesMessage(quint64 ticket,
QTextDocument *textDocument, QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses); const CppTools::SemanticInfo::LocalUseMap &localUses
= CppTools::SemanticInfo::LocalUseMap());
QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket); QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
bool isExpectingCodeCompletedMessage() const; bool isExpectingCodeCompletedMessage() const;

View File

@@ -33,6 +33,7 @@ SOURCES += \
clangpreprocessorassistproposalitem.cpp \ clangpreprocessorassistproposalitem.cpp \
clangprojectsettings.cpp \ clangprojectsettings.cpp \
clangprojectsettingswidget.cpp \ clangprojectsettingswidget.cpp \
clangrefactoringengine.cpp \
clangtextmark.cpp \ clangtextmark.cpp \
clanguiheaderondiskmanager.cpp \ clanguiheaderondiskmanager.cpp \
clangutils.cpp clangutils.cpp
@@ -69,6 +70,7 @@ HEADERS += \
clangpreprocessorassistproposalitem.h \ clangpreprocessorassistproposalitem.h \
clangprojectsettings.h \ clangprojectsettings.h \
clangprojectsettingswidget.h \ clangprojectsettingswidget.h \
clangrefactoringengine.h \
clangtextmark.h \ clangtextmark.h \
clanguiheaderondiskmanager.h \ clanguiheaderondiskmanager.h \
clangutils.h clangutils.h

View File

@@ -92,6 +92,8 @@ QtcPlugin {
"clangprojectsettingswidget.cpp", "clangprojectsettingswidget.cpp",
"clangprojectsettingswidget.h", "clangprojectsettingswidget.h",
"clangprojectsettingswidget.ui", "clangprojectsettingswidget.ui",
"clangrefactoringengine.cpp",
"clangrefactoringengine.h",
"clangtextmark.cpp", "clangtextmark.cpp",
"clangtextmark.h", "clangtextmark.h",
"clanguiheaderondiskmanager.cpp", "clanguiheaderondiskmanager.cpp",

View File

@@ -350,6 +350,23 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams &param
localUses); localUses);
} }
QFuture<CppTools::CursorInfo> ClangEditorDocumentProcessor::requestLocalReferences(
const QTextCursor &cursor)
{
int line, column;
convertPosition(cursor, &line, &column);
++column; // for 1-based columns
// TODO: check that by highlighting items
if (!isCursorOnIdentifier(cursor))
return defaultCursorInfoFuture();
return m_communicator.requestLocalReferences(simpleFileContainer(),
static_cast<quint32>(line),
static_cast<quint32>(column),
textDocument());
}
static QVector<Utf8String> prioritizeByBaseName(const QString &curPath, static QVector<Utf8String> prioritizeByBaseName(const QString &curPath,
const ::Utils::FileNameList &fileDeps) const ::Utils::FileNameList &fileDeps)
{ {

View File

@@ -86,6 +86,7 @@ public:
void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override; void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override;
QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams &params) override; QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams &params) override;
QFuture<CppTools::CursorInfo> requestLocalReferences(const QTextCursor &cursor) override;
QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line, int column) override; QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line, int column) override;
ClangBackEnd::FileContainer fileContainerWithArguments() const; ClangBackEnd::FileContainer fileContainerWithArguments() const;

View File

@@ -29,6 +29,7 @@
#include "clangeditordocumentprocessor.h" #include "clangeditordocumentprocessor.h"
#include "clangutils.h" #include "clangutils.h"
#include "clangfollowsymbol.h" #include "clangfollowsymbol.h"
#include "clangrefactoringengine.h"
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppfollowsymbolundercursor.h> #include <cpptools/cppfollowsymbolundercursor.h>
@@ -67,6 +68,7 @@ static CppTools::CppModelManager *cppModelManager()
ModelManagerSupportClang::ModelManagerSupportClang() ModelManagerSupportClang::ModelManagerSupportClang()
: m_completionAssistProvider(m_communicator) : m_completionAssistProvider(m_communicator)
, m_refactoringEngine(new RefactoringEngine)
{ {
QTC_CHECK(!m_instance); QTC_CHECK(!m_instance);
m_instance = this; m_instance = this;
@@ -114,6 +116,11 @@ CppTools::FollowSymbolInterface &ModelManagerSupportClang::followSymbolInterface
return *m_followSymbol; return *m_followSymbol;
} }
CppTools::RefactoringEngineInterface &ModelManagerSupportClang::refactoringEngineInterface()
{
return *m_refactoringEngine;
}
CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor( CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) TextEditor::TextDocument *baseTextDocument)
{ {

View File

@@ -42,7 +42,10 @@ QT_END_NAMESPACE
namespace Core { class IDocument; } namespace Core { class IDocument; }
namespace TextEditor { class TextEditorWidget; } namespace TextEditor { class TextEditorWidget; }
namespace CppTools { class FollowSymbolInterface; } namespace CppTools {
class FollowSymbolInterface;
class RefactoringEngineInterface;
} // namespace CppTools
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Internal { namespace Internal {
@@ -61,6 +64,7 @@ public:
CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor( CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) override; TextEditor::TextDocument *baseTextDocument) override;
CppTools::FollowSymbolInterface &followSymbolInterface() override; CppTools::FollowSymbolInterface &followSymbolInterface() override;
CppTools::RefactoringEngineInterface &refactoringEngineInterface() override;
BackendCommunicator &communicator(); BackendCommunicator &communicator();
QString dummyUiHeaderOnDiskDirPath() const; QString dummyUiHeaderOnDiskDirPath() const;
@@ -105,6 +109,7 @@ private:
BackendCommunicator m_communicator; BackendCommunicator m_communicator;
ClangCompletionAssistProvider m_completionAssistProvider; ClangCompletionAssistProvider m_completionAssistProvider;
std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol; std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
std::unique_ptr<CppTools::RefactoringEngineInterface> m_refactoringEngine;
}; };
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider

View File

@@ -0,0 +1,78 @@
/****************************************************************************
**
** Copyright (C) 2016 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 "clangrefactoringengine.h"
#include "clangeditordocumentprocessor.h"
#include <utils/textutils.h>
#include <utils/qtcassert.h>
namespace ClangCodeModel {
void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback)
{
Internal::ClangEditorDocumentProcessor *processor = Internal::ClangEditorDocumentProcessor::get(
data.filePath().toString());
const int startRevision = data.cursor().document()->revision();
using ClangBackEnd::SourceLocationsContainer;
auto defaultCallback = [renameSymbolsCallback, startRevision]() {
return renameSymbolsCallback(QString(), SourceLocationsContainer{}, startRevision);
};
if (!processor)
return defaultCallback();
QFuture<CppTools::CursorInfo> future = processor->requestLocalReferences(data.cursor());
if (future.isCanceled())
return defaultCallback();
// QFuture::waitForFinished seems to block completely, not even
// allowing to process events from QLocalSocket.
while (!future.isFinished()) {
if (future.isCanceled())
return defaultCallback();
QTC_ASSERT(startRevision == data.cursor().document()->revision(), return;);
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
}
const CppTools::CursorInfo info = future.result();
if (info.useRanges.empty())
return defaultCallback();
QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor,
info.useRanges.first().length);
const QString symbolName = cursor.selectedText();
ClangBackEnd::SourceLocationsContainer container;
for (auto& use : info.useRanges)
container.insertSourceLocation(ClangBackEnd::FilePathId(), use.line, use.column, use.length);
renameSymbolsCallback(symbolName, container, data.cursor().document()->revision());
}
}

View File

@@ -0,0 +1,48 @@
/****************************************************************************
**
** Copyright (C) 2016 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 ClangBackEnd {
class RefactoringClientInterface;
class RefactoringServerInterface;
}
namespace ClangCodeModel {
class RefactoringEngine : public CppTools::RefactoringEngineInterface
{
public:
void startLocalRenaming(const CppTools::CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) override;
void globalRename(const CppTools::CursorInEditor &, CppTools::UsagesCallback &&,
const QString &) override {}
void findUsages(const CppTools::CursorInEditor &, CppTools::UsagesCallback &&) const override {}
};
} // namespace ClangRefactoring

View File

@@ -570,6 +570,10 @@ void CppEditorWidget::renameSymbolUnderCursor()
if (!projPart) if (!projPart)
return; return;
if (d->m_localRenaming.isActive()
&& d->m_localRenaming.isSameSelection(textCursor().position())) {
return;
}
d->m_useSelectionsUpdater.abortSchedule(); d->m_useSelectionsUpdater.abortSchedule();
QPointer<CppEditorWidget> cppEditorWidget = this; QPointer<CppEditorWidget> cppEditorWidget = this;
@@ -588,6 +592,7 @@ void CppEditorWidget::renameSymbolUnderCursor()
static_cast<uint>(symbolName.size()), static_cast<uint>(symbolName.size()),
cppEditorWidget); cppEditorWidget);
setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections); setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections);
d->m_localRenaming.stop();
d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections); d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections);
} }
if (!d->m_localRenaming.start()) if (!d->m_localRenaming.start())

View File

@@ -242,6 +242,15 @@ bool CppLocalRenaming::isWithinRenameSelection(int position)
return renameSelectionBegin() <= position && position <= renameSelectionEnd(); return renameSelectionBegin() <= position && position <= renameSelectionEnd();
} }
bool CppLocalRenaming::isSameSelection(int cursorPosition) const
{
if (!isActive())
return false;
const QTextEdit::ExtraSelection &sel = m_selections[m_renameSelectionIndex];
return (sel.cursor.position() <= cursorPosition && cursorPosition <= sel.cursor.anchor());
}
bool CppLocalRenaming::findRenameSelection(int cursorPosition) bool CppLocalRenaming::findRenameSelection(int cursorPosition)
{ {
for (int i = 0, total = m_selections.size(); i < total; ++i) { for (int i = 0, total = m_selections.size(); i < total; ++i) {

View File

@@ -60,6 +60,7 @@ public:
void onContentsChangeOfEditorWidgetDocument(int position, int charsRemoved, int charsAdded); void onContentsChangeOfEditorWidgetDocument(int position, int charsRemoved, int charsAdded);
void updateSelectionsForVariableUnderCursor(const QList<QTextEdit::ExtraSelection> &selections); void updateSelectionsForVariableUnderCursor(const QList<QTextEdit::ExtraSelection> &selections);
bool isSameSelection(int cursorPosition) const;
signals: signals:
void finished(); void finished();

View File

@@ -76,6 +76,7 @@ public:
virtual void setParserConfig(const BaseEditorDocumentParser::Configuration config); virtual void setParserConfig(const BaseEditorDocumentParser::Configuration config);
virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) = 0; virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) = 0;
virtual QFuture<CursorInfo> requestLocalReferences(const QTextCursor &cursor) = 0;
virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0; virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0;
public: public:

View File

@@ -260,6 +260,24 @@ BuiltinEditorDocumentProcessor::cursorInfo(const CursorInfoParams &params)
return BuiltinCursorInfo::run(params); return BuiltinCursorInfo::run(params);
} }
QFuture<CursorInfo> BuiltinEditorDocumentProcessor::requestLocalReferences(const QTextCursor &)
{
QFutureInterface<CppTools::CursorInfo> futureInterface;
futureInterface.reportResult(CppTools::CursorInfo());
futureInterface.reportFinished();
return futureInterface.future();
}
QFuture<SymbolInfo> BuiltinEditorDocumentProcessor::requestFollowSymbol(int, int)
{
QFutureInterface<CppTools::SymbolInfo> futureInterface;
futureInterface.reportResult(CppTools::SymbolInfo());
futureInterface.reportFinished();
return futureInterface.future();
}
void BuiltinEditorDocumentProcessor::onParserFinished(CPlusPlus::Document::Ptr document, void BuiltinEditorDocumentProcessor::onParserFinished(CPlusPlus::Document::Ptr document,
CPlusPlus::Snapshot snapshot) CPlusPlus::Snapshot snapshot)
{ {

View File

@@ -52,8 +52,8 @@ public:
bool isParserRunning() const override; bool isParserRunning() const override;
QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) override; QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) override;
QFuture<SymbolInfo> requestFollowSymbol(int, int) override QFuture<CursorInfo> requestLocalReferences(const QTextCursor &) override;
{ return QFuture<SymbolInfo>(); } QFuture<SymbolInfo> requestFollowSymbol(int, int) override;
private: private:
void onParserFinished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot); void onParserFinished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot);

View File

@@ -169,9 +169,8 @@ public:
QTimer m_delayedGcTimer; QTimer m_delayedGcTimer;
// Refactoring // Refactoring
CppRefactoringEngine m_builtInRefactoringEngine;
using REHash = QMap<REType, RefactoringEngineInterface *>; using REHash = QMap<REType, RefactoringEngineInterface *>;
REHash m_refactoringEngines {{REType::BuiltIn, &m_builtInRefactoringEngine}}; REHash m_refactoringEngines;
}; };
} // namespace Internal } // namespace Internal
@@ -274,6 +273,7 @@ QString CppModelManager::editorConfigurationFileName()
static RefactoringEngineInterface *getRefactoringEngine( static RefactoringEngineInterface *getRefactoringEngine(
CppModelManagerPrivate::REHash &engines, bool excludeClangCodeModel = true) CppModelManagerPrivate::REHash &engines, bool excludeClangCodeModel = true)
{ {
QTC_ASSERT(!engines.empty(), return nullptr;);
RefactoringEngineInterface *currentEngine = engines[REType::BuiltIn]; RefactoringEngineInterface *currentEngine = engines[REType::BuiltIn];
if (!excludeClangCodeModel && engines.find(REType::ClangCodeModel) != engines.end()) { if (!excludeClangCodeModel && engines.find(REType::ClangCodeModel) != engines.end()) {
currentEngine = engines[REType::ClangCodeModel]; currentEngine = engines[REType::ClangCodeModel];
@@ -291,6 +291,7 @@ void CppModelManager::startLocalRenaming(const CursorInEditor &data,
{ {
RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines, RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines,
false); false);
QTC_ASSERT(engine, return;);
engine->startLocalRenaming(data, projectPart, std::move(renameSymbolsCallback)); engine->startLocalRenaming(data, projectPart, std::move(renameSymbolsCallback));
} }
@@ -298,12 +299,15 @@ void CppModelManager::globalRename(const CursorInEditor &data, UsagesCallback &&
const QString &replacement) const QString &replacement)
{ {
RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines); RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines);
QTC_ASSERT(engine, return;);
engine->globalRename(data, std::move(renameCallback), replacement); engine->globalRename(data, std::move(renameCallback), replacement);
} }
void CppModelManager::findUsages(const CppTools::CursorInEditor &data, void CppModelManager::findUsages(const CppTools::CursorInEditor &data,
UsagesCallback &&showUsagesCallback) const UsagesCallback &&showUsagesCallback) const
{ {
RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines); RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines);
QTC_ASSERT(engine, return;);
engine->findUsages(data, std::move(showUsagesCallback)); engine->findUsages(data, std::move(showUsagesCallback));
} }
@@ -367,6 +371,8 @@ void CppModelManager::initializeBuiltinModelManagerSupport()
d->m_builtinModelManagerSupport d->m_builtinModelManagerSupport
= ModelManagerSupportProviderInternal().createModelManagerSupport(); = ModelManagerSupportProviderInternal().createModelManagerSupport();
d->m_activeModelManagerSupport = d->m_builtinModelManagerSupport; d->m_activeModelManagerSupport = d->m_builtinModelManagerSupport;
d->m_refactoringEngines[RefactoringEngineType::BuiltIn] =
&d->m_activeModelManagerSupport->refactoringEngineInterface();
} }
CppModelManager::CppModelManager(QObject *parent) CppModelManager::CppModelManager(QObject *parent)
@@ -1267,6 +1273,8 @@ void CppModelManager::activateClangCodeModel(
QTC_ASSERT(modelManagerSupportProvider, return); QTC_ASSERT(modelManagerSupportProvider, return);
d->m_activeModelManagerSupport = modelManagerSupportProvider->createModelManagerSupport(); d->m_activeModelManagerSupport = modelManagerSupportProvider->createModelManagerSupport();
d->m_refactoringEngines[RefactoringEngineType::ClangCodeModel] =
&d->m_activeModelManagerSupport->refactoringEngineInterface();
} }
CppCompletionAssistProvider *CppModelManager::completionAssistProvider() const CppCompletionAssistProvider *CppModelManager::completionAssistProvider() const

View File

@@ -37,6 +37,7 @@ namespace CppTools {
class BaseEditorDocumentProcessor; class BaseEditorDocumentProcessor;
class CppCompletionAssistProvider; class CppCompletionAssistProvider;
class FollowSymbolInterface; class FollowSymbolInterface;
class RefactoringEngineInterface;
class CPPTOOLS_EXPORT ModelManagerSupport class CPPTOOLS_EXPORT ModelManagerSupport
{ {
@@ -50,6 +51,7 @@ public:
virtual BaseEditorDocumentProcessor *editorDocumentProcessor( virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) = 0; TextEditor::TextDocument *baseTextDocument) = 0;
virtual FollowSymbolInterface &followSymbolInterface() = 0; virtual FollowSymbolInterface &followSymbolInterface() = 0;
virtual RefactoringEngineInterface &refactoringEngineInterface() = 0;
}; };
class CPPTOOLS_EXPORT ModelManagerSupportProvider class CPPTOOLS_EXPORT ModelManagerSupportProvider

View File

@@ -26,6 +26,7 @@
#include "cppcompletionassist.h" #include "cppcompletionassist.h"
#include "cppmodelmanagersupportinternal.h" #include "cppmodelmanagersupportinternal.h"
#include "cppfollowsymbolundercursor.h" #include "cppfollowsymbolundercursor.h"
#include "cpprefactoringengine.h"
#include "builtineditordocumentprocessor.h" #include "builtineditordocumentprocessor.h"
#include <app/app_version.h> #include <app/app_version.h>
@@ -53,7 +54,8 @@ ModelManagerSupport::Ptr ModelManagerSupportProviderInternal::createModelManager
ModelManagerSupportInternal::ModelManagerSupportInternal() ModelManagerSupportInternal::ModelManagerSupportInternal()
: m_completionAssistProvider(new InternalCompletionAssistProvider), : m_completionAssistProvider(new InternalCompletionAssistProvider),
m_followSymbol(new FollowSymbolUnderCursor) m_followSymbol(new FollowSymbolUnderCursor),
m_refactoringEngine(new CppRefactoringEngine)
{ {
} }
@@ -76,3 +78,8 @@ FollowSymbolInterface &ModelManagerSupportInternal::followSymbolInterface()
{ {
return *m_followSymbol; return *m_followSymbol;
} }
RefactoringEngineInterface &ModelManagerSupportInternal::refactoringEngineInterface()
{
return *m_refactoringEngine;
}

View File

@@ -44,10 +44,12 @@ public:
BaseEditorDocumentProcessor *editorDocumentProcessor( BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) final; TextEditor::TextDocument *baseTextDocument) final;
FollowSymbolInterface &followSymbolInterface() final; FollowSymbolInterface &followSymbolInterface() final;
RefactoringEngineInterface &refactoringEngineInterface() final;
private: private:
QScopedPointer<CppCompletionAssistProvider> m_completionAssistProvider; QScopedPointer<CppCompletionAssistProvider> m_completionAssistProvider;
QScopedPointer<FollowSymbolInterface> m_followSymbol; QScopedPointer<FollowSymbolInterface> m_followSymbol;
QScopedPointer<RefactoringEngineInterface> m_refactoringEngine;
}; };
class ModelManagerSupportProviderInternal : public ModelManagerSupportProvider class ModelManagerSupportProviderInternal : public ModelManagerSupportProvider

View File

@@ -261,6 +261,7 @@ void ClangCodeModelServer::requestReferences(const RequestReferencesMessage &mes
JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestReferences); JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestReferences);
fillJobRequest(jobRequest, message); fillJobRequest(jobRequest, message);
jobRequest.localReferences = message.local();
processor.addJob(jobRequest); processor.addJob(jobRequest);
processor.process(); processor.process();
} catch (const std::exception &exception) { } catch (const std::exception &exception) {

View File

@@ -118,6 +118,7 @@ public:
qint32 funcNameStartColumn = -1; qint32 funcNameStartColumn = -1;
quint64 ticketNumber = 0; quint64 ticketNumber = 0;
Utf8StringVector dependentFiles; Utf8StringVector dependentFiles;
bool localReferences = false;
}; };
using JobRequests = QVector<JobRequest>; using JobRequests = QVector<JobRequest>;

View File

@@ -121,7 +121,7 @@ public:
ReferencesCollector(CXTranslationUnit cxTranslationUnit); ReferencesCollector(CXTranslationUnit cxTranslationUnit);
~ReferencesCollector(); ~ReferencesCollector();
ReferencesResult collect(uint line, uint column) const; ReferencesResult collect(uint line, uint column, bool localReferences = false) const;
private: private:
bool isWithinTokenRange(CXToken token, uint line, uint column) const; bool isWithinTokenRange(CXToken token, uint line, uint column) const;
@@ -207,7 +207,7 @@ bool ReferencesCollector::checkToken(unsigned index, const Utf8String &identifie
return candidate.usr() == usr; return candidate.usr() == usr;
} }
ReferencesResult ReferencesCollector::collect(uint line, uint column) const ReferencesResult ReferencesCollector::collect(uint line, uint column, bool localReferences) const
{ {
ReferencesResult result; ReferencesResult result;
@@ -216,11 +216,15 @@ ReferencesResult ReferencesCollector::collect(uint line, uint column) const
return result; return result;
const Cursor cursorFromUser = m_cxCursors[static_cast<int>(index)]; const Cursor cursorFromUser = m_cxCursors[static_cast<int>(index)];
const ReferencedCursor refCursor = ReferencedCursor::find(cursorFromUser); const ReferencedCursor refCursor = ReferencedCursor::find(cursorFromUser);
const Utf8String usr = refCursor.usr(); const Utf8String usr = refCursor.usr();
if (usr.isEmpty()) if (usr.isEmpty())
return result; return result;
if (localReferences && !refCursor.isLocalVariable())
return result;
const CXToken token = m_cxTokens[index]; const CXToken token = m_cxTokens[index];
const Utf8String identifier = ClangString(clang_getTokenSpelling(m_cxTranslationUnit, token)); const Utf8String identifier = ClangString(clang_getTokenSpelling(m_cxTranslationUnit, token));
for (uint i = 0; i < m_cxTokenCount; ++i) { for (uint i = 0; i < m_cxTokenCount; ++i) {
@@ -239,10 +243,11 @@ ReferencesResult ReferencesCollector::collect(uint line, uint column) const
ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit, ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit,
uint line, uint line,
uint column) uint column,
bool localReferences)
{ {
ReferencesCollector collector(cxTranslationUnit); ReferencesCollector collector(cxTranslationUnit);
return collector.collect(line, column); return collector.collect(line, column, localReferences);
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -54,7 +54,8 @@ public:
ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit, ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit,
uint line, uint line,
uint column); uint column,
bool localReferences = false);
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -43,9 +43,10 @@ IAsyncJob::AsyncPrepareResult RequestReferencesJob::prepareAsyncRun()
const TranslationUnit translationUnit = *m_translationUnit; const TranslationUnit translationUnit = *m_translationUnit;
const quint32 line = jobRequest.line; const quint32 line = jobRequest.line;
const quint32 column = jobRequest.column; const quint32 column = jobRequest.column;
setRunner([translationUnit, line, column]() { const bool localReferences = jobRequest.localReferences;
setRunner([translationUnit, line, column, localReferences]() {
TIME_SCOPE_DURATION("RequestReferencesJobRunner"); TIME_SCOPE_DURATION("RequestReferencesJobRunner");
return translationUnit.references(line, column); return translationUnit.references(line, column, localReferences);
}); });
return AsyncPrepareResult{translationUnit.id()}; return AsyncPrepareResult{translationUnit.id()};

View File

@@ -139,9 +139,9 @@ void TranslationUnit::extractDocumentAnnotations(
skippedSourceRanges = this->skippedSourceRanges().toSourceRangeContainers(); skippedSourceRanges = this->skippedSourceRanges().toSourceRangeContainers();
} }
ReferencesResult TranslationUnit::references(uint line, uint column) const ReferencesResult TranslationUnit::references(uint line, uint column, bool localReferences) const
{ {
return collectReferences(m_cxTranslationUnit, line, column); return collectReferences(m_cxTranslationUnit, line, column, localReferences);
} }
DiagnosticSet TranslationUnit::diagnostics() const DiagnosticSet TranslationUnit::diagnostics() const

View File

@@ -85,7 +85,7 @@ public:
QVector<SourceRangeContainer> &skippedSourceRanges) const; QVector<SourceRangeContainer> &skippedSourceRanges) const;
ReferencesResult references(uint line, uint column) const; ReferencesResult references(uint line, uint column, bool localReferences = false) const;
DiagnosticSet diagnostics() const; DiagnosticSet diagnostics() const;
SourceLocation sourceLocationAt(uint line, uint column) const; SourceLocation sourceLocationAt(uint line, uint column) const;