diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/clangrefactoring/clangrefactoring-source.pri | 3 | ||||
-rw-r--r-- | src/plugins/clangrefactoring/clangrefactoringplugin.cpp | 18 | ||||
-rw-r--r-- | src/plugins/clangrefactoring/refactoringengine.cpp | 45 | ||||
-rw-r--r-- | src/plugins/clangrefactoring/refactoringengine.h | 16 | ||||
-rw-r--r-- | src/plugins/clangrefactoring/symbolquery.h | 6 | ||||
-rw-r--r-- | src/plugins/clangrefactoring/symbolqueryinterface.h | 38 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorwidget.cpp | 77 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorwidget.h | 2 | ||||
-rw-r--r-- | src/plugins/cpptools/cppeditorwidgetinterface.h | 3 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.cpp | 7 | ||||
-rw-r--r-- | src/plugins/cpptools/cppmodelmanager.h | 2 | ||||
-rw-r--r-- | src/plugins/cpptools/cpprefactoringengine.cpp | 39 | ||||
-rw-r--r-- | src/plugins/cpptools/cpprefactoringengine.h | 8 | ||||
-rw-r--r-- | src/plugins/cpptools/refactoringengineinterface.h | 6 | ||||
-rw-r--r-- | src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp | 1 |
15 files changed, 232 insertions, 39 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> |