CppTools: add multiple refactoring engines support

Make model manager able to select the most functional
refactoring engine from the available ones.

Change-Id: I74031c910706fd694a0a7def022531501f1ea005
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Ivan Donchevskii
2017-09-25 16:41:17 +02:00
parent 57e35274c2
commit 5c554c0de9
17 changed files with 99 additions and 55 deletions

View File

@@ -51,17 +51,17 @@ public:
virtual void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) = 0; virtual void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) = 0;
virtual void cancel() = 0; virtual void cancel() = 0;
bool isUsable() const bool isAvailable() const
{ {
return isUsable_; return isAvailable_;
} }
void setUsable(bool isUsable) void setAvailable(bool isAvailable)
{ {
isUsable_ = isUsable; isAvailable_ = isAvailable;
} }
private: private:
bool isUsable_ = false; bool isAvailable_ = false;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -27,7 +27,7 @@
#include "clangsupport_global.h" #include "clangsupport_global.h"
#include <utf8string.h> #include <sqlite/utf8string.h>
namespace ClangBackEnd { namespace ClangBackEnd {

View File

@@ -25,10 +25,10 @@
#pragma once #pragma once
namespace Utils {
using uint = unsigned int; using uint = unsigned int;
namespace Utils {
class SmallStringView; class SmallStringView;
template <uint Size> template <uint Size>
class BasicSmallString; class BasicSmallString;

View File

@@ -127,14 +127,14 @@ void ClangQueryProjectsFindFilter::setProjectParts(const std::vector<CppTools::P
this->m_projectParts = projectParts; this->m_projectParts = projectParts;
} }
bool ClangQueryProjectsFindFilter::isUsable() const bool ClangQueryProjectsFindFilter::isAvailable() const
{ {
return m_server.isUsable(); return m_server.isAvailable();
} }
void ClangQueryProjectsFindFilter::setUsable(bool isUsable) void ClangQueryProjectsFindFilter::setAvailable(bool isAvailable)
{ {
m_server.setUsable(isUsable); m_server.setAvailable(isAvailable);
} }
SearchHandle *ClangQueryProjectsFindFilter::searchHandleForTestOnly() const SearchHandle *ClangQueryProjectsFindFilter::searchHandleForTestOnly() const

View File

@@ -66,8 +66,8 @@ public:
void setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &m_projectParts); void setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &m_projectParts);
bool isUsable() const; bool isAvailable() const;
void setUsable(bool isUsable); void setAvailable(bool isAvailable);
SearchHandle* searchHandleForTestOnly() const; SearchHandle* searchHandleForTestOnly() const;

View File

@@ -100,13 +100,15 @@ bool ClangRefactoringPlugin::initialize(const QStringList & /*arguments*/, QStri
void ClangRefactoringPlugin::extensionsInitialized() void ClangRefactoringPlugin::extensionsInitialized()
{ {
CppTools::CppModelManager::setRefactoringEngine(&refactoringEngine()); CppTools::CppModelManager::addRefactoringEngine(
CppTools::RefactoringEngineType::ClangRefactoring, &refactoringEngine());
} }
ExtensionSystem::IPlugin::ShutdownFlag ClangRefactoringPlugin::aboutToShutdown() ExtensionSystem::IPlugin::ShutdownFlag ClangRefactoringPlugin::aboutToShutdown()
{ {
ExtensionSystem::PluginManager::removeObject(&d->qtCreatorfindFilter); ExtensionSystem::PluginManager::removeObject(&d->qtCreatorfindFilter);
CppTools::CppModelManager::setRefactoringEngine(nullptr); CppTools::CppModelManager::removeRefactoringEngine(
CppTools::RefactoringEngineType::ClangRefactoring);
d->refactoringClient.setRefactoringConnectionClient(nullptr); d->refactoringClient.setRefactoringConnectionClient(nullptr);
d->refactoringClient.setRefactoringEngine(nullptr); d->refactoringClient.setRefactoringEngine(nullptr);
@@ -137,7 +139,7 @@ void ClangRefactoringPlugin::connectBackend()
void ClangRefactoringPlugin::backendIsConnected() void ClangRefactoringPlugin::backendIsConnected()
{ {
d->engine.setUsable(true); d->engine.setRefactoringEngineAvailable(true);
} }
} // namespace ClangRefactoring } // namespace ClangRefactoring

View File

@@ -47,7 +47,7 @@ void RefactoringClient::sourceLocationsForRenamingMessage(
message.sourceLocations(), message.sourceLocations(),
message.textDocumentRevision()); message.textDocumentRevision());
m_refactoringEngine->setUsable(true); m_refactoringEngine->setRefactoringEngineAvailable(true);
} }
void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage( void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage(

View File

@@ -60,7 +60,7 @@ void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
{ {
using CppTools::ClangCompilerOptionsBuilder; using CppTools::ClangCompilerOptionsBuilder;
setUsable(false); setRefactoringEngineAvailable(false);
m_client.setLocalRenamingCallback(std::move(renameSymbolsCallback)); m_client.setLocalRenamingCallback(std::move(renameSymbolsCallback));
@@ -89,14 +89,14 @@ void RefactoringEngine::startGlobalRenaming(const CppTools::CursorInEditor &)
// TODO: implement // TODO: implement
} }
bool RefactoringEngine::isUsable() const bool RefactoringEngine::isRefactoringEngineAvailable() const
{ {
return m_server.isUsable(); return m_server.isAvailable();
} }
void RefactoringEngine::setUsable(bool isUsable) void RefactoringEngine::setRefactoringEngineAvailable(bool isAvailable)
{ {
m_server.setUsable(isUsable); m_server.setAvailable(isAvailable);
} }
} // namespace ClangRefactoring } // namespace ClangRefactoring

View File

@@ -48,8 +48,8 @@ public:
RenameCallback &&renameSymbolsCallback) override; RenameCallback &&renameSymbolsCallback) override;
void startGlobalRenaming(const CppTools::CursorInEditor &data) override; void startGlobalRenaming(const CppTools::CursorInEditor &data) override;
bool isUsable() const override; bool isRefactoringEngineAvailable() const override;
void setUsable(bool isUsable); void setRefactoringEngineAvailable(bool isAvailable);
ClangBackEnd::FilePathCachingInterface &filePathCache() ClangBackEnd::FilePathCachingInterface &filePathCache()
{ {

View File

@@ -524,7 +524,7 @@ void CppEditorWidget::renameSymbolUnderCursor()
using ClangBackEnd::SourceLocationsContainer; using ClangBackEnd::SourceLocationsContainer;
ProjectPart *projPart = projectPart(); ProjectPart *projPart = projectPart();
if (!refactoringEngine().isUsable() || !projPart) if (!projPart)
return; return;
d->m_useSelectionsUpdater.abortSchedule(); d->m_useSelectionsUpdater.abortSchedule();
@@ -686,7 +686,7 @@ RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() const
RefactoringEngineInterface &CppEditorWidget::refactoringEngine() const RefactoringEngineInterface &CppEditorWidget::refactoringEngine() const
{ {
return CppTools::CppModelManager::refactoringEngine(); return *CppTools::CppModelManager::instance();
} }
CppTools::FollowSymbolInterface &CppEditorWidget::followSymbolInterface() const CppTools::FollowSymbolInterface &CppEditorWidget::followSymbolInterface() const

View File

@@ -119,6 +119,9 @@ protected:
#endif // QTCREATOR_WITH_DUMP_AST #endif // QTCREATOR_WITH_DUMP_AST
namespace CppTools { namespace CppTools {
using REType = RefactoringEngineType;
namespace Internal { namespace Internal {
static QMutex m_instanceMutex; static QMutex m_instanceMutex;
@@ -167,7 +170,8 @@ public:
// Refactoring // Refactoring
CppRefactoringEngine m_builtInRefactoringEngine; CppRefactoringEngine m_builtInRefactoringEngine;
RefactoringEngineInterface *m_refactoringEngine { &m_builtInRefactoringEngine }; using REHash = QMap<REType, RefactoringEngineInterface *>;
REHash m_refactoringEngines {{REType::BuiltIn, &m_builtInRefactoringEngine}};
}; };
} // namespace Internal } // namespace Internal
@@ -267,17 +271,44 @@ QString CppModelManager::editorConfigurationFileName()
return QLatin1String("<per-editor-defines>"); return QLatin1String("<per-editor-defines>");
} }
void CppModelManager::setRefactoringEngine(RefactoringEngineInterface *refactoringEngine) static RefactoringEngineInterface *getRefactoringEngine(
CppModelManagerPrivate::REHash &engines, bool excludeClangCodeModel = true)
{ {
if (refactoringEngine) RefactoringEngineInterface *currentEngine = engines[REType::BuiltIn];
instance()->d->m_refactoringEngine = refactoringEngine; if (!excludeClangCodeModel && engines.find(REType::ClangCodeModel) != engines.end()) {
else currentEngine = engines[REType::ClangCodeModel];
instance()->d->m_refactoringEngine = &instance()->d->m_builtInRefactoringEngine; } else if (engines.find(REType::ClangRefactoring) != engines.end()) {
RefactoringEngineInterface *engine = engines[REType::ClangRefactoring];
if (engine->isRefactoringEngineAvailable())
currentEngine = engine;
}
return currentEngine;
} }
RefactoringEngineInterface &CppModelManager::refactoringEngine() void CppModelManager::startLocalRenaming(const CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback)
{ {
return *instance()->d->m_refactoringEngine; RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines,
false);
engine->startLocalRenaming(data, projectPart, std::move(renameSymbolsCallback));
}
void CppModelManager::startGlobalRenaming(const CursorInEditor &data)
{
RefactoringEngineInterface *engine = getRefactoringEngine(instance()->d->m_refactoringEngines);
engine->startGlobalRenaming(data);
}
void CppModelManager::addRefactoringEngine(RefactoringEngineType type,
RefactoringEngineInterface *refactoringEngine)
{
instance()->d->m_refactoringEngines[type] = refactoringEngine;
}
void CppModelManager::removeRefactoringEngine(RefactoringEngineType type)
{
instance()->d->m_refactoringEngines.remove(type);
} }
FollowSymbolInterface &CppModelManager::followSymbolInterface() const FollowSymbolInterface &CppModelManager::followSymbolInterface() const

