summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2017-09-19 15:38:20 +0200
committerIvan Donchevskii <ivan.donchevskii@qt.io>2017-10-24 10:46:52 +0000
commit050b4dd2f5b2545e3afcd5b7f2c7293be8ddb74c (patch)
tree7699d5fd6a4ae1603548e04f4f62e258d3405cbd
parent263cdc03977a89eeb61d8dddd99efb7bf1e752fa (diff)
downloadqt-creator-050b4dd2f5b2545e3afcd5b7f2c7293be8ddb74c.tar.gz
Clang: implement findUsages with existing index
Functionality is limited to the abilities of current index which is not updated and is generated only at project open. Search box temporarily doesn't allow to "Search again". Change-Id: Id1047f27ad0aafc901f06aa51ad38ceab95eaebb Reviewed-by: Marco Bubke <marco.bubke@qt.io> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring-source.pri3
-rw-r--r--src/plugins/clangrefactoring/clangrefactoringplugin.cpp18
-rw-r--r--src/plugins/clangrefactoring/refactoringengine.cpp45
-rw-r--r--src/plugins/clangrefactoring/refactoringengine.h16
-rw-r--r--src/plugins/clangrefactoring/symbolquery.h6
-rw-r--r--src/plugins/clangrefactoring/symbolqueryinterface.h38
-rw-r--r--src/plugins/cppeditor/cppeditorwidget.cpp77
-rw-r--r--src/plugins/cppeditor/cppeditorwidget.h2
-rw-r--r--src/plugins/cpptools/cppeditorwidgetinterface.h3
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp7
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h2
-rw-r--r--src/plugins/cpptools/cpprefactoringengine.cpp39
-rw-r--r--src/plugins/cpptools/cpprefactoringengine.h8
-rw-r--r--src/plugins/cpptools/refactoringengineinterface.h6
-rw-r--r--src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp1
-rw-r--r--tests/unit/unittest/mocksymbolquery.h36
-rw-r--r--tests/unit/unittest/refactoringclient-test.cpp4
-rw-r--r--tests/unit/unittest/refactoringengine-test.cpp15
-rw-r--r--tests/unit/unittest/unittest.pro3
19 files changed, 287 insertions, 42 deletions
diff --git a/src/plugins/clangrefactoring/clangrefactoring-source.pri b/src/plugins/clangrefactoring/clangrefactoring-source.pri
index b08d292190..027f81794d 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 7ca01459c2..152b548162 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 083b0089ff..edccda68f8 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 eaa15ad7d5..5dd1bacd38 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 dc4c43b1f2..e8fd2157e3 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 0000000000..c59f1f9c28
--- /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 cd3da7d7ee..9cadc40217 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 166ff10557..fad200ef87 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 309fa581cd..ed8c7e0a46 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 633ad7a747..db5a4306e2 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 0a66e63bad..d2a51e2483 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 705a8ecc99..ffa48edbd0 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 9ea61ec29a..cfaae23d16 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 f18b6ba466..05cf8766b8 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 7c628fa376..4b9b1a02f0 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 0000000000..0728289728
--- /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 9d81d73b68..a28d27b3e9 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 83fe1085c6..e3b148c30b 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 a75f3dc215..40666a27e9 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 += \