diff --git a/src/plugins/clangrefactoring/clangrefactoring-source.pri b/src/plugins/clangrefactoring/clangrefactoring-source.pri index b08d292190c760d94f61ee8fa00ed68dbf2534d9..027f81794d4fd376e2197935c4d393638e6f3a5e 100644 --- a/src/plugins/clangrefactoring/clangrefactoring-source.pri +++ b/src/plugins/clangrefactoring/clangrefactoring-source.pri @@ -12,7 +12,8 @@ HEADERS += \ $$PWD/clangqueryhighlightmarker.h \ $$PWD/clangqueryexamplehighlighter.h \ $$PWD/clangqueryhighlighter.h \ - $$PWD/refactoringprojectupdater.h + $$PWD/refactoringprojectupdater.h \ + $$PWD/symbolqueryinterface.h SOURCES += \ $$PWD/refactoringengine.cpp \ diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp index 7ca01459c22909fb775fbc4c1b9b045bc0622c4b..152b548162e929315f366b5a529bde918b5bb0ae 100644 --- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp +++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp @@ -24,8 +24,13 @@ ****************************************************************************/ #include "clangrefactoringplugin.h" +#include "symbolquery.h" +#include "sqlitereadstatement.h" +#include "sqlitedatabase.h" +#include "querysqlitestatementfactory.h" #include <clangpchmanager/qtcreatorprojectupdater.h> +#include <clangsupport/refactoringdatabaseinitializer.h> #include <cpptools/cppmodelmanager.h> @@ -41,6 +46,7 @@ #include <utils/hostosinfo.h> #include <QDir> +#include <QApplication> namespace ClangRefactoring { @@ -59,21 +65,23 @@ std::unique_ptr<ClangRefactoringPluginData> ClangRefactoringPlugin::d; class ClangRefactoringPluginData { - using ProjectUpdater = ClangPchManager::QtCreatorProjectUpdater<ClangPchManager::ProjectUpdater>; public: + using QuerySqliteStatementFactory = QuerySqliteStatementFactory<Sqlite::Database, + Sqlite::ReadStatement>; + Sqlite::Database database{Utils::PathString{QDir::tempPath() + "/symbol.db"}}; ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; ClangBackEnd::FilePathCaching filePathCache{database}; RefactoringClient refactoringClient; ClangBackEnd::RefactoringConnectionClient connectionClient{&refactoringClient}; - RefactoringEngine engine{connectionClient.serverProxy(), refactoringClient, filePathCache}; + QuerySqliteStatementFactory statementFactory{database}; + SymbolQuery<QuerySqliteStatementFactory> symbolQuery{statementFactory}; + RefactoringEngine engine{connectionClient.serverProxy(), refactoringClient, filePathCache, symbolQuery}; + QtCreatorSearch qtCreatorSearch{*Core::SearchResultWindow::instance()}; QtCreatorClangQueryFindFilter qtCreatorfindFilter{connectionClient.serverProxy(), qtCreatorSearch, refactoringClient}; - ProjectUpdater projectUpdate{connectionClient.serverProxy()}; - - }; ClangRefactoringPlugin::ClangRefactoringPlugin() diff --git a/src/plugins/clangrefactoring/refactoringengine.cpp b/src/plugins/clangrefactoring/refactoringengine.cpp index 083b0089ff3f9df22a729b7b574eac9d7fa27c21..edccda68f83a7e2307ce2279c9be403862ac271a 100644 --- a/src/plugins/clangrefactoring/refactoringengine.cpp +++ b/src/plugins/clangrefactoring/refactoringengine.cpp @@ -24,20 +24,22 @@ ****************************************************************************/ #include "refactoringengine.h" - #include "projectpartutilities.h" - #include <refactoringserverinterface.h> #include <requestsourcelocationforrenamingmessage.h> #include <cpptools/compileroptionsbuilder.h> #include <cpptools/cpptoolsreuse.h> -#include <texteditor/textdocument.h> +#include <clangsupport/filepathcachinginterface.h> + +#include <utils/textutils.h> #include <QTextCursor> #include <QTextDocument> +#include <QTextBlock> +#include <QDir> #include <algorithm> @@ -47,13 +49,17 @@ using ClangBackEnd::RequestSourceLocationsForRenamingMessage; RefactoringEngine::RefactoringEngine(ClangBackEnd::RefactoringServerInterface &server, ClangBackEnd::RefactoringClientInterface &client, - ClangBackEnd::FilePathCachingInterface &filePathCache) + ClangBackEnd::FilePathCachingInterface &filePathCache, + SymbolQueryInterface &symbolQuery) : m_server(server), m_client(client), - m_filePathCache(filePathCache) + m_filePathCache(filePathCache), + m_symbolQuery(symbolQuery) { } +RefactoringEngine::~RefactoringEngine() = default; + void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data, CppTools::ProjectPart *projectPart, RenameCallback &&renameSymbolsCallback) @@ -89,6 +95,35 @@ void RefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &) // TODO: implement } +CppTools::Usages RefactoringEngine::locationsAt(const CppTools::CursorInEditor &data) const +{ + int line = 0, column = 0; + QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor()); + Utils::Text::convertPosition(cursor.document(), cursor.position(), &line, &column); + + const QByteArray filePath = data.filePath().toString().toLatin1(); + const ClangBackEnd::FilePathId filePathId = m_filePathCache.filePathId(filePath.constData()); + ClangRefactoring::SourceLocations usages = m_symbolQuery.locationsAt(filePathId, line, + column + 1); + CppTools::Usages result; + result.reserve(usages.size()); + for (const auto &location : usages) { + const Utils::SmallStringView path = m_filePathCache.filePath(location.filePathId).path(); + result.push_back({path, location.line, location.column}); + } + return result; +} + +void RefactoringEngine::findUsages(const CppTools::CursorInEditor &data, + CppTools::UsagesCallback &&showUsagesCallback) const +{ + int line = 0, column = 0; + QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor()); + Utils::Text::convertPosition(cursor.document(), cursor.position(), &line, &column); + + showUsagesCallback(locationsAt(data)); +} + bool RefactoringEngine::isRefactoringEngineAvailable() const { return m_server.isAvailable(); diff --git a/src/plugins/clangrefactoring/refactoringengine.h b/src/plugins/clangrefactoring/refactoringengine.h index eaa15ad7d542d4f7d31d9700434f7ab2b4410c65..5dd1bacd38493db86a2369e9a2bc64b6eafff3da 100644 --- a/src/plugins/clangrefactoring/refactoringengine.h +++ b/src/plugins/clangrefactoring/refactoringengine.h @@ -25,7 +25,9 @@ #pragma once -#include <filepathcachingfwd.h> +#include "symbolqueryinterface.h" + +#include <clangsupport/filepathcachingfwd.h> #include <cpptools/refactoringengineinterface.h> @@ -41,25 +43,33 @@ class RefactoringEngine : public CppTools::RefactoringEngineInterface public: RefactoringEngine(ClangBackEnd::RefactoringServerInterface &m_server, ClangBackEnd::RefactoringClientInterface &m_client, - ClangBackEnd::FilePathCachingInterface &filePathCache); + ClangBackEnd::FilePathCachingInterface &filePathCache, + SymbolQueryInterface &symbolQuery); + ~RefactoringEngine() override; void startLocalRenaming(const CppTools::CursorInEditor &data, CppTools::ProjectPart *projectPart, RenameCallback &&renameSymbolsCallback) override; void startGlobalRenaming(const CppTools::CursorInEditor &data) override; + void findUsages(const CppTools::CursorInEditor &data, + CppTools::UsagesCallback &&showUsagesCallback) const override; bool isRefactoringEngineAvailable() const override; void setRefactoringEngineAvailable(bool isAvailable); - ClangBackEnd::FilePathCachingInterface &filePathCache() + const ClangBackEnd::FilePathCachingInterface &filePathCache() const { return m_filePathCache; } private: + CppTools::Usages locationsAt(const CppTools::CursorInEditor &data) const; + ClangBackEnd::RefactoringServerInterface &m_server; ClangBackEnd::RefactoringClientInterface &m_client; ClangBackEnd::FilePathCachingInterface &m_filePathCache; + + SymbolQueryInterface &m_symbolQuery; }; } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/symbolquery.h b/src/plugins/clangrefactoring/symbolquery.h index dc4c43b1f29e632e5476c369c15c6c1c95edc65b..e8fd2157e30bba37c28fd459e6d9dd2cbf1d4915 100644 --- a/src/plugins/clangrefactoring/symbolquery.h +++ b/src/plugins/clangrefactoring/symbolquery.h @@ -25,7 +25,7 @@ #pragma once -#include <utils/smallstring.h> +#include "symbolqueryinterface.h" #include <filepathid.h> #include <sourcelocations.h> @@ -37,7 +37,7 @@ namespace ClangRefactoring { template <typename StatementFactory> -class SymbolQuery +class SymbolQuery final : public SymbolQueryInterface { using ReadStatement = typename StatementFactory::ReadStatementType; @@ -46,7 +46,7 @@ public: : m_statementFactory(statementFactory) {} - SourceLocations locationsAt(ClangBackEnd::FilePathId filePathId, int line, int utf8Column) + SourceLocations locationsAt(ClangBackEnd::FilePathId filePathId, int line, int utf8Column) override { ReadStatement &locationsStatement = m_statementFactory.selectLocationsForSymbolLocation; diff --git a/src/plugins/clangrefactoring/symbolqueryinterface.h b/src/plugins/clangrefactoring/symbolqueryinterface.h new file mode 100644 index 0000000000000000000000000000000000000000..c59f1f9c28e33d0ac024b5253f26c5c554b171e5 --- /dev/null +++ b/src/plugins/clangrefactoring/symbolqueryinterface.h @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** 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 "sourcelocations.h" + +namespace ClangRefactoring { + +class SymbolQueryInterface +{ +public: + virtual SourceLocations locationsAt(ClangBackEnd::FilePathId filePathId, int line, int utf8Column) = 0; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index cd3da7d7ee2004752e83bf63f93d7916e35a2e7f..9cadc402176a1907eedf0aa095fe5b16e044909b 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -44,6 +44,7 @@ #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/editormanager/documentmodel.h> #include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/find/searchresultwindow.h> #include <coreplugin/infobar.h> #include <cpptools/cppcanonicalsymbol.h> @@ -344,23 +345,73 @@ void CppEditorWidget::onShowInfoBarAction(const Id &id, bool show) action->setVisible(show); } -void CppEditorWidget::findUsages() +static QString getDocumentLine(const QTextDocument &document, int line) { - if (!d->m_modelManager) - return; + return document.findBlockByNumber(line - 1).text(); +} - SemanticInfo info = d->m_lastSemanticInfo; - info.snapshot = CppModelManager::instance()->snapshot(); - info.snapshot.insert(info.doc); +static QString getFileLine(const QString &path, int line) +{ + const IDocument *document = DocumentModel::documentForFilePath(path); + const TextDocument *textDocument = qobject_cast<const TextDocument *>(document); + if (textDocument) + return getDocumentLine(*textDocument->document(), line); + + const QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec(); + QString contents; + Utils::TextFileFormat format; + QString error; + if (Utils::TextFileFormat::readFile(path, defaultCodec, &contents, &format, &error) + != Utils::TextFileFormat::ReadSuccess) { + qWarning() << "Error reading file " << path << " : " << error; + return QString(); + } - if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) { - d->m_modelManager->findMacroUsages(*macro); - } else { - CanonicalSymbol cs(info.doc, info.snapshot); - Symbol *canonicalSymbol = cs(textCursor()); - if (canonicalSymbol) - d->m_modelManager->findUsages(canonicalSymbol, cs.context()); + const QTextDocument tmpDocument{contents}; + return getDocumentLine(tmpDocument, line); +} + +static void findRenameCallback(QTextCursor cursor, + const CppTools::Usages &usages, + bool rename = false) +{ + cursor = Utils::Text::wordStartCursor(cursor); + cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor); + QString text = cursor.selectedText(); + SearchResultWindow::SearchMode mode = SearchResultWindow::SearchOnly; + if (rename) + mode = SearchResultWindow::SearchAndReplace; + SearchResult *search = SearchResultWindow::instance()->startNewSearch( + QObject::tr("C++ Usages:"), + QString(), + text, + mode, + SearchResultWindow::PreserveCaseDisabled, + QLatin1String("CppEditor")); + for (const CppTools::Usage &usage : usages) { + const QString lineStr = getFileLine(usage.path, usage.line); + if (lineStr.isEmpty()) + continue; + Search::TextRange range{Search::TextPosition(usage.line, usage.column - 1), + Search::TextPosition(usage.line, usage.column + text.length() - 1)}; + search->addResult(usage.path, lineStr, range); } + search->finishSearch(false); + QObject::connect(search, &SearchResult::activated, + [](const Core::SearchResultItem& item) { + Core::EditorManager::openEditorAtSearchResult(item); + }); + search->popup(); +} + +void CppEditorWidget::findUsages() +{ + refactoringEngine().findUsages(CppTools::CursorInEditor{textCursor(), + textDocument()->filePath(), + this}, + [this](const CppTools::Usages &usages) { + findRenameCallback(textCursor(), usages); + }); } void CppEditorWidget::renameUsagesInternal(const QString &replacement) diff --git a/src/plugins/cppeditor/cppeditorwidget.h b/src/plugins/cppeditor/cppeditorwidget.h index 166ff10557dba07382ad68206755190b5a15b3ba..fad200ef874656e5e4caf0ef10b9c3bf48b1a331 100644 --- a/src/plugins/cppeditor/cppeditorwidget.h +++ b/src/plugins/cppeditor/cppeditorwidget.h @@ -59,7 +59,6 @@ public: CppEditorDocument *cppEditorDocument() const; CppTools::CppEditorOutline *outline() const; - CppTools::SemanticInfo semanticInfo() const; bool isSemanticInfoValidExceptLocalUses() const; bool isSemanticInfoValid() const; @@ -88,6 +87,7 @@ public: static void updateWidgetHighlighting(QWidget *widget, bool highlight); static bool isWidgetHighlighted(QWidget *widget); + CppTools::SemanticInfo semanticInfo() const override; void updateSemanticInfo() override; void invokeTextEditorWidgetAssist(TextEditor::AssistKind assistKind, TextEditor::IAssistProvider *provider) override; diff --git a/src/plugins/cpptools/cppeditorwidgetinterface.h b/src/plugins/cpptools/cppeditorwidgetinterface.h index 309fa581cdd825e48778fb8c8e9823e2e459cbf2..ed8c7e0a46e5d930c4b1d9fc21396cd07e7fe9c0 100644 --- a/src/plugins/cpptools/cppeditorwidgetinterface.h +++ b/src/plugins/cpptools/cppeditorwidgetinterface.h @@ -35,6 +35,8 @@ namespace TextEditor { class IAssistProvider; } namespace CppTools { +class SemanticInfo; + class CPPTOOLS_EXPORT CppEditorWidgetInterface { public: @@ -44,6 +46,7 @@ public: } virtual void showPreProcessorWidget() = 0; + virtual SemanticInfo semanticInfo() const = 0; virtual void updateSemanticInfo() = 0; virtual void renameUsagesInternal(const QString &replacement) = 0; diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 633ad7a747020449c92c72ad651fe4f62b21989c..db5a4306e22fdcb19a26f9cec9ca60277789e0c3 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -300,6 +300,13 @@ void CppModelManager::startGlobalRenaming(const CursorInEditor &data) engine->startGlobalRenaming(data); } +void CppModelManager::findUsages(const CppTools::CursorInEditor &data, + UsagesCallback &&showUsagesCallback) const +{ + RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines); + engine->findUsages(data, std::move(showUsagesCallback)); +} + void CppModelManager::addRefactoringEngine(RefactoringEngineType type, RefactoringEngineInterface *refactoringEngine) { diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 0a66e63badbc968362f72913e2e8f2d916ea42ae..d2a51e2483f21684181d926b1ec0c9086f2882fe 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -152,6 +152,8 @@ public: CppTools::ProjectPart *projectPart, RenameCallback &&renameSymbolsCallback) final; void startGlobalRenaming(const CursorInEditor &data) final; + void findUsages(const CppTools::CursorInEditor &data, + UsagesCallback &&showUsagesCallback) const final; void renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context, const QString &replacement = QString()); diff --git a/src/plugins/cpptools/cpprefactoringengine.cpp b/src/plugins/cpptools/cpprefactoringengine.cpp index 705a8ecc99ec076431a920dcad31f027468b9304..ffa48edbd0d34c4938635c32eb34ee0773979e21 100644 --- a/src/plugins/cpptools/cpprefactoringengine.cpp +++ b/src/plugins/cpptools/cpprefactoringengine.cpp @@ -23,15 +23,20 @@ ** ****************************************************************************/ +#include "cppcanonicalsymbol.h" +#include "cppmodelmanager.h" #include "cpprefactoringengine.h" -#include "texteditor/texteditor.h" +#include "cppsemanticinfo.h" +#include "cpptoolsreuse.h" -#include "utils/qtcassert.h" +#include <texteditor/texteditor.h> + +#include <utils/qtcassert.h> namespace CppTools { -void CppRefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data, - CppTools::ProjectPart *, +void CppRefactoringEngine::startLocalRenaming(const CursorInEditor &data, + ProjectPart *, RenameCallback &&renameSymbolsCallback) { CppEditorWidgetInterface *editorWidget = data.editorWidget(); @@ -45,11 +50,35 @@ void CppRefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &da data.cursor().document()->revision()); } -void CppRefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &data) +void CppRefactoringEngine::startGlobalRenaming(const CursorInEditor &data) { CppEditorWidgetInterface *editorWidget = data.editorWidget(); QTC_ASSERT(editorWidget, return;); editorWidget->renameUsages(); } +void CppRefactoringEngine::findUsages(const CursorInEditor &data, + UsagesCallback &&) const +{ + CppModelManager *modelManager = CppModelManager::instance(); + if (!modelManager) + return; + + CppEditorWidgetInterface *editorWidget = data.editorWidget(); + QTC_ASSERT(editorWidget, return;); + + SemanticInfo info = editorWidget->semanticInfo(); + info.snapshot = modelManager->snapshot(); + info.snapshot.insert(info.doc); + const QTextCursor &cursor = data.cursor(); + if (const CPlusPlus::Macro *macro = findCanonicalMacro(cursor, info.doc)) { + modelManager->findMacroUsages(*macro); + } else { + CanonicalSymbol cs(info.doc, info.snapshot); + CPlusPlus::Symbol *canonicalSymbol = cs(cursor); + if (canonicalSymbol) + modelManager->findUsages(canonicalSymbol, cs.context()); + } +} + } // namespace CppEditor diff --git a/src/plugins/cpptools/cpprefactoringengine.h b/src/plugins/cpptools/cpprefactoringengine.h index 9ea61ec29ad466b032e9fac95544fa815872fe62..cfaae23d16384d2e62e6c12a3a9f52f794504cbf 100644 --- a/src/plugins/cpptools/cpprefactoringengine.h +++ b/src/plugins/cpptools/cpprefactoringengine.h @@ -32,10 +32,12 @@ namespace CppTools { class CPPTOOLS_EXPORT CppRefactoringEngine : public RefactoringEngineInterface { public: - void startLocalRenaming(const CppTools::CursorInEditor &data, - CppTools::ProjectPart *projectPart, + void startLocalRenaming(const CursorInEditor &data, + ProjectPart *projectPart, RenameCallback &&renameSymbolsCallback) override; - void startGlobalRenaming(const CppTools::CursorInEditor &data) override; + void startGlobalRenaming(const CursorInEditor &data) override; + + void findUsages(const CursorInEditor &data, UsagesCallback &&) const override; }; } // namespace CppEditor diff --git a/src/plugins/cpptools/refactoringengineinterface.h b/src/plugins/cpptools/refactoringengineinterface.h index f18b6ba466c2fe056eb6f915311318fb91f88c9f..05cf8766b8aaf9d343ccb35f489b4d02efbcca74 100644 --- a/src/plugins/cpptools/refactoringengineinterface.h +++ b/src/plugins/cpptools/refactoringengineinterface.h @@ -27,8 +27,10 @@ #include "cpptools_global.h" #include "cursorineditor.h" +#include "usages.h" #include <utils/fileutils.h> +#include <utils/smallstring.h> #include <clangsupport/sourcelocationscontainer.h> #include <clangsupport/refactoringclientinterface.h> @@ -53,10 +55,14 @@ class CPPTOOLS_EXPORT RefactoringEngineInterface public: using RenameCallback = ClangBackEnd::RefactoringClientInterface::RenameCallback; + virtual ~RefactoringEngineInterface() {} + virtual void startLocalRenaming(const CursorInEditor &data, CppTools::ProjectPart *projectPart, RenameCallback &&renameSymbolsCallback) = 0; virtual void startGlobalRenaming(const CursorInEditor &data) = 0; + virtual void findUsages(const CppTools::CursorInEditor &data, + UsagesCallback &&showUsagesCallback) const = 0; virtual bool isRefactoringEngineAvailable() const { return true; } }; diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp index 7c628fa376583eac2728fa7c7559dbd36be0dcd6..4b9b1a02f021034d07dfb03d8ab8b6a07076d52c 100644 --- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp +++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp @@ -26,6 +26,7 @@ #include <QCommandLineParser> #include <QCoreApplication> #include <QLoggingCategory> +#include <QApplication> #include <QDir> #include <connectionserver.h> diff --git a/tests/unit/unittest/mocksymbolquery.h b/tests/unit/unittest/mocksymbolquery.h new file mode 100644 index 0000000000000000000000000000000000000000..07282897280f445d71eb0d361e447e59a89178c8 --- /dev/null +++ b/tests/unit/unittest/mocksymbolquery.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** 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 "googletest.h" + +#include <symbolqueryinterface.h> + +class MockSymbolQuery : public ClangRefactoring::SymbolQueryInterface +{ +public: + MOCK_METHOD3(locationsAt, ClangRefactoring::SourceLocations(ClangBackEnd::FilePathId filePathId, int line, int utf8Column)); +}; diff --git a/tests/unit/unittest/refactoringclient-test.cpp b/tests/unit/unittest/refactoringclient-test.cpp index 9d81d73b689bb09bd152c1af71808bf73af15e22..a28d27b3e9a6cdfd63da5bad6d87ba98bc8c4c7e 100644 --- a/tests/unit/unittest/refactoringclient-test.cpp +++ b/tests/unit/unittest/refactoringclient-test.cpp @@ -27,6 +27,7 @@ #include "mockrefactoringclientcallback.h" #include "mocksearchhandle.h" #include "mockfilepathcaching.h" +#include "mocksymbolquery.h" #include <clangqueryprojectsfindfilter.h> #include <refactoringclient.h> @@ -71,10 +72,11 @@ class RefactoringClient : public ::testing::Test protected: NiceMock<MockFilePathCaching> mockFilePathCaching; NiceMock<MockSearchHandle> mockSearchHandle; + NiceMock<MockSymbolQuery> mockSymbolQuery; MockRefactoringClientCallBack callbackMock; ClangRefactoring::RefactoringClient client; ClangBackEnd::RefactoringConnectionClient connectionClient{&client}; - RefactoringEngine engine{connectionClient.serverProxy(), client, mockFilePathCaching}; + RefactoringEngine engine{connectionClient.serverProxy(), client, mockFilePathCaching, mockSymbolQuery}; QString fileContent{QStringLiteral("int x;\nint y;")}; QTextDocument textDocument{fileContent}; QTextCursor cursor{&textDocument}; diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp index 83fe1085c6f21c012506d06df08915fa24dafaa4..e3b148c30bf6629bb21f1005799236dd1d6b87dc 100644 --- a/tests/unit/unittest/refactoringengine-test.cpp +++ b/tests/unit/unittest/refactoringengine-test.cpp @@ -28,6 +28,7 @@ #include "mockfilepathcaching.h" #include "mockrefactoringserver.h" #include "mockrefactoringclient.h" +#include "mocksymbolquery.h" #include <refactoringengine.h> @@ -61,9 +62,11 @@ protected: NiceMock<MockFilePathCaching> mockFilePathCaching; MockRefactoringServer mockRefactoringServer; MockRefactoringClient mockRefactoringClient; + MockSymbolQuery mockSymbolQuery; ClangRefactoring::RefactoringEngine engine{mockRefactoringServer, mockRefactoringClient, - mockFilePathCaching}; + mockFilePathCaching, + mockSymbolQuery}; QString fileContent{QStringLiteral("int x;\nint y;")}; QTextDocument textDocument{fileContent}; QTextCursor cursor{&textDocument}; @@ -102,6 +105,16 @@ TEST_F(RefactoringEngine, AfterSendRequestSourceLocationsForRenamingMessageIsUnu ASSERT_FALSE(engine.isRefactoringEngineAvailable()); } +TEST_F(RefactoringEngine, ExpectLocationsAtInFindUsages) +{ + cursor.setPosition(11); + + EXPECT_CALL(mockSymbolQuery, locationsAt(_, 2, 5)); + + engine.findUsages(CppTools::CursorInEditor{cursor, filePath}, + [](const CppTools::Usages &) {}); +} + TEST_F(RefactoringEngine, EngineIsNotUsableForUnusableServer) { ASSERT_FALSE(engine.isRefactoringEngineAvailable()); diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index a75f3dc215127165eba98bf3af287c6253684a6f..40666a27e93564ee501e553ff980abd0c5f85d4e 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -210,7 +210,8 @@ HEADERS += \ mockfilepathstorage.h \ mockfilepathcaching.h \ mocksqlitestatement.h \ - unittest-utility-functions.h + unittest-utility-functions.h \ + mocksymbolquery.h !isEmpty(LIBCLANG_LIBS) { HEADERS += \