View File

@@ -27,6 +27,7 @@
#include "cpptools_global.h" #include "cpptools_global.h"
#include "refactoringengineinterface.h"
#include "projectinfo.h" #include "projectinfo.h"
#include "projectpart.h" #include "projectpart.h"
#include "projectpartheaderpath.h" #include "projectpartheaderpath.h"
@@ -53,7 +54,6 @@ class CppCompletionAssistProvider;
class CppEditorDocumentHandle; class CppEditorDocumentHandle;
class CppIndexingSupport; class CppIndexingSupport;
class ModelManagerSupportProvider; class ModelManagerSupportProvider;
class RefactoringEngineInterface;
class FollowSymbolInterface; class FollowSymbolInterface;
class SymbolFinder; class SymbolFinder;
class WorkingCopy; class WorkingCopy;
@@ -67,7 +67,15 @@ namespace Tests {
class ModelManagerTestHelper; class ModelManagerTestHelper;
} }
class CPPTOOLS_EXPORT CppModelManager : public CPlusPlus::CppModelManagerBase enum class RefactoringEngineType : int
{
BuiltIn = 0,
ClangCodeModel = 1,
ClangRefactoring = 2
};
class CPPTOOLS_EXPORT CppModelManager final : public CPlusPlus::CppModelManagerBase,
public RefactoringEngineInterface
{ {
Q_OBJECT Q_OBJECT
@@ -140,6 +148,11 @@ public:
QList<int> references(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context); QList<int> references(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context);
void startLocalRenaming(const CursorInEditor &data,
CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) final;
void startGlobalRenaming(const CursorInEditor &data) final;
void renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context, void renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context,
const QString &replacement = QString()); const QString &replacement = QString());
void findUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context); void findUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context);
@@ -179,8 +192,9 @@ public:
static QString configurationFileName(); static QString configurationFileName();
static QString editorConfigurationFileName(); static QString editorConfigurationFileName();
static void setRefactoringEngine(RefactoringEngineInterface *refactoringEngine); static void addRefactoringEngine(RefactoringEngineType type,
static RefactoringEngineInterface &refactoringEngine(); RefactoringEngineInterface *refactoringEngine);
static void removeRefactoringEngine(RefactoringEngineType type);
void renameIncludes(const QString &oldFileName, const QString &newFileName); void renameIncludes(const QString &oldFileName, const QString &newFileName);

