diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2017-09-26 16:00:30 +0200 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2017-11-20 10:24:47 +0000 |
commit | 32bae7ef6cd5c5a2a9e37ee0ca77eb3b5e68be67 (patch) | |
tree | e225b6f8b6b6d797c34cc01fd1fab4f1440b52ea | |
parent | 94e818dc822a68e546a6c96ebf08c39b7aa3eb3d (diff) | |
download | qt-creator-32bae7ef6cd5c5a2a9e37ee0ca77eb3b5e68be67.tar.gz |
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>
30 files changed, 275 insertions, 21 deletions
diff --git a/src/libs/clangsupport/requestreferencesmessage.cpp b/src/libs/clangsupport/requestreferencesmessage.cpp index 0527db59d6..df42d690ae 100644 --- a/src/libs/clangsupport/requestreferencesmessage.cpp +++ b/src/libs/clangsupport/requestreferencesmessage.cpp @@ -41,6 +41,7 @@ QDebug operator<<(QDebug debug, const RequestReferencesMessage &message) debug.nospace() << message.m_ticketNumber << ", "; debug.nospace() << message.m_line << ", "; debug.nospace() << message.m_column << ", "; + debug.nospace() << message.m_local << ", "; debug.nospace() << ")"; @@ -54,6 +55,7 @@ std::ostream &operator<<(std::ostream &os, const RequestReferencesMessage &messa << message.m_ticketNumber << ", " << message.m_line << ", " << message.m_column << ", " + << message.m_local << ", " << ")"; return os; diff --git a/src/libs/clangsupport/requestreferencesmessage.h b/src/libs/clangsupport/requestreferencesmessage.h index fbbd934c43..004e718fd6 100644 --- a/src/libs/clangsupport/requestreferencesmessage.h +++ b/src/libs/clangsupport/requestreferencesmessage.h @@ -39,11 +39,13 @@ public: RequestReferencesMessage() = default; RequestReferencesMessage(const FileContainer &fileContainer, quint32 line, - quint32 column) + quint32 column, + bool local = false) : m_fileContainer(fileContainer) , m_ticketNumber(++ticketCounter) , m_line(line) , m_column(column) + , m_local(local) { } @@ -67,12 +69,18 @@ public: return m_ticketNumber; } + bool local() const + { + return m_local; + } + friend QDataStream &operator<<(QDataStream &out, const RequestReferencesMessage &message) { out << message.m_fileContainer; out << message.m_ticketNumber; out << message.m_line; out << message.m_column; + out << message.m_local; return out; } @@ -83,6 +91,7 @@ public: in >> message.m_ticketNumber; in >> message.m_line; in >> message.m_column; + in >> message.m_local; return in; } @@ -93,7 +102,8 @@ public: return first.m_ticketNumber == second.m_ticketNumber && first.m_line == second.m_line && 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); @@ -104,6 +114,7 @@ private: quint64 m_ticketNumber = 0; quint32 m_line = 0; quint32 m_column = 0; + bool m_local = false; static CLANGSUPPORT_EXPORT quint64 ticketCounter; }; diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp index fc5603b0c0..00f5c9a8e6 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -377,7 +377,19 @@ QFuture<CppTools::CursorInfo> BackendCommunicator::requestReferences( m_sender->requestReferences(message); return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument, - 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( diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.h b/src/plugins/clangcodemodel/clangbackendcommunicator.h index 86054e566f..baafa3c2a6 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.h +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.h @@ -57,6 +57,7 @@ public: using FileContainer = ClangBackEnd::FileContainer; using FileContainers = QVector<ClangBackEnd::FileContainer>; using ProjectPartContainers = QVector<ClangBackEnd::ProjectPartContainer>; + using LocalUseMap = CppTools::SemanticInfo::LocalUseMap; public: BackendCommunicator(); @@ -75,7 +76,12 @@ public: quint32 line, quint32 column, 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, const QVector<Utf8String> &dependentFiles, quint32 line, diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.h b/src/plugins/clangcodemodel/clangbackendreceiver.h index d67db73223..d7a966eae9 100644 --- a/src/plugins/clangcodemodel/clangbackendreceiver.h +++ b/src/plugins/clangcodemodel/clangbackendreceiver.h @@ -56,7 +56,8 @@ public: QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket, QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses); + const CppTools::SemanticInfo::LocalUseMap &localUses + = CppTools::SemanticInfo::LocalUseMap()); QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket); bool isExpectingCodeCompletedMessage() const; diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index bc37ba54b9..55a3bf4572 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -33,6 +33,7 @@ SOURCES += \ clangpreprocessorassistproposalitem.cpp \ clangprojectsettings.cpp \ clangprojectsettingswidget.cpp \ + clangrefactoringengine.cpp \ clangtextmark.cpp \ clanguiheaderondiskmanager.cpp \ clangutils.cpp @@ -69,6 +70,7 @@ HEADERS += \ clangpreprocessorassistproposalitem.h \ clangprojectsettings.h \ clangprojectsettingswidget.h \ + clangrefactoringengine.h \ clangtextmark.h \ clanguiheaderondiskmanager.h \ clangutils.h diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index bce2f967cd..1733a26e60 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -92,6 +92,8 @@ QtcPlugin { "clangprojectsettingswidget.cpp", "clangprojectsettingswidget.h", "clangprojectsettingswidget.ui", + "clangrefactoringengine.cpp", + "clangrefactoringengine.h", "clangtextmark.cpp", "clangtextmark.h", "clanguiheaderondiskmanager.cpp", diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 4735c8497b..84667dd652 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -350,6 +350,23 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m 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, const ::Utils::FileNameList &fileDeps) { diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index a040cba256..328adb0143 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -86,6 +86,7 @@ public: void setParserConfig(const CppTools::BaseEditorDocumentParser::Configuration config) override; QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams ¶ms) override; + QFuture<CppTools::CursorInfo> requestLocalReferences(const QTextCursor &cursor) override; QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line, int column) override; ClangBackEnd::FileContainer fileContainerWithArguments() const; diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index df1e96869c..f73c5fe4e4 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -29,6 +29,7 @@ #include "clangeditordocumentprocessor.h" #include "clangutils.h" #include "clangfollowsymbol.h" +#include "clangrefactoringengine.h" #include <coreplugin/editormanager/editormanager.h> #include <cpptools/cppfollowsymbolundercursor.h> @@ -67,6 +68,7 @@ static CppTools::CppModelManager *cppModelManager() ModelManagerSupportClang::ModelManagerSupportClang() : m_completionAssistProvider(m_communicator) + , m_refactoringEngine(new RefactoringEngine) { QTC_CHECK(!m_instance); m_instance = this; @@ -114,6 +116,11 @@ CppTools::FollowSymbolInterface &ModelManagerSupportClang::followSymbolInterface return *m_followSymbol; } +CppTools::RefactoringEngineInterface &ModelManagerSupportClang::refactoringEngineInterface() +{ + return *m_refactoringEngine; +} + CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) { diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index f87ac11923..e87a7f162e 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -42,7 +42,10 @@ QT_END_NAMESPACE namespace Core { class IDocument; } namespace TextEditor { class TextEditorWidget; } -namespace CppTools { class FollowSymbolInterface; } +namespace CppTools { +class FollowSymbolInterface; +class RefactoringEngineInterface; +} // namespace CppTools namespace ClangCodeModel { namespace Internal { @@ -61,6 +64,7 @@ public: CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) override; CppTools::FollowSymbolInterface &followSymbolInterface() override; + CppTools::RefactoringEngineInterface &refactoringEngineInterface() override; BackendCommunicator &communicator(); QString dummyUiHeaderOnDiskDirPath() const; @@ -105,6 +109,7 @@ private: BackendCommunicator m_communicator; ClangCompletionAssistProvider m_completionAssistProvider; std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol; + std::unique_ptr<CppTools::RefactoringEngineInterface> m_refactoringEngine; }; class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider diff --git a/src/plugins/clangcodemodel/clangrefactoringengine.cpp b/src/plugins/clangcodemodel/clangrefactoringengine.cpp new file mode 100644 index 0000000000..919ee5c5f7 --- /dev/null +++ b/src/plugins/clangcodemodel/clangrefactoringengine.cpp @@ -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()); +} + +} diff --git a/src/plugins/clangcodemodel/clangrefactoringengine.h b/src/plugins/clangcodemodel/clangrefactoringengine.h new file mode 100644 index 0000000000..e72a4f5f4d --- /dev/null +++ b/src/plugins/clangcodemodel/clangrefactoringengine.h @@ -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 diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 7b523b2421..bb8755f7b1 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -570,6 +570,10 @@ void CppEditorWidget::renameSymbolUnderCursor() if (!projPart) return; + if (d->m_localRenaming.isActive() + && d->m_localRenaming.isSameSelection(textCursor().position())) { + return; + } d->m_useSelectionsUpdater.abortSchedule(); QPointer<CppEditorWidget> cppEditorWidget = this; @@ -588,6 +592,7 @@ void CppEditorWidget::renameSymbolUnderCursor() static_cast<uint>(symbolName.size()), cppEditorWidget); setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections); + d->m_localRenaming.stop(); d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections); } if (!d->m_localRenaming.start()) diff --git a/src/plugins/cppeditor/cpplocalrenaming.cpp b/src/plugins/cppeditor/cpplocalrenaming.cpp index fd989c782c..14a7a93fc2 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.cpp +++ b/src/plugins/cppeditor/cpplocalrenaming.cpp @@ -242,6 +242,15 @@ bool CppLocalRenaming::isWithinRenameSelection(int position) 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) { for (int i = 0, total = m_selections.size(); i < total; ++i) { diff --git a/src/plugins/cppeditor/cpplocalrenaming.h b/src/plugins/cppeditor/cpplocalrenaming.h index c71bcdb5d8..61c1d1ca11 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.h +++ b/src/plugins/cppeditor/cpplocalrenaming.h @@ -60,6 +60,7 @@ public: void onContentsChangeOfEditorWidgetDocument(int position, int charsRemoved, int charsAdded); void updateSelectionsForVariableUnderCursor(const QList<QTextEdit::ExtraSelection> &selections); + bool isSameSelection(int cursorPosition) const; signals: void finished(); diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index 1ac31a6ebc..b3f96d466d 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -76,6 +76,7 @@ public: virtual void setParserConfig(const BaseEditorDocumentParser::Configuration config); virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams ¶ms) = 0; + virtual QFuture<CursorInfo> requestLocalReferences(const QTextCursor &cursor) = 0; virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0; public: diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp index bfdabe5362..ce282e3685 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp +++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp @@ -260,6 +260,24 @@ BuiltinEditorDocumentProcessor::cursorInfo(const CursorInfoParams ¶ms) 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, CPlusPlus::Snapshot snapshot) { diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.h b/src/plugins/cpptools/builtineditordocumentprocessor.h index 800bff085a..01962843f4 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.h +++ b/src/plugins/cpptools/builtineditordocumentprocessor.h @@ -52,8 +52,8 @@ public: bool isParserRunning() const override; QFuture<CursorInfo> cursorInfo(const CursorInfoParams ¶ms) override; - QFuture<SymbolInfo> requestFollowSymbol(int, int) override - { return QFuture<SymbolInfo>(); } + QFuture<CursorInfo> requestLocalReferences(const QTextCursor &) override; + QFuture<SymbolInfo> requestFollowSymbol(int, int) override; private: void onParserFinished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 2074899572..c889ac8b9e 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -169,9 +169,8 @@ public: QTimer m_delayedGcTimer; // Refactoring - CppRefactoringEngine m_builtInRefactoringEngine; using REHash = QMap<REType, RefactoringEngineInterface *>; - REHash m_refactoringEngines {{REType::BuiltIn, &m_builtInRefactoringEngine}}; + REHash m_refactoringEngines; }; } // namespace Internal @@ -274,6 +273,7 @@ QString CppModelManager::editorConfigurationFileName() static RefactoringEngineInterface *getRefactoringEngine( CppModelManagerPrivate::REHash &engines, bool excludeClangCodeModel = true) { + QTC_ASSERT(!engines.empty(), return nullptr;); RefactoringEngineInterface *currentEngine = engines[REType::BuiltIn]; if (!excludeClangCodeModel && engines.find(REType::ClangCodeModel) != engines.end()) { currentEngine = engines[REType::ClangCodeModel]; @@ -291,6 +291,7 @@ void CppModelManager::startLocalRenaming(const CursorInEditor &data, { RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines, false); + QTC_ASSERT(engine, return;); engine->startLocalRenaming(data, projectPart, std::move(renameSymbolsCallback)); } @@ -298,12 +299,15 @@ void CppModelManager::globalRename(const CursorInEditor &data, UsagesCallback && const QString &replacement) { RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines); + QTC_ASSERT(engine, return;); engine->globalRename(data, std::move(renameCallback), replacement); } + void CppModelManager::findUsages(const CppTools::CursorInEditor &data, UsagesCallback &&showUsagesCallback) const { RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines); + QTC_ASSERT(engine, return;); engine->findUsages(data, std::move(showUsagesCallback)); } @@ -367,6 +371,8 @@ void CppModelManager::initializeBuiltinModelManagerSupport() d->m_builtinModelManagerSupport = ModelManagerSupportProviderInternal().createModelManagerSupport(); d->m_activeModelManagerSupport = d->m_builtinModelManagerSupport; + d->m_refactoringEngines[RefactoringEngineType::BuiltIn] = + &d->m_activeModelManagerSupport->refactoringEngineInterface(); } CppModelManager::CppModelManager(QObject *parent) @@ -1267,6 +1273,8 @@ void CppModelManager::activateClangCodeModel( QTC_ASSERT(modelManagerSupportProvider, return); d->m_activeModelManagerSupport = modelManagerSupportProvider->createModelManagerSupport(); + d->m_refactoringEngines[RefactoringEngineType::ClangCodeModel] = + &d->m_activeModelManagerSupport->refactoringEngineInterface(); } CppCompletionAssistProvider *CppModelManager::completionAssistProvider() const diff --git a/src/plugins/cpptools/cppmodelmanagersupport.h b/src/plugins/cpptools/cppmodelmanagersupport.h index cb74f00efd..b1256aa51f 100644 --- a/src/plugins/cpptools/cppmodelmanagersupport.h +++ b/src/plugins/cpptools/cppmodelmanagersupport.h @@ -37,6 +37,7 @@ namespace CppTools { class BaseEditorDocumentProcessor; class CppCompletionAssistProvider; class FollowSymbolInterface; +class RefactoringEngineInterface; class CPPTOOLS_EXPORT ModelManagerSupport { @@ -50,6 +51,7 @@ public: virtual BaseEditorDocumentProcessor *editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) = 0; virtual FollowSymbolInterface &followSymbolInterface() = 0; + virtual RefactoringEngineInterface &refactoringEngineInterface() = 0; }; class CPPTOOLS_EXPORT ModelManagerSupportProvider diff --git a/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp b/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp index c03e2ed57e..95b98bbdf3 100644 --- a/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp +++ b/src/plugins/cpptools/cppmodelmanagersupportinternal.cpp @@ -26,6 +26,7 @@ #include "cppcompletionassist.h" #include "cppmodelmanagersupportinternal.h" #include "cppfollowsymbolundercursor.h" +#include "cpprefactoringengine.h" #include "builtineditordocumentprocessor.h" #include <app/app_version.h> @@ -53,7 +54,8 @@ ModelManagerSupport::Ptr ModelManagerSupportProviderInternal::createModelManager ModelManagerSupportInternal::ModelManagerSupportInternal() : 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; } + +RefactoringEngineInterface &ModelManagerSupportInternal::refactoringEngineInterface() +{ + return *m_refactoringEngine; +} diff --git a/src/plugins/cpptools/cppmodelmanagersupportinternal.h b/src/plugins/cpptools/cppmodelmanagersupportinternal.h index cd35ea5abc..6ac2d4d022 100644 --- a/src/plugins/cpptools/cppmodelmanagersupportinternal.h +++ b/src/plugins/cpptools/cppmodelmanagersupportinternal.h @@ -44,10 +44,12 @@ public: BaseEditorDocumentProcessor *editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) final; FollowSymbolInterface &followSymbolInterface() final; + RefactoringEngineInterface &refactoringEngineInterface() final; private: QScopedPointer<CppCompletionAssistProvider> m_completionAssistProvider; QScopedPointer<FollowSymbolInterface> m_followSymbol; + QScopedPointer<RefactoringEngineInterface> m_refactoringEngine; }; class ModelManagerSupportProviderInternal : public ModelManagerSupportProvider diff --git a/src/tools/clangbackend/source/clangcodemodelserver.cpp b/src/tools/clangbackend/source/clangcodemodelserver.cpp index 9def46b2db..8b9a03dfe5 100644 --- a/src/tools/clangbackend/source/clangcodemodelserver.cpp +++ b/src/tools/clangbackend/source/clangcodemodelserver.cpp @@ -261,6 +261,7 @@ void ClangCodeModelServer::requestReferences(const RequestReferencesMessage &mes JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestReferences); fillJobRequest(jobRequest, message); + jobRequest.localReferences = message.local(); processor.addJob(jobRequest); processor.process(); } catch (const std::exception &exception) { diff --git a/src/tools/clangbackend/source/clangjobrequest.h b/src/tools/clangbackend/source/clangjobrequest.h index 78aaed6618..2df63e126d 100644 --- a/src/tools/clangbackend/source/clangjobrequest.h +++ b/src/tools/clangbackend/source/clangjobrequest.h @@ -118,6 +118,7 @@ public: qint32 funcNameStartColumn = -1; quint64 ticketNumber = 0; Utf8StringVector dependentFiles; + bool localReferences = false; }; using JobRequests = QVector<JobRequest>; diff --git a/src/tools/clangbackend/source/clangreferencescollector.cpp b/src/tools/clangbackend/source/clangreferencescollector.cpp index d2b7bf5431..64d9b61392 100644 --- a/src/tools/clangbackend/source/clangreferencescollector.cpp +++ b/src/tools/clangbackend/source/clangreferencescollector.cpp @@ -121,7 +121,7 @@ public: ReferencesCollector(CXTranslationUnit cxTranslationUnit); ~ReferencesCollector(); - ReferencesResult collect(uint line, uint column) const; + ReferencesResult collect(uint line, uint column, bool localReferences = false) const; private: 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; } -ReferencesResult ReferencesCollector::collect(uint line, uint column) const +ReferencesResult ReferencesCollector::collect(uint line, uint column, bool localReferences) const { ReferencesResult result; @@ -216,11 +216,15 @@ ReferencesResult ReferencesCollector::collect(uint line, uint column) const return result; const Cursor cursorFromUser = m_cxCursors[static_cast<int>(index)]; + const ReferencedCursor refCursor = ReferencedCursor::find(cursorFromUser); const Utf8String usr = refCursor.usr(); if (usr.isEmpty()) return result; + if (localReferences && !refCursor.isLocalVariable()) + return result; + const CXToken token = m_cxTokens[index]; const Utf8String identifier = ClangString(clang_getTokenSpelling(m_cxTranslationUnit, token)); for (uint i = 0; i < m_cxTokenCount; ++i) { @@ -239,10 +243,11 @@ ReferencesResult ReferencesCollector::collect(uint line, uint column) const ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit, uint line, - uint column) + uint column, + bool localReferences) { ReferencesCollector collector(cxTranslationUnit); - return collector.collect(line, column); + return collector.collect(line, column, localReferences); } } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangreferencescollector.h b/src/tools/clangbackend/source/clangreferencescollector.h index 263ba07fd9..c467f8b090 100644 --- a/src/tools/clangbackend/source/clangreferencescollector.h +++ b/src/tools/clangbackend/source/clangreferencescollector.h @@ -54,7 +54,8 @@ public: ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit, uint line, - uint column); + uint column, + bool localReferences = false); } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangrequestreferencesjob.cpp b/src/tools/clangbackend/source/clangrequestreferencesjob.cpp index 39b3319488..cb2354ede3 100644 --- a/src/tools/clangbackend/source/clangrequestreferencesjob.cpp +++ b/src/tools/clangbackend/source/clangrequestreferencesjob.cpp @@ -43,9 +43,10 @@ IAsyncJob::AsyncPrepareResult RequestReferencesJob::prepareAsyncRun() const TranslationUnit translationUnit = *m_translationUnit; const quint32 line = jobRequest.line; const quint32 column = jobRequest.column; - setRunner([translationUnit, line, column]() { + const bool localReferences = jobRequest.localReferences; + setRunner([translationUnit, line, column, localReferences]() { TIME_SCOPE_DURATION("RequestReferencesJobRunner"); - return translationUnit.references(line, column); + return translationUnit.references(line, column, localReferences); }); return AsyncPrepareResult{translationUnit.id()}; diff --git a/src/tools/clangbackend/source/clangtranslationunit.cpp b/src/tools/clangbackend/source/clangtranslationunit.cpp index 6951551985..7d3bcbbddd 100644 --- a/src/tools/clangbackend/source/clangtranslationunit.cpp +++ b/src/tools/clangbackend/source/clangtranslationunit.cpp @@ -139,9 +139,9 @@ void TranslationUnit::extractDocumentAnnotations( 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 diff --git a/src/tools/clangbackend/source/clangtranslationunit.h b/src/tools/clangbackend/source/clangtranslationunit.h index 9634c8cb51..e42d67ea6d 100644 --- a/src/tools/clangbackend/source/clangtranslationunit.h +++ b/src/tools/clangbackend/source/clangtranslationunit.h @@ -85,7 +85,7 @@ public: QVector<SourceRangeContainer> &skippedSourceRanges) const; - ReferencesResult references(uint line, uint column) const; + ReferencesResult references(uint line, uint column, bool localReferences = false) const; DiagnosticSet diagnostics() const; SourceLocation sourceLocationAt(uint line, uint column) const; |