View File

@@ -36,8 +36,6 @@ public:
CppTools::ProjectPart *projectPart, CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) override; RenameCallback &&renameSymbolsCallback) override;
void startGlobalRenaming(const CppTools::CursorInEditor &data) override; void startGlobalRenaming(const CppTools::CursorInEditor &data) override;
bool isUsable() const override { return true; }
}; };
} // namespace CppEditor } // namespace CppEditor

View File

@@ -57,8 +57,7 @@ public:
CppTools::ProjectPart *projectPart, CppTools::ProjectPart *projectPart,
RenameCallback &&renameSymbolsCallback) = 0; RenameCallback &&renameSymbolsCallback) = 0;
virtual void startGlobalRenaming(const CursorInEditor &data) = 0; virtual void startGlobalRenaming(const CursorInEditor &data) = 0;
virtual bool isRefactoringEngineAvailable() const { return true; }
virtual bool isUsable() const = 0;
}; };
} // namespace CppTools } // namespace CppTools

View File

@@ -82,25 +82,25 @@ TEST_F(ClangQueryProjectFindFilter, SupportedFindFlags)
TEST_F(ClangQueryProjectFindFilter, IsNotUsableForUnusableServer) TEST_F(ClangQueryProjectFindFilter, IsNotUsableForUnusableServer)
{ {
auto isUsable = findFilter.isUsable(); auto isUsable = findFilter.isAvailable();
ASSERT_FALSE(isUsable); ASSERT_FALSE(isUsable);
} }
TEST_F(ClangQueryProjectFindFilter, IsUsableForUsableServer) TEST_F(ClangQueryProjectFindFilter, IsUsableForUsableServer)
{ {
mockRefactoringServer.setUsable(true); mockRefactoringServer.setAvailable(true);
auto isUsable = findFilter.isUsable(); auto isUsable = findFilter.isAvailable();
ASSERT_TRUE(isUsable); ASSERT_TRUE(isUsable);
} }
TEST_F(ClangQueryProjectFindFilter, ServerIsUsableForUsableFindFilter) TEST_F(ClangQueryProjectFindFilter, ServerIsUsableForUsableFindFilter)
{ {
findFilter.setUsable(true); findFilter.setAvailable(true);
auto isUsable = mockRefactoringServer.isUsable(); auto isUsable = mockRefactoringServer.isAvailable();
ASSERT_TRUE(isUsable); ASSERT_TRUE(isUsable);
} }

View File

@@ -123,7 +123,7 @@ TEST_F(RefactoringClient, AfterSourceLocationsForRenamingEngineIsUsableAgain)
client.sourceLocationsForRenamingMessage(std::move(renameMessage)); client.sourceLocationsForRenamingMessage(std::move(renameMessage));
ASSERT_TRUE(engine.isUsable()); ASSERT_TRUE(engine.isRefactoringEngineAvailable());
} }
TEST_F(RefactoringClient, AfterStartLocalRenameHasValidCallback) TEST_F(RefactoringClient, AfterStartLocalRenameHasValidCallback)

View File

@@ -99,26 +99,26 @@ TEST_F(RefactoringEngine, AfterSendRequestSourceLocationsForRenamingMessageIsUnu
engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath}, engine.startLocalRenaming(CppTools::CursorInEditor{cursor, filePath},
projectPart.data(), {}); projectPart.data(), {});
ASSERT_FALSE(engine.isUsable()); ASSERT_FALSE(engine.isRefactoringEngineAvailable());
} }
TEST_F(RefactoringEngine, EngineIsNotUsableForUnusableServer) TEST_F(RefactoringEngine, EngineIsNotUsableForUnusableServer)
{ {
ASSERT_FALSE(engine.isUsable()); ASSERT_FALSE(engine.isRefactoringEngineAvailable());
} }
TEST_F(RefactoringEngine, EngineIsUsableForUsableServer) TEST_F(RefactoringEngine, EngineIsUsableForUsableServer)
{ {
mockRefactoringServer.setUsable(true); mockRefactoringServer.setAvailable(true);
ASSERT_TRUE(engine.isUsable()); ASSERT_TRUE(engine.isRefactoringEngineAvailable());
} }
TEST_F(RefactoringEngine, ServerIsUsableForUsableEngine) TEST_F(RefactoringEngine, ServerIsUsableForUsableEngine)
{ {
engine.setUsable(true); engine.setRefactoringEngineAvailable(true);
ASSERT_TRUE(mockRefactoringServer.isUsable()); ASSERT_TRUE(mockRefactoringServer.isAvailable());
} }
void RefactoringEngine::SetUp() void RefactoringEngine::SetUp()