diff options
author | Marco Bubke <marco.bubke@qt.io> | 2017-07-03 12:35:58 +0200 |
---|---|---|
committer | Tim Jenssen <tim.jenssen@qt.io> | 2017-07-20 13:32:39 +0000 |
commit | a31eae4d0ad1ffd5a06cd5beff9e16473f929615 (patch) | |
tree | fa0ed3976b9c6822fe24a05346f980a5bd8f3026 /src | |
parent | 8c4127ebacd0508f12db79689ef976a814729d91 (diff) | |
download | qt-creator-a31eae4d0ad1ffd5a06cd5beff9e16473f929615.tar.gz |
Clang: Add clang query pane
We now support highlighting for an example text and for the query.
Change-Id: I88c415ff871cf3e4c2d4fc83d60a8555bf0ce08a
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Diffstat (limited to 'src')
57 files changed, 2040 insertions, 230 deletions
diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri index 9664775dd1..e930763843 100644 --- a/src/libs/clangbackendipc/clangbackendipc-lib.pri +++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri @@ -79,7 +79,9 @@ SOURCES += $$PWD/clangcodemodelserverinterface.cpp \ $$PWD/pchmanagerclientproxy.cpp \ $$PWD/projectpartpch.cpp \ $$PWD/precompiledheadersupdatedmessage.cpp \ - $$PWD/removepchprojectpartsmessage.cpp + $$PWD/removepchprojectpartsmessage.cpp \ + $$PWD/sourcerangesforquerymessage.cpp \ + $$PWD/requestsourcerangesforquerymessage.cpp HEADERS += \ $$PWD/clangcodemodelserverinterface.h \ @@ -159,5 +161,10 @@ HEADERS += \ $$PWD/removepchprojectpartsmessage.h \ $$PWD/clangcodemodelclientmessages.h \ $$PWD/clangcodemodelservermessages.h \ + $$PWD/sourcerangesforquerymessage.h \ + $$PWD/clangrefactoringmessages.h \ + $$PWD/clangrefactoringclientmessages.h \ + $$PWD/clangrefactoringservermessages.h \ + $$PWD/requestsourcerangesforquerymessage.h contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols diff --git a/src/libs/clangbackendipc/clangbackendipc_global.h b/src/libs/clangbackendipc/clangbackendipc_global.h index 8f7f08a6ee..e48a05e7d9 100644 --- a/src/libs/clangbackendipc/clangbackendipc_global.h +++ b/src/libs/clangbackendipc/clangbackendipc_global.h @@ -128,7 +128,9 @@ enum class MessageType : quint8 { RequestSourceLocationsForRenamingMessage, RequestSourceRangesAndDiagnosticsForQueryMessage, + RequestSourceRangesForQueryMessage, SourceRangesAndDiagnosticsForQueryMessage, + SourceRangesForQueryMessage, CancelMessage, UpdatePchProjectPartsMessage, diff --git a/src/libs/clangbackendipc/clangrefactoringclientmessages.h b/src/libs/clangbackendipc/clangrefactoringclientmessages.h new file mode 100644 index 0000000000..7b90453540 --- /dev/null +++ b/src/libs/clangbackendipc/clangrefactoringclientmessages.h @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** 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 "sourcelocationsforrenamingmessage.h" +#include "sourcerangesanddiagnosticsforquerymessage.h" +#include "sourcerangesforquerymessage.h" +#include "cmbalivemessage.h" diff --git a/src/libs/clangbackendipc/clangrefactoringmessages.h b/src/libs/clangbackendipc/clangrefactoringmessages.h new file mode 100644 index 0000000000..7f6f0de69e --- /dev/null +++ b/src/libs/clangbackendipc/clangrefactoringmessages.h @@ -0,0 +1,29 @@ +/**************************************************************************** +** +** 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 "clangrefactoringclientmessages.h" +#include "clangrefactoringservermessages.h" diff --git a/src/libs/clangbackendipc/clangrefactoringservermessages.h b/src/libs/clangbackendipc/clangrefactoringservermessages.h new file mode 100644 index 0000000000..797b3d58ef --- /dev/null +++ b/src/libs/clangbackendipc/clangrefactoringservermessages.h @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** 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 "cancelmessage.h" +#include "cmbendmessage.h" +#include "requestsourcelocationforrenamingmessage.h" +#include "requestsourcerangesanddiagnosticsforquerymessage.h" +#include "requestsourcerangesforquerymessage.h" diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.h b/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.h index 63e59d9ee9..09149ea35d 100644 --- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.h +++ b/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontainer.h @@ -34,19 +34,19 @@ class DynamicASTMatcherDiagnosticContainer { public: DynamicASTMatcherDiagnosticContainer() = default; - DynamicASTMatcherDiagnosticContainer(std::vector<DynamicASTMatcherDiagnosticMessageContainer> &&messages, - std::vector<DynamicASTMatcherDiagnosticContextContainer> &&contexts) + DynamicASTMatcherDiagnosticContainer(DynamicASTMatcherDiagnosticMessageContainers &&messages, + DynamicASTMatcherDiagnosticContextContainers &&contexts) : m_messages(std::move(messages)), m_contexts(std::move(contexts)) { } - const std::vector<DynamicASTMatcherDiagnosticMessageContainer> &messages() const + const DynamicASTMatcherDiagnosticMessageContainers &messages() const { return m_messages; } - const std::vector<DynamicASTMatcherDiagnosticContextContainer> &contexts() const + const DynamicASTMatcherDiagnosticContextContainers &contexts() const { return m_contexts; } @@ -88,15 +88,16 @@ public: DynamicASTMatcherDiagnosticContainer clone() const { - return DynamicASTMatcherDiagnosticContainer(Utils::clone(m_messages), - Utils::clone(m_contexts)); + return *this; } private: - std::vector<DynamicASTMatcherDiagnosticMessageContainer> m_messages; - std::vector<DynamicASTMatcherDiagnosticContextContainer> m_contexts; + DynamicASTMatcherDiagnosticMessageContainers m_messages; + DynamicASTMatcherDiagnosticContextContainers m_contexts; }; +using DynamicASTMatcherDiagnosticContainers = std::vector<DynamicASTMatcherDiagnosticContainer>; + CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContainer &container); std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticContainer &container); diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.h b/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.h index 2ba2812efa..61d7e2fff5 100644 --- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.h +++ b/src/libs/clangbackendipc/dynamicastmatcherdiagnosticcontextcontainer.h @@ -105,6 +105,8 @@ private: Utils::SmallStringVector m_arguments; }; +using DynamicASTMatcherDiagnosticContextContainers = std::vector<DynamicASTMatcherDiagnosticContextContainer>; + CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContextContainer &container); std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticContextContainer &container); diff --git a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.h b/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.h index 868346a5e0..8f9581872d 100644 --- a/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.h +++ b/src/libs/clangbackendipc/dynamicastmatcherdiagnosticmessagecontainer.h @@ -105,6 +105,8 @@ private: Utils::SmallStringVector m_arguments; }; +using DynamicASTMatcherDiagnosticMessageContainers = std::vector<DynamicASTMatcherDiagnosticMessageContainer>; + CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticMessageContainer &container); std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticMessageContainer &container); diff --git a/src/libs/clangbackendipc/filepath.h b/src/libs/clangbackendipc/filepath.h index 717d020790..a29ecf941f 100644 --- a/src/libs/clangbackendipc/filepath.h +++ b/src/libs/clangbackendipc/filepath.h @@ -86,13 +86,19 @@ public: friend QDataStream &operator<<(QDataStream &out, const FilePath &filePath) { out << filePath.m_path; + out << uint(filePath.m_slashIndex); return out; } friend QDataStream &operator>>(QDataStream &in, FilePath &filePath) { + uint slashIndex; + in >> filePath.m_path; + in >> slashIndex; + + filePath.m_slashIndex = slashIndex; return in; } @@ -116,7 +122,7 @@ public: FilePath clone() const { - return FilePath(m_path.clone(), m_slashIndex); + return *this; } private: diff --git a/src/libs/clangbackendipc/refactoringclientinterface.cpp b/src/libs/clangbackendipc/refactoringclientinterface.cpp index d261ae6715..fc69cd0cd5 100644 --- a/src/libs/clangbackendipc/refactoringclientinterface.cpp +++ b/src/libs/clangbackendipc/refactoringclientinterface.cpp @@ -26,8 +26,7 @@ #include "refactoringclientinterface.h" #include "messageenvelop.h" -#include "sourcelocationsforrenamingmessage.h" -#include "sourcerangesanddiagnosticsforquerymessage.h" +#include "clangrefactoringclientmessages.h" #include <QDebug> @@ -45,6 +44,9 @@ void RefactoringClientInterface::dispatch(const MessageEnvelop &messageEnvelop) case MessageType::SourceRangesAndDiagnosticsForQueryMessage: sourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<SourceRangesAndDiagnosticsForQueryMessage>()); break; + case MessageType::SourceRangesForQueryMessage: + sourceRangesForQueryMessage(messageEnvelop.message<SourceRangesForQueryMessage>()); + break; default: qWarning() << "Unknown IpcClientMessage"; } diff --git a/src/libs/clangbackendipc/refactoringclientinterface.h b/src/libs/clangbackendipc/refactoringclientinterface.h index 4cb6885806..8f10986929 100644 --- a/src/libs/clangbackendipc/refactoringclientinterface.h +++ b/src/libs/clangbackendipc/refactoringclientinterface.h @@ -33,6 +33,7 @@ namespace ClangBackEnd { class SourceLocationsForRenamingMessage; class SourceRangesAndDiagnosticsForQueryMessage; +class SourceRangesForQueryMessage; class SourceLocationsContainer; class CMBIPC_EXPORT RefactoringClientInterface : public IpcClientInterface @@ -47,6 +48,7 @@ public: virtual void alive() = 0; virtual void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) = 0; virtual void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) = 0; + virtual void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) = 0; virtual void setLocalRenamingCallback(RenameCallback &&localRenamingCallback) = 0; }; diff --git a/src/libs/clangbackendipc/refactoringclientproxy.cpp b/src/libs/clangbackendipc/refactoringclientproxy.cpp index d03edc37db..576489aa25 100644 --- a/src/libs/clangbackendipc/refactoringclientproxy.cpp +++ b/src/libs/clangbackendipc/refactoringclientproxy.cpp @@ -28,8 +28,7 @@ #include "cmbalivemessage.h" #include "messageenvelop.h" #include "refactoringserverinterface.h" -#include "sourcelocationsforrenamingmessage.h" -#include "sourcerangesanddiagnosticsforquerymessage.h" +#include "clangrefactoringclientmessages.h" #include <QDebug> #include <QIODevice> @@ -85,4 +84,9 @@ void RefactoringClientProxy::sourceRangesAndDiagnosticsForQueryMessage(SourceRan writeMessageBlock.write(message); } +void RefactoringClientProxy::sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) +{ + writeMessageBlock.write(message); +} + } // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/refactoringclientproxy.h b/src/libs/clangbackendipc/refactoringclientproxy.h index 0533dfe28d..2f7c3af980 100644 --- a/src/libs/clangbackendipc/refactoringclientproxy.h +++ b/src/libs/clangbackendipc/refactoringclientproxy.h @@ -51,6 +51,7 @@ public: void alive() override; void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) override; void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) override; + void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) override; void setLocalRenamingCallback(RenameCallback &&) final {} diff --git a/src/libs/clangbackendipc/refactoringserverinterface.cpp b/src/libs/clangbackendipc/refactoringserverinterface.cpp index 9e45779140..d6b0f6815b 100644 --- a/src/libs/clangbackendipc/refactoringserverinterface.cpp +++ b/src/libs/clangbackendipc/refactoringserverinterface.cpp @@ -26,9 +26,7 @@ #include "refactoringserverinterface.h" #include "messageenvelop.h" -#include "requestsourcelocationforrenamingmessage.h" -#include "requestsourcerangesanddiagnosticsforquerymessage.h" -#include "cancelmessage.h" +#include "clangrefactoringservermessages.h" #include <QDebug> @@ -46,6 +44,9 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop) case MessageType::RequestSourceRangesAndDiagnosticsForQueryMessage: requestSourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<RequestSourceRangesAndDiagnosticsForQueryMessage>()); break; + case MessageType::RequestSourceRangesForQueryMessage: + requestSourceRangesForQueryMessage(messageEnvelop.message<RequestSourceRangesForQueryMessage>()); + break; case MessageType::CancelMessage: cancel(); break; diff --git a/src/libs/clangbackendipc/refactoringserverinterface.h b/src/libs/clangbackendipc/refactoringserverinterface.h index a22f4c1f1f..c4a8ec6195 100644 --- a/src/libs/clangbackendipc/refactoringserverinterface.h +++ b/src/libs/clangbackendipc/refactoringserverinterface.h @@ -34,6 +34,7 @@ namespace ClangBackEnd { class RefactoringClientInterface; class RequestSourceLocationsForRenamingMessage; class RequestSourceRangesAndDiagnosticsForQueryMessage; +class RequestSourceRangesForQueryMessage; class CancelMessage; class CMBIPC_EXPORT RefactoringServerInterface : public IpcServerInterface<RefactoringClientInterface> @@ -44,6 +45,7 @@ public: virtual void end() = 0; virtual void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) = 0; virtual void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) = 0; + virtual void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) = 0; virtual void cancel() = 0; bool isUsable() const diff --git a/src/libs/clangbackendipc/refactoringserverproxy.cpp b/src/libs/clangbackendipc/refactoringserverproxy.cpp index 77f7e7e6fa..0cf4473f07 100644 --- a/src/libs/clangbackendipc/refactoringserverproxy.cpp +++ b/src/libs/clangbackendipc/refactoringserverproxy.cpp @@ -25,12 +25,9 @@ #include "refactoringserverproxy.h" -#include "cancelmessage.h" -#include "cmbendmessage.h" #include "messageenvelop.h" #include "refactoringclientinterface.h" -#include "requestsourcelocationforrenamingmessage.h" -#include "requestsourcerangesanddiagnosticsforquerymessage.h" +#include "clangrefactoringservermessages.h" #include <QIODevice> #include <QVector> @@ -60,6 +57,11 @@ void RefactoringServerProxy::requestSourceRangesAndDiagnosticsForQueryMessage(Re writeMessageBlock.write(message); } +void RefactoringServerProxy::requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) +{ + writeMessageBlock.write(message); +} + void RefactoringServerProxy::cancel() { writeMessageBlock.write(CancelMessage()); diff --git a/src/libs/clangbackendipc/refactoringserverproxy.h b/src/libs/clangbackendipc/refactoringserverproxy.h index 44eb2065b2..73d165a9a0 100644 --- a/src/libs/clangbackendipc/refactoringserverproxy.h +++ b/src/libs/clangbackendipc/refactoringserverproxy.h @@ -52,6 +52,7 @@ public: void end() override; void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override; void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override; + void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override; void cancel() override; void readMessages(); diff --git a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.cpp b/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.cpp index 5bbc906504..878f11f0de 100644 --- a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.cpp +++ b/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.cpp @@ -31,7 +31,7 @@ QDebug operator<<(QDebug debug, const RequestSourceRangesAndDiagnosticsForQueryM { debug.nospace() << "RequestSourceRangesAndDiagnosticsForQuery(" << message.query() << ", " - << message.sources() << ")"; + << message.source() << ")"; return debug; } @@ -40,7 +40,7 @@ std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosti { os << "(" << message.query() << ", " - << message.sources() + << message.source() << ")"; return os; diff --git a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h b/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h index bbc97aa8d1..afac9e9b6b 100644 --- a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h +++ b/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h @@ -34,32 +34,20 @@ class RequestSourceRangesAndDiagnosticsForQueryMessage public: RequestSourceRangesAndDiagnosticsForQueryMessage() = default; RequestSourceRangesAndDiagnosticsForQueryMessage(Utils::SmallString &&query, - std::vector<V2::FileContainer> &&sources, - std::vector<V2::FileContainer> &&unsavedContent) + V2::FileContainer &&source) : m_query(std::move(query)), - m_sources(std::move(sources)), - m_unsavedContent(std::move(unsavedContent)) + m_source(std::move(source)) {} - const std::vector<V2::FileContainer> &sources() const + const V2::FileContainer &source() const { - return m_sources; + return m_source; } - std::vector<V2::FileContainer> takeSources() + V2::FileContainer takeSource() { - return std::move(m_sources); - } - - const std::vector<V2::FileContainer> &unsavedContent() const - { - return m_unsavedContent; - } - - std::vector<V2::FileContainer> takeUnsavedContent() - { - return std::move(m_unsavedContent); + return std::move(m_source); } const Utils::SmallString &query() const @@ -75,8 +63,7 @@ public: friend QDataStream &operator<<(QDataStream &out, const RequestSourceRangesAndDiagnosticsForQueryMessage &message) { out << message.m_query; - out << message.m_sources; - out << message.m_unsavedContent; + out << message.m_source; return out; } @@ -84,8 +71,7 @@ public: friend QDataStream &operator>>(QDataStream &in, RequestSourceRangesAndDiagnosticsForQueryMessage &message) { in >> message.m_query; - in >> message.m_sources; - in >> message.m_unsavedContent; + in >> message.m_source; return in; } @@ -94,26 +80,21 @@ public: const RequestSourceRangesAndDiagnosticsForQueryMessage &second) { return first.m_query == second.m_query - && first.m_sources == second.m_sources - && first.m_unsavedContent == second.m_unsavedContent; + && first.m_source == second.m_source; } RequestSourceRangesAndDiagnosticsForQueryMessage clone() const { - return RequestSourceRangesAndDiagnosticsForQueryMessage(m_query.clone(), - Utils::clone(m_sources), - Utils::clone(m_unsavedContent)); + return *this; } private: Utils::SmallString m_query; - std::vector<V2::FileContainer> m_sources; - std::vector<V2::FileContainer> m_unsavedContent; + V2::FileContainer m_source; }; CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestSourceRangesAndDiagnosticsForQueryMessage &message); std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosticsForQueryMessage &message); DECLARE_MESSAGE(RequestSourceRangesAndDiagnosticsForQueryMessage) - } // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/requestsourcerangesforquerymessage.cpp b/src/libs/clangbackendipc/requestsourcerangesforquerymessage.cpp new file mode 100644 index 0000000000..ab5b8d8468 --- /dev/null +++ b/src/libs/clangbackendipc/requestsourcerangesforquerymessage.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "requestsourcerangesforquerymessage.h" + +namespace ClangBackEnd { + +QDebug operator<<(QDebug debug, const RequestSourceRangesForQueryMessage &message) +{ + debug.nospace() << "RequestSourceRangesForQueryMessage(" + << message.query() << ")"; + + return debug; +} + +std::ostream &operator<<(std::ostream &os, const RequestSourceRangesForQueryMessage &message) +{ + os << "(" + << message.query() + << ")"; + + return os; +} + +} // namespace ClangBackEnd + diff --git a/src/libs/clangbackendipc/requestsourcerangesforquerymessage.h b/src/libs/clangbackendipc/requestsourcerangesforquerymessage.h new file mode 100644 index 0000000000..1dc3ca6ac5 --- /dev/null +++ b/src/libs/clangbackendipc/requestsourcerangesforquerymessage.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** 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 "filecontainerv2.h" + +namespace ClangBackEnd { + +class RequestSourceRangesForQueryMessage +{ +public: + RequestSourceRangesForQueryMessage() = default; + RequestSourceRangesForQueryMessage(Utils::SmallString &&query, + std::vector<V2::FileContainer> &&sources, + std::vector<V2::FileContainer> &&unsavedContent) + : m_query(std::move(query)), + m_sources(std::move(sources)), + m_unsavedContent(std::move(unsavedContent)) + + {} + + const std::vector<V2::FileContainer> &sources() const + { + return m_sources; + } + + std::vector<V2::FileContainer> takeSources() + { + return std::move(m_sources); + } + + const std::vector<V2::FileContainer> &unsavedContent() const + { + return m_unsavedContent; + } + + std::vector<V2::FileContainer> takeUnsavedContent() + { + return std::move(m_unsavedContent); + } + + const Utils::SmallString &query() const + { + return m_query; + } + + Utils::SmallString takeQuery() + { + return std::move(m_query); + } + + friend QDataStream &operator<<(QDataStream &out, const RequestSourceRangesForQueryMessage &message) + { + out << message.m_query; + out << message.m_sources; + out << message.m_unsavedContent; + + return out; + } + + friend QDataStream &operator>>(QDataStream &in, RequestSourceRangesForQueryMessage &message) + { + in >> message.m_query; + in >> message.m_sources; + in >> message.m_unsavedContent; + + return in; + } + + friend bool operator==(const RequestSourceRangesForQueryMessage &first, + const RequestSourceRangesForQueryMessage &second) + { + return first.m_query == second.m_query + && first.m_sources == second.m_sources + && first.m_unsavedContent == second.m_unsavedContent; + } + + RequestSourceRangesForQueryMessage clone() const + { + return *this; + } + +private: + Utils::SmallString m_query; + std::vector<V2::FileContainer> m_sources; + std::vector<V2::FileContainer> m_unsavedContent; +}; + + +CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestSourceRangesForQueryMessage &message); +std::ostream &operator<<(std::ostream &os, const RequestSourceRangesForQueryMessage &message); + +DECLARE_MESSAGE(RequestSourceRangesForQueryMessage) +} // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/sourcelocationcontainerv2.h b/src/libs/clangbackendipc/sourcelocationcontainerv2.h index 6f508ae4a3..db54c7c028 100644 --- a/src/libs/clangbackendipc/sourcelocationcontainerv2.h +++ b/src/libs/clangbackendipc/sourcelocationcontainerv2.h @@ -97,8 +97,14 @@ public: { return first.m_line != second.m_line || first.m_column != second.m_column - || first.m_fileHash != second.m_fileHash - || first.m_offset != second.m_offset; + || first.m_fileHash != second.m_fileHash; + } + + friend bool operator<(const SourceLocationContainer &first, + const SourceLocationContainer &second) + { + return std::tie(first.m_fileHash, first.m_line, first.m_column) + < std::tie(second.m_fileHash, second.m_line, second.m_column); } SourceLocationContainer clone() const diff --git a/src/libs/clangbackendipc/sourcerangecontainerv2.h b/src/libs/clangbackendipc/sourcerangecontainerv2.h index 7ffac75a02..a5dba3ddf1 100644 --- a/src/libs/clangbackendipc/sourcerangecontainerv2.h +++ b/src/libs/clangbackendipc/sourcerangecontainerv2.h @@ -27,6 +27,8 @@ #include "sourcelocationcontainerv2.h" +#include <tuple> + namespace ClangBackEnd { namespace V2 { @@ -89,6 +91,12 @@ public: return first.m_start == second.m_start && first.m_end == second.m_end; } + friend bool operator<(const SourceRangeContainer &first, + const SourceRangeContainer &second) + { + return std::tie(first.m_start, first.m_end) < std::tie(second.m_start, second.m_end); + } + SourceRangeContainer clone() const { return SourceRangeContainer(m_start.clone(), m_end.clone()); @@ -99,6 +107,8 @@ private: SourceLocationContainer m_end; }; +using SourceRangeContainers = std::vector<SourceRangeContainer>; + CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangeContainer &container); std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container); } // namespace V2 diff --git a/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.h b/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.h index 6634d50195..f91db432f6 100644 --- a/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.h +++ b/src/libs/clangbackendipc/sourcerangesanddiagnosticsforquerymessage.h @@ -38,56 +38,61 @@ public: SourceRangesAndDiagnosticsForQueryMessage() = default; SourceRangesAndDiagnosticsForQueryMessage(SourceRangesContainer &&sourceRangesContainer, std::vector<DynamicASTMatcherDiagnosticContainer> &&diagnosticContainers) - : sourceRangesContainer(std::move(sourceRangesContainer)), - diagnosticContainers(std::move(diagnosticContainers)) + : m_sourceRangesContainer(std::move(sourceRangesContainer)), + m_diagnosticContainers(std::move(diagnosticContainers)) {} const SourceRangesContainer &sourceRanges() const { - return sourceRangesContainer; + return m_sourceRangesContainer; } SourceRangesContainer &sourceRanges() { - return sourceRangesContainer; + return m_sourceRangesContainer; } - const std::vector<DynamicASTMatcherDiagnosticContainer> &diagnostics() const + SourceRangesContainer takeSourceRanges() { - return diagnosticContainers; + return std::move(m_sourceRangesContainer); + } + + const DynamicASTMatcherDiagnosticContainers &diagnostics() const + { + return m_diagnosticContainers; } friend QDataStream &operator<<(QDataStream &out, const SourceRangesAndDiagnosticsForQueryMessage &message) { - out << message.sourceRangesContainer; - out << message.diagnosticContainers; + out << message.m_sourceRangesContainer; + out << message.m_diagnosticContainers; return out; } friend QDataStream &operator>>(QDataStream &in, SourceRangesAndDiagnosticsForQueryMessage &message) { - in >> message.sourceRangesContainer; - in >> message.diagnosticContainers; + in >> message.m_sourceRangesContainer; + in >> message.m_diagnosticContainers; return in; } friend bool operator==(const SourceRangesAndDiagnosticsForQueryMessage &first, const SourceRangesAndDiagnosticsForQueryMessage &second) { - return first.sourceRangesContainer == second.sourceRangesContainer - && first.diagnosticContainers == second.diagnosticContainers; + return first.m_sourceRangesContainer == second.m_sourceRangesContainer + && first.m_diagnosticContainers == second.m_diagnosticContainers; } SourceRangesAndDiagnosticsForQueryMessage clone() const { - return SourceRangesAndDiagnosticsForQueryMessage(sourceRangesContainer.clone(), - Utils::clone(diagnosticContainers)); + return SourceRangesAndDiagnosticsForQueryMessage(m_sourceRangesContainer.clone(), + Utils::clone(m_diagnosticContainers)); } private: - SourceRangesContainer sourceRangesContainer; - std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers; + SourceRangesContainer m_sourceRangesContainer; + DynamicASTMatcherDiagnosticContainers m_diagnosticContainers; }; CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangesAndDiagnosticsForQueryMessage &message); diff --git a/src/libs/clangbackendipc/sourcerangescontainer.h b/src/libs/clangbackendipc/sourcerangescontainer.h index 147b7cb53a..6968830a6d 100644 --- a/src/libs/clangbackendipc/sourcerangescontainer.h +++ b/src/libs/clangbackendipc/sourcerangescontainer.h @@ -37,7 +37,7 @@ class SourceRangesContainer : public SourceFilePathContainerBase public: SourceRangesContainer() = default; SourceRangesContainer(std::unordered_map<uint, FilePath> &&filePathHash, - std::vector<SourceRangeWithTextContainer> &&sourceRangeWithTextContainers) + SourceRangeWithTextContainers &&sourceRangeWithTextContainers) : SourceFilePathContainerBase(std::move(filePathHash)), m_sourceRangeWithTextContainers(std::move(sourceRangeWithTextContainers)) {} @@ -49,19 +49,19 @@ public: return found->second; } - const std::vector<SourceRangeWithTextContainer> &sourceRangeWithTextContainers() const + const SourceRangeWithTextContainers &sourceRangeWithTextContainers() const { return m_sourceRangeWithTextContainers; } - std::vector<SourceRangeWithTextContainer> &sourceRangeWithTextContainers() + SourceRangeWithTextContainers takeSourceRangeWithTextContainers() { - return m_sourceRangeWithTextContainers; + return std::move(m_sourceRangeWithTextContainers); } - std::vector<SourceRangeWithTextContainer> takeSourceRangeWithTextContainers() + void setSourceRangeWithTextContainers(SourceRangeWithTextContainers &&sourceRanges) { - return std::move(m_sourceRangeWithTextContainers); + m_sourceRangeWithTextContainers = std::move(sourceRanges); } bool hasContent() const @@ -117,10 +117,10 @@ public: SourceRangesContainer clone() const { - return SourceRangesContainer(Utils::clone(m_filePathHash), Utils::clone(m_sourceRangeWithTextContainers)); + return *this; } - std::vector<SourceRangeWithTextContainer> m_sourceRangeWithTextContainers; + SourceRangeWithTextContainers m_sourceRangeWithTextContainers; }; diff --git a/src/libs/clangbackendipc/sourcerangesforquerymessage.cpp b/src/libs/clangbackendipc/sourcerangesforquerymessage.cpp new file mode 100644 index 0000000000..e9227b3a66 --- /dev/null +++ b/src/libs/clangbackendipc/sourcerangesforquerymessage.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "sourcerangesforquerymessage.h" + +namespace ClangBackEnd { + +QDebug operator<<(QDebug debug, const SourceRangesForQueryMessage &message) +{ + debug.nospace() << "SourceRangesForQueryMessage(" + << message.sourceRanges() << ")"; + + return debug; +} + +std::ostream &operator<<(std::ostream &os, const SourceRangesForQueryMessage &message) +{ + os << "(" + << message.sourceRanges() + << ")"; + + return os; +} +} // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/sourcerangesforquerymessage.h b/src/libs/clangbackendipc/sourcerangesforquerymessage.h new file mode 100644 index 0000000000..7aa410e1ae --- /dev/null +++ b/src/libs/clangbackendipc/sourcerangesforquerymessage.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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 "sourcerangescontainer.h" +#include "dynamicastmatcherdiagnosticcontainer.h" + +#include <utils/smallstring.h> + +namespace ClangBackEnd { + +class SourceRangesForQueryMessage +{ +public: + SourceRangesForQueryMessage() = default; + SourceRangesForQueryMessage(SourceRangesContainer &&m_sourceRangesContainer) + : m_sourceRangesContainer(std::move(m_sourceRangesContainer)) + {} + + const SourceRangesContainer &sourceRanges() const + { + return m_sourceRangesContainer; + } + + SourceRangesContainer &sourceRanges() + { + return m_sourceRangesContainer; + } + + friend QDataStream &operator<<(QDataStream &out, const SourceRangesForQueryMessage &message) + { + out << message.m_sourceRangesContainer; + + return out; + } + + friend QDataStream &operator>>(QDataStream &in, SourceRangesForQueryMessage &message) + { + in >> message.m_sourceRangesContainer; + + return in; + } + + friend bool operator==(const SourceRangesForQueryMessage &first, const SourceRangesForQueryMessage &second) + { + return first.m_sourceRangesContainer == second.m_sourceRangesContainer; + } + + SourceRangesForQueryMessage clone() const + { + return *this; + } + +private: + SourceRangesContainer m_sourceRangesContainer; +}; + +CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangesForQueryMessage &message); +std::ostream &operator<<(std::ostream &os, const SourceRangesForQueryMessage &message); + +DECLARE_MESSAGE(SourceRangesForQueryMessage) +} // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/sourcerangewithtextcontainer.h b/src/libs/clangbackendipc/sourcerangewithtextcontainer.h index 8a92086319..4edb231550 100644 --- a/src/libs/clangbackendipc/sourcerangewithtextcontainer.h +++ b/src/libs/clangbackendipc/sourcerangewithtextcontainer.h @@ -31,7 +31,7 @@ namespace ClangBackEnd { -class SourceRangeWithTextContainer : V2::SourceRangeContainer +class SourceRangeWithTextContainer : public V2::SourceRangeContainer { public: SourceRangeWithTextContainer() = default; @@ -103,7 +103,7 @@ public: SourceRangeWithTextContainer clone() const { - return SourceRangeWithTextContainer(base().clone(), m_text.clone()); + return *this; } private: @@ -116,19 +116,3 @@ CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangeWithTextContainer std::ostream &operator<<(std::ostream &os, const SourceRangeWithTextContainer &container); } // namespace ClangBackEnd -namespace std -{ -template<> struct hash<ClangBackEnd::SourceRangeWithTextContainer> -{ - using argument_type = ClangBackEnd::SourceRangeWithTextContainer; - using result_type = std::size_t; - result_type operator()(const argument_type &container) const - { - const result_type h1{std::hash<uint>{}(container.fileHash())}; - const result_type h2{std::hash<uint>{}(container.start().offset())}; - const result_type h3{std::hash<uint>{}(container.end().offset())}; - - return h1 ^ (h2 << 8) ^ (h3 << 16); - } -}; -} diff --git a/src/plugins/clangrefactoring/baseclangquerytexteditorwidget.cpp b/src/plugins/clangrefactoring/baseclangquerytexteditorwidget.cpp new file mode 100644 index 0000000000..05cb74f599 --- /dev/null +++ b/src/plugins/clangrefactoring/baseclangquerytexteditorwidget.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "baseclangquerytexteditorwidget.h" + +#include <texteditor/texteditorconstants.h> + +namespace ClangRefactoring { + +BaseClangQueryTextEditorWidget::BaseClangQueryTextEditorWidget(QWidget *parent) + : TextEditor::TextEditorWidget(parent) +{ + setupFallBackEditor(Core::Id()); + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + setHighlightCurrentLine(false); + setLineNumbersVisible(false); + setParenthesesMatchingEnabled(true); +} + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/baseclangquerytexteditorwidget.h b/src/plugins/clangrefactoring/baseclangquerytexteditorwidget.h new file mode 100644 index 0000000000..b7f54a5325 --- /dev/null +++ b/src/plugins/clangrefactoring/baseclangquerytexteditorwidget.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** 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 <texteditor/texteditor.h> + +namespace ClangRefactoring { + +class BaseClangQueryTextEditorWidget : public TextEditor::TextEditorWidget +{ + Q_OBJECT + +public: + BaseClangQueryTextEditorWidget(QWidget *parent); +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryexamplehighlighter.cpp b/src/plugins/clangrefactoring/clangqueryexamplehighlighter.cpp new file mode 100644 index 0000000000..d1ff575c02 --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryexamplehighlighter.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "clangqueryexamplehighlighter.h" + +#include <sourcerangescontainer.h> + +#include <QTextBlock> + + +namespace ClangRefactoring { + +ClangQueryExampleHighlighter::ClangQueryExampleHighlighter() + : m_marker(*this) +{ + std::array<QTextCharFormat, 5> textFormats; + textFormats[0].setBackground(QColor("#c9ffc3")); + textFormats[1].setBackground(QColor("#c3d9ff")); + textFormats[2].setBackground(QColor("#e5c3ff")); + textFormats[3].setBackground(QColor("#ffc3cb")); + textFormats[4].setBackground(QColor("#ffe8c3")); + + m_marker.setTextFormats(std::move(textFormats)); + + setNoAutomaticHighlighting(true); +} + +void ClangQueryExampleHighlighter::setSourceRanges(ClangBackEnd::SourceRangesContainer &&container) +{ + m_marker.setSourceRanges(container.takeSourceRangeWithTextContainers()); + rehighlight(); +} + +void ClangQueryExampleHighlighter::highlightBlock(const QString &text) +{ + int currentLineNumber = currentBlock().blockNumber() + 1; + m_marker.highlightBlock(uint(currentLineNumber), text); +} + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryexamplehighlighter.h b/src/plugins/clangrefactoring/clangqueryexamplehighlighter.h new file mode 100644 index 0000000000..6c943644dc --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryexamplehighlighter.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** 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 "clangqueryexamplehighlightmarker.h" + +#include <texteditor/syntaxhighlighter.h> + +#include <sourcerangewithtextcontainer.h> + +namespace ClangBackEnd { +class SourceRangesContainer; +} + +namespace ClangRefactoring { + +class ClangQueryExampleHighlighter : public TextEditor::SyntaxHighlighter +{ + friend ClangQueryExampleHighlightMarker<ClangQueryExampleHighlighter>; + +public: + ClangQueryExampleHighlighter(); + + void setSourceRanges(ClangBackEnd::SourceRangesContainer &&container); + +protected: + void highlightBlock(const QString &text) override; + +private: + ClangQueryExampleHighlightMarker<ClangQueryExampleHighlighter> m_marker; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryexamplehighlightmarker.h b/src/plugins/clangrefactoring/clangqueryexamplehighlightmarker.h new file mode 100644 index 0000000000..07b7205a53 --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryexamplehighlightmarker.h @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** 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 <sourcerangewithtextcontainer.h> + +#include <QString> +#include <QTextCharFormat> + +namespace ClangRefactoring { + +template<typename SyntaxHighlighter> +class ClangQueryExampleHighlightMarker +{ + using SourceRange = ClangBackEnd::V2::SourceRangeContainer; + using SourceRanges = ClangBackEnd::V2::SourceRangeContainers; + using SourceRangeWithTexts = ClangBackEnd::SourceRangeWithTextContainers; +public: + ClangQueryExampleHighlightMarker(SourceRangeWithTexts &&sourceRanges, + SyntaxHighlighter &highlighter, + const std::array<QTextCharFormat, 5> &textFormats) + : m_sourceRanges(std::move(sourceRanges)), + m_currentSourceRangeIterator(m_sourceRanges.begin()), + m_highlighter(highlighter), + m_textFormats(textFormats) + { + } + + ClangQueryExampleHighlightMarker(SyntaxHighlighter &highlighter) + : m_currentSourceRangeIterator(m_sourceRanges.begin()), + m_highlighter(highlighter) + { + } + + void setTextFormats(std::array<QTextCharFormat, 5> &&textFormats) + { + m_textFormats = std::move(textFormats); + } + + void setSourceRanges(SourceRangeWithTexts &&sourceRanges) + { + m_currentlyUsedSourceRanges.clear(); + m_sourceRanges = std::move(sourceRanges); + m_currentSourceRangeIterator = m_sourceRanges.begin(); + } + + void highlightSourceRanges(uint currentLineNumber, const QString ¤tText) + { + while (hasSourceRangesForCurrentLine(currentLineNumber)) { + SourceRange &sourceRange = *m_currentSourceRangeIterator; + + popSourceRangeIfMultiLineEndsHere(currentLineNumber, sourceRange.start().column()); + + formatSourceRange(sourceRange, + currentLineNumber, + currentText.size(), + int(m_currentlyUsedSourceRanges.size())); + + pushSourceRangeIfMultiLine(sourceRange); + ++m_currentSourceRangeIterator; + } + } + + void highlightCurrentlyUsedSourceRanges(uint currentLineNumber, const QString ¤tText) + { + formatCurrentlyUsedSourceRanges(currentLineNumber, currentText.size()); + popSourceRangeIfMultiLineEndsHereAndAllSourceRangesAreConsumed(currentLineNumber); + } + + void highlightBlock(uint currentLineNumber, const QString ¤tText) + { + popSourceRangeIfMultiLineEndedBefore(currentLineNumber); + highlightCurrentlyUsedSourceRanges(currentLineNumber, currentText); + highlightSourceRanges(currentLineNumber, currentText); + } + + bool hasSourceRangesForCurrentLine(uint currentLineNumber) const + { + return m_currentSourceRangeIterator != m_sourceRanges.end() + && m_currentSourceRangeIterator->start().line() == currentLineNumber; + } + + bool hasOnlySCurrentlyUsedSourceRanges() const + { + return m_currentSourceRangeIterator == m_sourceRanges.end() + && !m_currentlyUsedSourceRanges.empty(); + } + + void formatSingleSourceRange(const SourceRange &sourceRange, + int textFormatIndex) + { + int size = int(sourceRange.end().column() - sourceRange.start().column()); + m_highlighter.setFormat(int(sourceRange.start().column()) - 1, + size, + m_textFormats[textFormatIndex]); + } + + void formatStartMultipleSourceRange(const SourceRange &sourceRange, + int textSize, + int textFormatIndex) + { + int size = textSize - int(sourceRange.start().column()) + 1; + m_highlighter.setFormat(int(sourceRange.start().column()) - 1, + size, + m_textFormats[textFormatIndex]); + } + + void formatEndMultipleSourceRange(const SourceRange &sourceRange, + int textFormatIndex) + { + int size = int(sourceRange.end().column()) - 1; + m_highlighter.setFormat(0, size, m_textFormats[textFormatIndex]); + } + + void formatMiddleMultipleSourceRange(int textSize, + int textFormatIndex) + { + m_highlighter.setFormat(0, textSize, m_textFormats[textFormatIndex]); + } + + void formatSourceRange(const SourceRange &sourceRange, + uint currentLineNumber, + int textSize, + int textFormatIndex) + { + if (sourceRange.start().line() == sourceRange.end().line()) + formatSingleSourceRange(sourceRange, textFormatIndex); + else if (sourceRange.start().line() == currentLineNumber) + formatStartMultipleSourceRange(sourceRange, textSize, textFormatIndex); + else if (sourceRange.end().line() == currentLineNumber) + formatEndMultipleSourceRange(sourceRange, textFormatIndex); + else + formatMiddleMultipleSourceRange(textSize, textFormatIndex); + } + + void formatCurrentlyUsedSourceRanges(uint currentLineNumber, int textSize) + { + int textFormatIndex = 0; + + for (const SourceRange &sourceRange : m_currentlyUsedSourceRanges) { + formatSourceRange(sourceRange, currentLineNumber, textSize, textFormatIndex); + ++textFormatIndex; + } + } + + bool currentlyUsedHasEndLineAndColumnNumber(uint currentLineNumber, uint currentColumnNumber) + { + return !m_currentlyUsedSourceRanges.empty() + && m_currentlyUsedSourceRanges.back().end().line() <= currentLineNumber + && m_currentlyUsedSourceRanges.back().end().column() <= currentColumnNumber; + } + + void popSourceRangeIfMultiLineEndsHere(uint currentLineNumber, uint currentColumnNumber) + { + while (currentlyUsedHasEndLineAndColumnNumber(currentLineNumber, currentColumnNumber)) + m_currentlyUsedSourceRanges.pop_back(); + } + + bool currentlyUsedHasEndLineNumberAndSourceRangesAreConsumed(uint currentLineNumber) + { + return !m_currentlyUsedSourceRanges.empty() + && m_currentSourceRangeIterator == m_sourceRanges.end() + && m_currentlyUsedSourceRanges.back().end().line() == currentLineNumber; + } + + void popSourceRangeIfMultiLineEndsHereAndAllSourceRangesAreConsumed(uint currentLineNumber) + { + while (currentlyUsedHasEndLineNumberAndSourceRangesAreConsumed(currentLineNumber)) + m_currentlyUsedSourceRanges.pop_back(); + } + + bool currentlyUsedHasEndedBeforeLineNumber(uint currentLineNumber) + { + return !m_currentlyUsedSourceRanges.empty() + && m_currentlyUsedSourceRanges.back().end().line() < currentLineNumber; + } + + void popSourceRangeIfMultiLineEndedBefore(uint currentLineNumber) + { + while (currentlyUsedHasEndedBeforeLineNumber(currentLineNumber)) + m_currentlyUsedSourceRanges.pop_back(); + } + + void pushSourceRangeIfMultiLine(SourceRange &sourceRange) + { + m_currentlyUsedSourceRanges.push_back(sourceRange); + } + +private: + SourceRangeWithTexts m_sourceRanges; + SourceRangeWithTexts::iterator m_currentSourceRangeIterator; + SourceRanges m_currentlyUsedSourceRanges; + SyntaxHighlighter &m_highlighter; + std::array<QTextCharFormat, 5> m_textFormats; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp b/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp new file mode 100644 index 0000000000..19273d5ede --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "clangqueryexampletexteditorwidget.h" + +#include "clangqueryexamplehighlighter.h" + +#include <texteditor/textdocument.h> + +namespace ClangRefactoring { + +ClangQueryExampleTextEditorWidget::ClangQueryExampleTextEditorWidget(QWidget *parent) + : BaseClangQueryTextEditorWidget(parent) +{ + m_syntaxHighlighter = new ClangQueryExampleHighlighter; + textDocument()->setSyntaxHighlighter(m_syntaxHighlighter); +} + +ClangQueryExampleHighlighter *ClangQueryExampleTextEditorWidget::syntaxHighlighter() const +{ + return m_syntaxHighlighter; +} + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.h b/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.h new file mode 100644 index 0000000000..0a86f50220 --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** 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 "baseclangquerytexteditorwidget.h" + +namespace ClangRefactoring { + +class ClangQueryExampleHighlighter; + +class ClangQueryExampleTextEditorWidget : public BaseClangQueryTextEditorWidget +{ + Q_OBJECT + +public: + ClangQueryExampleTextEditorWidget(QWidget *parent); + + ClangQueryExampleHighlighter *syntaxHighlighter() const; + +private: + ClangQueryExampleHighlighter *m_syntaxHighlighter; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryhighlighter.cpp b/src/plugins/clangrefactoring/clangqueryhighlighter.cpp new file mode 100644 index 0000000000..5f9e72d4be --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryhighlighter.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "clangqueryhighlighter.h" + +#include <texteditor/fontsettings.h> +#include <texteditor/texteditorconstants.h> +#include <texteditor/texteditorsettings.h> + +#include <QTextBlock> + +namespace ClangRefactoring { + +ClangQueryHighlighter::ClangQueryHighlighter() + : m_marker(*this) +{ +#ifndef UNIT_TESTS + TextEditor::FontSettings fontSettings = TextEditor::TextEditorSettings::fontSettings(); + + m_marker.setTextFormats(fontSettings.toTextCharFormat(TextEditor::C_ERROR), + fontSettings.toTextCharFormat(TextEditor::C_ERROR_CONTEXT)); +#endif + + setNoAutomaticHighlighting(true); +} + +void ClangQueryHighlighter::setDiagnostics( + const ClangBackEnd::DynamicASTMatcherDiagnosticContainers &diagnostics) +{ + using Messages = ClangBackEnd::DynamicASTMatcherDiagnosticMessageContainers; + using Contexts = ClangBackEnd::DynamicASTMatcherDiagnosticContextContainers; + + Messages messages; + Contexts contexts; + + for (const ClangBackEnd::DynamicASTMatcherDiagnosticContainer &diagnostic : diagnostics) { + Messages newMessages = diagnostic.messages(); + Contexts newContexts = diagnostic.contexts(); + std::copy(newMessages.begin(), newMessages.end(), std::back_inserter(messages)); + std::copy(newContexts.begin(), newContexts.end(), std::back_inserter(contexts)); + } + + m_marker.setMessagesAndContexts(std::move(messages), std::move(contexts)); + + rehighlight(); +} + +bool ClangQueryHighlighter::hasDiagnostics() const +{ + return m_marker.hasMessagesOrContexts(); +} + +void ClangQueryHighlighter::highlightBlock(const QString &text) +{ + int currentLineNumber = currentBlock().blockNumber() + 1; + m_marker.highlightBlock(uint(currentLineNumber), text); +} + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryhighlighter.h b/src/plugins/clangrefactoring/clangqueryhighlighter.h new file mode 100644 index 0000000000..977f91fd11 --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryhighlighter.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** 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 "clangqueryhighlightmarker.h" + +#include <texteditor/syntaxhighlighter.h> + +#include <dynamicastmatcherdiagnosticcontainer.h> + +namespace ClangRefactoring { + +class ClangQueryHighlighter : public TextEditor::SyntaxHighlighter +{ + friend class ClangQueryHighlightMarker<ClangQueryHighlighter>; + +public: + ClangQueryHighlighter(); + + void setDiagnostics(const ClangBackEnd::DynamicASTMatcherDiagnosticContainers &diagnostics); + + bool hasDiagnostics() const; + +protected: + void highlightBlock(const QString &text) override; + +private: + ClangQueryHighlightMarker<ClangQueryHighlighter> m_marker; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryhighlightmarker.h b/src/plugins/clangrefactoring/clangqueryhighlightmarker.h new file mode 100644 index 0000000000..8f53d59538 --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryhighlightmarker.h @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** 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 <dynamicastmatcherdiagnosticcontextcontainer.h> +#include <dynamicastmatcherdiagnosticmessagecontainer.h> +#include <sourcerangecontainerv2.h> + +#include <QString> +#include <QTextCharFormat> + +namespace ClangRefactoring { + +template<typename SyntaxHighlighter> +class ClangQueryHighlightMarker +{ + using SourceRange = ClangBackEnd::V2::SourceRangeContainer; + using Message = ClangBackEnd::DynamicASTMatcherDiagnosticMessageContainer; + using Context = ClangBackEnd::DynamicASTMatcherDiagnosticContextContainer; + using Messages = ClangBackEnd::DynamicASTMatcherDiagnosticMessageContainers; + using Contexts = ClangBackEnd::DynamicASTMatcherDiagnosticContextContainers; + +public: + ClangQueryHighlightMarker(SyntaxHighlighter &highlighter) + : m_highlighter(highlighter) + { + } + + void setTextFormats(const QTextCharFormat &messageTextFormat, + const QTextCharFormat &contextTextFormat) + { + m_contextTextFormat = contextTextFormat; + m_messageTextFormat = messageTextFormat; + } + + void setMessagesAndContexts(Messages &&messages, Contexts &&contexts) + { + m_currentlyUsedContexts.clear(); + m_currentlyUsedMessages.clear(); + m_contexts = std::move(contexts); + m_messages = std::move(messages); + m_currentContextsIterator = m_contexts.begin(); + m_currentMessagesIterator = m_messages.begin(); + } + + bool hasMessage(uint currentLineNumber) const + { + return m_currentMessagesIterator != m_messages.end() + && m_currentMessagesIterator->sourceRange().start().line() == currentLineNumber; + } + + bool hasContext(uint currentLineNumber) const + { + return m_currentContextsIterator != m_contexts.end() + && m_currentContextsIterator->sourceRange().start().line() == currentLineNumber; + } + + bool isMessageNext() const + { + return m_currentMessagesIterator->sourceRange().start().column() + < m_currentContextsIterator->sourceRange().start().column(); + } + + void formatSameLineSourceRange(const SourceRange &sourceRange, const QTextCharFormat &textFormat) + { + uint startColumn = sourceRange.start().column(); + uint endColumn = sourceRange.end().column(); + m_highlighter.setFormat(startColumn - 1, endColumn - startColumn, textFormat); + } + + void formatStartLineSourceRange(const SourceRange &sourceRange, + int textSize, + const QTextCharFormat &textFormat) + { + uint startColumn = sourceRange.start().column(); + m_highlighter.setFormat(startColumn - 1, textSize - startColumn, textFormat); + } + + void formatEndLineSourceRange(const SourceRange &sourceRange, const QTextCharFormat &textFormat) + { + uint endColumn = sourceRange.end().column(); + m_highlighter.setFormat(0, endColumn - 1, textFormat); + } + + void formatMiddleLineSourceRange(int textSize, const QTextCharFormat &textFormat) + { + m_highlighter.setFormat(0, textSize, textFormat); + } + + static + bool isSameLine(const SourceRange &sourceRange) + { + uint startLine = sourceRange.start().line(); + uint endLine = sourceRange.end().line(); + + return startLine == endLine; + } + + static + bool isStartLine(const SourceRange &sourceRange, uint currentLineNumber) + { + uint startLine = sourceRange.start().line(); + + return startLine == currentLineNumber; + } + + static + bool isEndLine(const SourceRange &sourceRange, uint currentLineNumber) + { + uint endLine = sourceRange.end().line(); + + return endLine == currentLineNumber; + } + + void formatLine(const SourceRange &sourceRange, + uint currentLineNumber, + int textSize, + const QTextCharFormat &textFormat) + { + if (isSameLine(sourceRange)) + formatSameLineSourceRange(sourceRange, textFormat); + else if (isStartLine(sourceRange, currentLineNumber)) + formatStartLineSourceRange(sourceRange, textSize, textFormat); + else if (isEndLine(sourceRange, currentLineNumber)) + formatEndLineSourceRange(sourceRange, textFormat); + else + formatMiddleLineSourceRange(textSize, textFormat); + } + + template<typename Container> + void format(Container &container, + typename Container::iterator &iterator, + uint currentLineNumber, + int textSize, + const QTextCharFormat &textFormat) + { + const SourceRange &sourceRange = iterator->sourceRange(); + + formatLine(sourceRange, currentLineNumber, textSize, textFormat); + + if (isStartLine(sourceRange, currentLineNumber)) + container.push_back(*iterator); + + if (isSameLine(sourceRange) || isStartLine(sourceRange, currentLineNumber)) + ++iterator; + } + + template<typename Container> + static + void removeEndedContainers(uint currentLineNumber, Container &container) + { + auto newEnd = std::remove_if(container.begin(), + container.end(), + [&] (const auto &entry) { + return ClangQueryHighlightMarker::isEndLine(entry.sourceRange(), currentLineNumber); + }); + + container.erase(newEnd, container.end()); + } + + template<typename Container> + void formatCurrentlyUsed(Container container, + uint currentLineNumber, + int textSize, + const QTextCharFormat &textFormat) + { + for (const auto &entry : container) { + formatLine(entry.sourceRange(), currentLineNumber, textSize, textFormat);; + } + } + + void formatMessage(uint currentLineNumber, int textSize) + { + format(m_currentlyUsedMessages, + m_currentMessagesIterator, + currentLineNumber, + textSize, + m_messageTextFormat); + } + + void formatContext(uint currentLineNumber, int textSize) + { + format(m_currentlyUsedContexts, + m_currentContextsIterator, + currentLineNumber, + textSize, + m_contextTextFormat); + } + + void formatCurrentlyUsedMessagesAndContexts(uint currentLineNumber, int textSize) + { + formatCurrentlyUsed(m_currentlyUsedContexts, currentLineNumber, textSize, m_contextTextFormat); + formatCurrentlyUsed(m_currentlyUsedMessages, currentLineNumber, textSize, m_messageTextFormat); + + removeEndedContainers(currentLineNumber, m_currentlyUsedContexts); + removeEndedContainers(currentLineNumber, m_currentlyUsedMessages); + } + + void formatCurrentMessageOrContext(uint currentLineNumber, int textSize) + { + bool hasContext = this->hasContext(currentLineNumber); + bool hasMessage = this->hasMessage(currentLineNumber); + + while (hasContext || hasMessage) { + if (!hasContext) + formatMessage(currentLineNumber, textSize); + else if (!hasMessage) + formatContext(currentLineNumber, textSize); + else if (isMessageNext()) + formatMessage(currentLineNumber, textSize); + else + formatContext(currentLineNumber, textSize); + + hasContext = this->hasContext(currentLineNumber); + hasMessage = this->hasMessage(currentLineNumber); + } + } + + void highlightBlock(uint currentLineNumber, const QString ¤tText) + { + formatCurrentlyUsedMessagesAndContexts(currentLineNumber, currentText.size()); + formatCurrentMessageOrContext(currentLineNumber, currentText.size()); + } + + bool hasMessagesOrContexts() const + { + return !m_messages.empty() || !m_contexts.empty(); + } + + +private: + Contexts m_contexts; + Messages m_messages; + Contexts m_currentlyUsedContexts; + Messages m_currentlyUsedMessages; + Contexts::iterator m_currentContextsIterator{m_contexts.begin()}; + Messages::iterator m_currentMessagesIterator{m_messages.begin()}; + QTextCharFormat m_messageTextFormat; + QTextCharFormat m_contextTextFormat; + SyntaxHighlighter &m_highlighter; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp index e22bc7e2ad..2289746db3 100644 --- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp @@ -30,20 +30,23 @@ #include "searchinterface.h" #include <refactoringserverinterface.h> -#include <requestsourcerangesanddiagnosticsforquerymessage.h> +#include <clangrefactoringservermessages.h> #include <cpptools/clangcompileroptionsbuilder.h> +#include <QPointer> + namespace ClangRefactoring { ClangQueryProjectsFindFilter::ClangQueryProjectsFindFilter( ClangBackEnd::RefactoringServerInterface &server, SearchInterface &searchInterface, RefactoringClient &refactoringClient) - : server(server), - searchInterface(searchInterface), - refactoringClient(refactoringClient) + : m_server(server), + m_searchInterface(searchInterface), + m_refactoringClient(refactoringClient) { + temporaryFile.open(); } QString ClangQueryProjectsFindFilter::id() const @@ -61,19 +64,57 @@ bool ClangQueryProjectsFindFilter::isEnabled() const return true; } -void ClangQueryProjectsFindFilter::findAll(const QString &queryText, Core::FindFlags) +namespace { +Utils::SmallString toNative(const QString &path) { - searchHandle = searchInterface.startNewSearch(tr("Clang Query"), queryText); + Utils::SmallString nativePath = path; + +#ifdef Q_OS_WIN + nativePath.replace('/', '\\'); +#endif + + return nativePath; +} +} - searchHandle->setRefactoringServer(&server); +void ClangQueryProjectsFindFilter::requestSourceRangesAndDiagnostics(const QString &queryText, + const QString &exampleContent) +{ + const QString filePath = temporaryFile.fileName(); - refactoringClient.setSearchHandle(searchHandle.get()); + ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(queryText, + {ClangBackEnd::FilePath(filePath), + exampleContent, + {"cc", toNative(filePath)}}); + + m_server.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message)); +} + +SearchHandle *ClangQueryProjectsFindFilter::find(const QString &queryText) +{ + m_searchHandle = m_searchInterface.startNewSearch(tr("Clang Query"), queryText); + + m_searchHandle->setRefactoringServer(&m_server); + + m_refactoringClient.setSearchHandle(m_searchHandle.get()); auto message = createMessage(queryText); - refactoringClient.setExpectedResultCount(uint(message.sources().size())); + m_refactoringClient.setExpectedResultCount(uint(message.sources().size())); + + m_server.requestSourceRangesForQueryMessage(std::move(message)); - server.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message)); + return m_searchHandle.get(); +} + +void ClangQueryProjectsFindFilter::findAll(const QString &, Core::FindFlags) +{ + find(queryText()); +} + +bool ClangQueryProjectsFindFilter::showSearchTermInput() const +{ + return false; } Core::FindFlags ClangQueryProjectsFindFilter::supportedFindFlags() const @@ -83,28 +124,28 @@ Core::FindFlags ClangQueryProjectsFindFilter::supportedFindFlags() const void ClangQueryProjectsFindFilter::setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts) { - this->projectParts = projectParts; + this->m_projectParts = projectParts; } bool ClangQueryProjectsFindFilter::isUsable() const { - return server.isUsable(); + return m_server.isUsable(); } void ClangQueryProjectsFindFilter::setUsable(bool isUsable) { - server.setUsable(isUsable); + m_server.setUsable(isUsable); } SearchHandle *ClangQueryProjectsFindFilter::searchHandleForTestOnly() const { - return searchHandle.get(); + return m_searchHandle.get(); } void ClangQueryProjectsFindFilter::setUnsavedContent( std::vector<ClangBackEnd::V2::FileContainer> &&unsavedContent) { - this->unsavedContent = std::move(unsavedContent); + this->m_unsavedContent = std::move(unsavedContent); } Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTools::ProjectPart *projectPart, @@ -141,6 +182,11 @@ Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTool return Utils::SmallStringVector(builder.options()); } +QWidget *ClangQueryProjectsFindFilter::widget() const +{ + return nullptr; +} + namespace { Utils::SmallStringVector createCommandLine(CppTools::ProjectPart *projectPart, @@ -205,12 +251,22 @@ createSources(const std::vector<CppTools::ProjectPart::Ptr> &projectParts, } -ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage ClangQueryProjectsFindFilter::createMessage(const QString &queryText) const +ClangBackEnd::RequestSourceRangesForQueryMessage ClangQueryProjectsFindFilter::createMessage(const QString &queryText) const { - return ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage( + return ClangBackEnd::RequestSourceRangesForQueryMessage( Utils::SmallString(queryText), - createSources(projectParts, unsavedContent), - Utils::clone(unsavedContent)); + createSources(m_projectParts, m_unsavedContent), + Utils::clone(m_unsavedContent)); +} + +QString ClangQueryProjectsFindFilter::queryText() const +{ + return QString(); +} + +RefactoringClient &ClangQueryProjectsFindFilter::refactoringClient() +{ + return m_refactoringClient; } diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h index d206b0531a..73608557ec 100644 --- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h @@ -34,6 +34,7 @@ #include <filecontainerv2.h> #include <utils/smallstringvector.h> +#include <utils/temporaryfile.h> #include <memory> @@ -54,35 +55,44 @@ public: SearchInterface &searchInterface, RefactoringClient &refactoringClient); - QString id() const; - QString displayName() const; - bool isEnabled() const; - void findAll(const QString &queryText, Core::FindFlags findFlags = 0); - Core::FindFlags supportedFindFlags() const; + QString id() const override; + QString displayName() const override; + bool isEnabled() const override; + void requestSourceRangesAndDiagnostics(const QString &queryText, const QString &exampleContent); + SearchHandle *find(const QString &queryText); + void findAll(const QString &queryText, Core::FindFlags findFlags = 0) override; + bool showSearchTermInput() const override; + Core::FindFlags supportedFindFlags() const override; - void setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts); + void setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &m_projectParts); bool isUsable() const; void setUsable(bool isUsable); SearchHandle* searchHandleForTestOnly() const; - void setUnsavedContent(std::vector<ClangBackEnd::V2::FileContainer> &&unsavedContent); + void setUnsavedContent(std::vector<ClangBackEnd::V2::FileContainer> &&m_unsavedContent); static Utils::SmallStringVector compilerArguments(CppTools::ProjectPart *projectPart, CppTools::ProjectFile::Kind fileKind); +protected: + virtual QWidget *widget() const; + virtual QString queryText() const; + RefactoringClient &refactoringClient(); + private: - ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage createMessage( + ClangBackEnd::RequestSourceRangesForQueryMessage createMessage( const QString &queryText) const; private: - std::vector<ClangBackEnd::V2::FileContainer> unsavedContent; - std::unique_ptr<SearchHandle> searchHandle; - std::vector<CppTools::ProjectPart::Ptr> projectParts; - ClangBackEnd::RefactoringServerInterface &server; - SearchInterface &searchInterface; - RefactoringClient &refactoringClient; + std::vector<ClangBackEnd::V2::FileContainer> m_unsavedContent; + std::unique_ptr<SearchHandle> m_searchHandle; + std::vector<CppTools::ProjectPart::Ptr> m_projectParts; + Utils::TemporaryFile temporaryFile{"clangQuery-XXXXXX.cpp"}; + ClangBackEnd::RefactoringServerInterface &m_server; + SearchInterface &m_searchInterface; + RefactoringClient &m_refactoringClient; }; } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui new file mode 100644 index 0000000000..9fbad01f0b --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1241</width> + <height>471</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="ClangRefactoring::ClangQueryExampleTextEditorWidget" name="exampleSourceTextEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>3</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="ClangRefactoring::ClangQueryTextEditorWidget" name="queryTextEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ClangRefactoring::ClangQueryExampleTextEditorWidget</class> + <extends>QPlainTextEdit</extends> + <header>clangqueryexampletexteditorwidget.h</header> + </customwidget> + <customwidget> + <class>ClangRefactoring::ClangQueryTextEditorWidget</class> + <extends>QPlainTextEdit</extends> + <header>clangquerytexteditorwidget.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.cpp b/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.cpp new file mode 100644 index 0000000000..2351ecbcda --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "clangqueryprojectsfindfilterwidget.h" + +#include "clangqueryhighlighter.h" + +#include <texteditor/textdocument.h> + +#include <QTextDocument> + +namespace ClangRefactoring { + +ClangQueryProjectsFindFilterWidget::ClangQueryProjectsFindFilterWidget() +{ + m_form.setupUi(this); +} + +QPlainTextEdit *ClangQueryProjectsFindFilterWidget::queryTextEdit() const +{ + return m_form.queryTextEdit; +} + +QPlainTextEdit *ClangQueryProjectsFindFilterWidget::queryExampleTextEdit() const +{ + return m_form.exampleSourceTextEdit; +} + +ClangQueryExampleHighlighter *ClangQueryProjectsFindFilterWidget::clangQueryExampleHighlighter() const +{ + return m_form.exampleSourceTextEdit->syntaxHighlighter(); +} + +ClangQueryHighlighter *ClangQueryProjectsFindFilterWidget::clangQueryHighlighter() const +{ + return m_form.queryTextEdit->syntaxHighlighter(); +} + +bool ClangQueryProjectsFindFilterWidget::isValid() const +{ + return !m_form.queryTextEdit->textDocument()->document()->isEmpty() + && !clangQueryHighlighter()->hasDiagnostics(); + +} + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.h b/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.h new file mode 100644 index 0000000000..2d9fdd785a --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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 "ui_clangqueryprojectsfindfilter.h" + +namespace ClangRefactoring { + +class ClangQueryExampleHighlighter; +class ClangQueryHighlighter; + +class ClangQueryProjectsFindFilterWidget : public QWidget +{ + Q_OBJECT +public: + ClangQueryProjectsFindFilterWidget(); + + QPlainTextEdit *queryTextEdit() const; + QPlainTextEdit *queryExampleTextEdit() const; + ClangQueryExampleHighlighter *clangQueryExampleHighlighter() const; + ClangQueryHighlighter *clangQueryHighlighter() const; + + bool isValid() const; + +private: + Ui::Form m_form; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangquerytexteditorwidget.cpp b/src/plugins/clangrefactoring/clangquerytexteditorwidget.cpp new file mode 100644 index 0000000000..7ca9d90254 --- /dev/null +++ b/src/plugins/clangrefactoring/clangquerytexteditorwidget.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#include "clangquerytexteditorwidget.h" + +#include "clangqueryhighlighter.h" + +#include <texteditor/textdocument.h> + +namespace ClangRefactoring { + +ClangQueryTextEditorWidget::ClangQueryTextEditorWidget(QWidget *parent) + : BaseClangQueryTextEditorWidget(parent) +{ + m_syntaxHighlighter = new ClangQueryHighlighter; + + textDocument()->setSyntaxHighlighter(m_syntaxHighlighter); +} + +ClangQueryHighlighter *ClangQueryTextEditorWidget::syntaxHighlighter() const +{ + return m_syntaxHighlighter; +} + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangquerytexteditorwidget.h b/src/plugins/clangrefactoring/clangquerytexteditorwidget.h new file mode 100644 index 0000000000..85dace1432 --- /dev/null +++ b/src/plugins/clangrefactoring/clangquerytexteditorwidget.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** 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 "baseclangquerytexteditorwidget.h" + +namespace ClangRefactoring { + +class ClangQueryHighlighter; + +class ClangQueryTextEditorWidget : public BaseClangQueryTextEditorWidget +{ + Q_OBJECT + +public: + ClangQueryTextEditorWidget(QWidget *parent); + + ClangQueryHighlighter *syntaxHighlighter() const; + +private: + ClangQueryHighlighter *m_syntaxHighlighter; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangrefactoring-source.pri b/src/plugins/clangrefactoring/clangrefactoring-source.pri index 24c3c4f597..24102dfd99 100644 --- a/src/plugins/clangrefactoring/clangrefactoring-source.pri +++ b/src/plugins/clangrefactoring/clangrefactoring-source.pri @@ -7,7 +7,11 @@ HEADERS += \ $$PWD/searchinterface.h \ $$PWD/searchhandle.h \ $$PWD/projectpartutilities.h \ - $$PWD/clangqueryprojectsfindfilter.h + $$PWD/clangqueryprojectsfindfilter.h \ + $$PWD/clangqueryexamplehighlightmarker.h \ + $$PWD/clangqueryhighlightmarker.h \ + $$PWD/clangqueryexamplehighlighter.h \ + $$PWD/clangqueryhighlighter.h SOURCES += \ $$PWD/refactoringengine.cpp \ @@ -16,4 +20,6 @@ SOURCES += \ $$PWD/searchinterface.cpp \ $$PWD/searchhandle.cpp \ $$PWD/projectpartutilities.cpp \ - $$PWD/clangqueryprojectsfindfilter.cpp + $$PWD/clangqueryprojectsfindfilter.cpp \ + $$PWD/clangqueryexamplehighlighter.cpp \ + $$PWD/clangqueryhighlighter.cpp diff --git a/src/plugins/clangrefactoring/clangrefactoring.pro b/src/plugins/clangrefactoring/clangrefactoring.pro index 42efebd56a..1a8d16e3e3 100644 --- a/src/plugins/clangrefactoring/clangrefactoring.pro +++ b/src/plugins/clangrefactoring/clangrefactoring.pro @@ -7,13 +7,24 @@ include(../../shared/clang/clang_defines.pri) requires(!isEmpty(LIBTOOLING_LIBS)) HEADERS += \ - $$PWD/clangrefactoringplugin.h \ + clangrefactoringplugin.h \ qtcreatorsearch.h \ qtcreatorsearchhandle.h \ - qtcreatorclangqueryfindfilter.h + qtcreatorclangqueryfindfilter.h \ + clangqueryprojectsfindfilterwidget.h \ + clangqueryexampletexteditorwidget.h \ + clangquerytexteditorwidget.h \ + baseclangquerytexteditorwidget.h SOURCES += \ - $$PWD/clangrefactoringplugin.cpp \ + clangrefactoringplugin.cpp \ qtcreatorsearch.cpp \ qtcreatorsearchhandle.cpp \ - qtcreatorclangqueryfindfilter.cpp + qtcreatorclangqueryfindfilter.cpp \ + clangqueryprojectsfindfilterwidget.cpp \ + clangqueryexampletexteditorwidget.cpp \ + clangquerytexteditorwidget.cpp \ + baseclangquerytexteditorwidget.cpp + +FORMS += \ + clangqueryprojectsfindfilter.ui diff --git a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp index 7fa9daab37..b4ab35e851 100644 --- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp +++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp @@ -25,6 +25,9 @@ #include "qtcreatorclangqueryfindfilter.h" +#include "clangqueryprojectsfindfilterwidget.h" +#include "refactoringclient.h" + #include <cpptools/abstracteditorsupport.h> #include <cpptools/cppmodelmanager.h> #include <cpptools/projectinfo.h> @@ -49,13 +52,61 @@ void QtCreatorClangQueryFindFilter::findAll(const QString &queryText, Core::Find ClangQueryProjectsFindFilter::findAll(queryText, findFlags); } +void QtCreatorClangQueryFindFilter::handleQueryOrExampleTextChanged() +{ + const QString queryText = this->queryText(); + const QString queryExampleText = this->queryExampleText(); + if (!queryText.isEmpty() && !queryExampleText.isEmpty()) + requestSourceRangesAndDiagnostics(queryText, queryExampleText); +} + +QWidget *QtCreatorClangQueryFindFilter::createConfigWidget() +{ + m_widget = new ClangQueryProjectsFindFilterWidget; + + refactoringClient().setClangQueryExampleHighlighter(m_widget->clangQueryExampleHighlighter()); + refactoringClient().setClangQueryHighlighter(m_widget->clangQueryHighlighter()); + + QObject::connect(m_widget->queryExampleTextEdit(), + &QPlainTextEdit::textChanged, + this, + &QtCreatorClangQueryFindFilter::handleQueryOrExampleTextChanged); + + QObject::connect(m_widget->queryTextEdit(), + &QPlainTextEdit::textChanged, + this, + &QtCreatorClangQueryFindFilter::handleQueryOrExampleTextChanged); + + return m_widget; +} + +bool ClangRefactoring::QtCreatorClangQueryFindFilter::isValid() const +{ + return true; +} + +QWidget *QtCreatorClangQueryFindFilter::widget() const +{ + return m_widget; +} + +QString QtCreatorClangQueryFindFilter::queryText() const +{ + return m_widget->queryTextEdit()->toPlainText(); +} + +QString QtCreatorClangQueryFindFilter::queryExampleText() const +{ + return m_widget->queryExampleTextEdit()->toPlainText(); +} + namespace { std::vector<ClangBackEnd::V2::FileContainer> createUnsavedContents() { auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports(); std::vector<ClangBackEnd::V2::FileContainer> unsavedContents; - unsavedContents.reserve(abstractEditors.size()); + unsavedContents.reserve(std::size_t(abstractEditors.size())); auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) { return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()), diff --git a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h index 8157779bc9..aa53cd6fd7 100644 --- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h +++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h @@ -27,19 +27,38 @@ #include "clangqueryprojectsfindfilter.h" +#include <QPointer> + namespace ClangRefactoring { +class ClangQueryProjectsFindFilterWidget; + class QtCreatorClangQueryFindFilter final : public ClangQueryProjectsFindFilter { public: - QtCreatorClangQueryFindFilter(ClangBackEnd::RefactoringServerInterface &server, - SearchInterface &searchInterface, - RefactoringClient &refactoringClient); + QtCreatorClangQueryFindFilter(ClangBackEnd::RefactoringServerInterface &m_server, + SearchInterface &m_searchInterface, + RefactoringClient &m_refactoringClient); void findAll(const QString &queryText, Core::FindFlags findFlags = 0) override; + void handleQueryOrExampleTextChanged(); + + QWidget *createConfigWidget() override; + + bool isValid() const override; + + +protected: + QWidget *widget() const override; + QString queryText() const override; + QString queryExampleText() const; + private: void prepareFind(); + +private: + QPointer<ClangQueryProjectsFindFilterWidget> m_widget; }; } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/refactoringclient.cpp b/src/plugins/clangrefactoring/refactoringclient.cpp index 4cb954e231..e4904b53cc 100644 --- a/src/plugins/clangrefactoring/refactoringclient.cpp +++ b/src/plugins/clangrefactoring/refactoringclient.cpp @@ -25,32 +25,40 @@ #include "refactoringclient.h" +#include "clangqueryhighlighter.h" +#include "clangqueryexamplehighlighter.h" + #include <refactoringconnectionclient.h> -#include <sourcelocationsforrenamingmessage.h> -#include <sourcerangesanddiagnosticsforquerymessage.h> +#include <clangrefactoringmessages.h> namespace ClangRefactoring { void RefactoringClient::alive() { - if (connectionClient) - connectionClient->resetProcessAliveTimer(); + if (m_connectionClient) + m_connectionClient->resetProcessAliveTimer(); } void RefactoringClient::sourceLocationsForRenamingMessage( ClangBackEnd::SourceLocationsForRenamingMessage &&message) { - localRenamingCallback(message.symbolName().toQString(), + m_localRenamingCallback(message.symbolName().toQString(), message.sourceLocations(), message.textDocumentRevision()); - refactoringEngine->setUsable(true); + m_refactoringEngine->setUsable(true); } void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage( ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) { - ++resultCounter_; + m_clangQueryExampleHighlighter->setSourceRanges(message.takeSourceRanges()); + m_clangQueryHighlighter->setDiagnostics(message.diagnostics()); +} + +void RefactoringClient::sourceRangesForQueryMessage(ClangBackEnd::SourceRangesForQueryMessage &&message) +{ + ++m_resultCounter; addSearchResults(message.sourceRanges()); setResultCounterAndSendSearchIsFinishedIfFinished(); } @@ -58,50 +66,60 @@ void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage( void RefactoringClient::setLocalRenamingCallback( CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) { - this->localRenamingCallback = std::move(localRenamingCallback); + m_localRenamingCallback = std::move(localRenamingCallback); } void RefactoringClient::setRefactoringEngine(RefactoringEngine *refactoringEngine) { - this->refactoringEngine = refactoringEngine; + m_refactoringEngine = refactoringEngine; } void RefactoringClient::setSearchHandle(SearchHandle *searchHandle) { - this->searchHandle_ = searchHandle; + m_searchHandle = searchHandle; } SearchHandle *RefactoringClient::searchHandle() const { - return searchHandle_; + return m_searchHandle; +} + +void RefactoringClient::setClangQueryExampleHighlighter(ClangQueryExampleHighlighter *highlighter) +{ + m_clangQueryExampleHighlighter = highlighter; +} + +void RefactoringClient::setClangQueryHighlighter(ClangQueryHighlighter *highlighter) +{ + m_clangQueryHighlighter = highlighter; } bool RefactoringClient::hasValidLocalRenamingCallback() const { - return bool(localRenamingCallback); + return bool(m_localRenamingCallback); } void RefactoringClient::setExpectedResultCount(uint count) { - expectedResultCount_ = count; - resultCounter_ = 0; - searchHandle_->setExpectedResultCount(count); + m_expectedResultCount = count; + m_resultCounter = 0; + m_searchHandle->setExpectedResultCount(count); } uint RefactoringClient::expectedResultCount() const { - return expectedResultCount_; + return m_expectedResultCount; } uint RefactoringClient::resultCounter() const { - return resultCounter_; + return m_resultCounter; } void RefactoringClient::setRefactoringConnectionClient( ClangBackEnd::RefactoringConnectionClient *connectionClient) { - this->connectionClient = connectionClient; + m_connectionClient = connectionClient; } std::unordered_map<uint, QString> RefactoringClient::convertFilePaths( @@ -135,7 +153,7 @@ void RefactoringClient::addSearchResults(const ClangBackEnd::SourceRangesContain void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText, std::unordered_map<uint, QString> &filePaths) { - searchHandle_->addResult(filePaths[sourceRangeWithText.fileHash()], + m_searchHandle->addResult(filePaths[sourceRangeWithText.fileHash()], sourceRangeWithText.text(), {{int(sourceRangeWithText.start().line()), int(sourceRangeWithText.start().column() - 1), @@ -147,9 +165,9 @@ void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextC void RefactoringClient::setResultCounterAndSendSearchIsFinishedIfFinished() { - searchHandle_->setResultCounter(resultCounter_); - if (resultCounter_ == expectedResultCount_) - searchHandle_->finishSearch(); + m_searchHandle->setResultCounter(m_resultCounter); + if (m_resultCounter == m_expectedResultCount) + m_searchHandle->finishSearch(); } } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/refactoringclient.h b/src/plugins/clangrefactoring/refactoringclient.h index ea1abac026..09524f314f 100644 --- a/src/plugins/clangrefactoring/refactoringclient.h +++ b/src/plugins/clangrefactoring/refactoringclient.h @@ -42,6 +42,9 @@ class SourceRangeWithTextContainer; namespace ClangRefactoring { +class ClangQueryExampleHighlighter; +class ClangQueryHighlighter; + class RefactoringClient final : public ClangBackEnd::RefactoringClientInterface { public: @@ -50,12 +53,16 @@ public: ClangBackEnd::SourceLocationsForRenamingMessage &&message) override; void sourceRangesAndDiagnosticsForQueryMessage( ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) override; + void sourceRangesForQueryMessage( + ClangBackEnd::SourceRangesForQueryMessage &&message) override; void setLocalRenamingCallback( CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) override; void setRefactoringEngine(ClangRefactoring::RefactoringEngine *refactoringEngine); void setSearchHandle(ClangRefactoring::SearchHandle *searchHandleInterface); ClangRefactoring::SearchHandle *searchHandle() const; + void setClangQueryExampleHighlighter(ClangQueryExampleHighlighter *highlighter); + void setClangQueryHighlighter(ClangQueryHighlighter *highlighter); bool hasValidLocalRenamingCallback() const; @@ -79,12 +86,14 @@ private: void sendSearchIsFinished(); private: - CppTools::RefactoringEngineInterface::RenameCallback localRenamingCallback; - ClangBackEnd::RefactoringConnectionClient *connectionClient = nullptr; - ClangRefactoring::SearchHandle *searchHandle_ = nullptr; - ClangRefactoring::RefactoringEngine *refactoringEngine = nullptr; - uint expectedResultCount_ = 0; - uint resultCounter_ = 0; + CppTools::RefactoringEngineInterface::RenameCallback m_localRenamingCallback; + ClangBackEnd::RefactoringConnectionClient *m_connectionClient = nullptr; + SearchHandle *m_searchHandle = nullptr; + RefactoringEngine *m_refactoringEngine = nullptr; + ClangQueryExampleHighlighter *m_clangQueryExampleHighlighter = nullptr; + ClangQueryHighlighter *m_clangQueryHighlighter = nullptr; + uint m_expectedResultCount = 0; + uint m_resultCounter = 0; }; } // namespace ClangRefactoring diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp index 219011eff2..319cfaa47d 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp @@ -41,8 +41,8 @@ ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex { } -SourceRangesAndDiagnosticsForQueryMessage -ClangQueryGatherer::createSourceRangesAndDiagnosticsForSource( +SourceRangesForQueryMessage +ClangQueryGatherer::createSourceRangesForSource( StringCache<Utils::PathString, std::mutex> *filePathCache, V2::FileContainer &&source, const std::vector<V2::FileContainer> &unsaved, @@ -59,29 +59,29 @@ ClangQueryGatherer::createSourceRangesAndDiagnosticsForSource( clangQuery.findLocations(); - return {clangQuery.takeSourceRanges(), clangQuery.takeDiagnosticContainers()}; + return {clangQuery.takeSourceRanges()}; } -bool ClangQueryGatherer::canCreateSourceRangesAndDiagnostics() const +bool ClangQueryGatherer::canCreateSourceRanges() const { return !m_sources.empty(); } -SourceRangesAndDiagnosticsForQueryMessage ClangQueryGatherer::createNextSourceRangesAndDiagnostics() +SourceRangesForQueryMessage ClangQueryGatherer::createNextSourceRanges() { - auto message = createSourceRangesAndDiagnosticsForSource(m_filePathCache, - std::move(m_sources.back()), - m_unsaved, - m_query.clone()); + auto message = createSourceRangesForSource(m_filePathCache, + std::move(m_sources.back()), + m_unsaved, + m_query.clone()); m_sources.pop_back(); return message; } -ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesAndDiagnosticsMessage() +ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesMessage() { Future future = std::async(std::launch::async, - createSourceRangesAndDiagnosticsForSource, + createSourceRangesForSource, m_filePathCache, std::move(m_sources.back()), m_unsaved, @@ -92,12 +92,12 @@ ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesAndDia return future; } -void ClangQueryGatherer::startCreateNextSourceRangesAndDiagnosticsMessages() +void ClangQueryGatherer::startCreateNextSourceRangesMessages() { std::vector<ClangQueryGatherer::Future> futures; while (!m_sources.empty() && m_sourceFutures.size() < m_processingSlotCount) - m_sourceFutures.push_back(startCreateNextSourceRangesAndDiagnosticsMessage()); + m_sourceFutures.push_back(startCreateNextSourceRangesMessage()); } void ClangQueryGatherer::waitForFinished() @@ -121,9 +121,9 @@ const std::vector<ClangQueryGatherer::Future> &ClangQueryGatherer::sourceFutures return m_sourceFutures; } -std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::allCurrentProcessedMessages() +std::vector<SourceRangesForQueryMessage> ClangQueryGatherer::allCurrentProcessedMessages() { - std::vector<SourceRangesAndDiagnosticsForQueryMessage> messages; + std::vector<SourceRangesForQueryMessage> messages; for (Future &future : m_sourceFutures) messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get())); @@ -131,9 +131,9 @@ std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::allCu return messages; } -std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::finishedMessages() +std::vector<SourceRangesForQueryMessage> ClangQueryGatherer::finishedMessages() { - std::vector<SourceRangesAndDiagnosticsForQueryMessage> messages; + std::vector<SourceRangesForQueryMessage> messages; for (auto &&future : finishedFutures()) messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get())); diff --git a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h index 67e662bd86..7d93560eec 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h @@ -27,7 +27,7 @@ #include "sourcerangefilter.h" -#include <sourcerangesanddiagnosticsforquerymessage.h> +#include <sourcerangesforquerymessage.h> #include <filecontainerv2.h> #include <stringcache.h> @@ -38,7 +38,7 @@ namespace ClangBackEnd { class ClangQueryGatherer { public: - using Future = std::future<SourceRangesAndDiagnosticsForQueryMessage>; + using Future = std::future<SourceRangesForQueryMessage>; ClangQueryGatherer() = default; ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache, @@ -46,22 +46,22 @@ public: std::vector<V2::FileContainer> &&unsaved, Utils::SmallString &&query); - static SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForSource( + static SourceRangesForQueryMessage createSourceRangesForSource( StringCache<Utils::PathString, std::mutex> *filePathCache, V2::FileContainer &&source, const std::vector<V2::FileContainer> &unsaved, Utils::SmallString &&query); - bool canCreateSourceRangesAndDiagnostics() const; - SourceRangesAndDiagnosticsForQueryMessage createNextSourceRangesAndDiagnostics(); - Future startCreateNextSourceRangesAndDiagnosticsMessage(); - void startCreateNextSourceRangesAndDiagnosticsMessages(); + bool canCreateSourceRanges() const; + SourceRangesForQueryMessage createNextSourceRanges(); + Future startCreateNextSourceRangesMessage(); + void startCreateNextSourceRangesMessages(); void waitForFinished(); bool isFinished() const; const std::vector<V2::FileContainer> &sources() const; const std::vector<Future> &sourceFutures() const; - std::vector<SourceRangesAndDiagnosticsForQueryMessage> allCurrentProcessedMessages(); - std::vector<SourceRangesAndDiagnosticsForQueryMessage> finishedMessages(); + std::vector<SourceRangesForQueryMessage> allCurrentProcessedMessages(); + std::vector<SourceRangesForQueryMessage> finishedMessages(); void setProcessingSlotCount(uint count); diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp index 80fdbe86e3..ff4f06babe 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp @@ -29,10 +29,7 @@ #include "clangquery.h" #include <refactoringclientinterface.h> -#include <requestsourcelocationforrenamingmessage.h> -#include <requestsourcerangesanddiagnosticsforquerymessage.h> -#include <sourcelocationsforrenamingmessage.h> -#include <sourcerangesanddiagnosticsforquerymessage.h> +#include <clangrefactoringmessages.h> #include <QCoreApplication> @@ -47,7 +44,7 @@ RefactoringServer::RefactoringServer() QObject::connect(&m_pollTimer, &QTimer::timeout, - std::bind(&RefactoringServer::pollSourceRangesAndDiagnosticsForQueryMessages, this)); + std::bind(&RefactoringServer::pollSourceRangesForQueryMessages, this)); } void RefactoringServer::end() @@ -74,7 +71,22 @@ void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLo void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage( RequestSourceRangesAndDiagnosticsForQueryMessage &&message) { - gatherSourceRangesAndDiagnosticsForQueryMessages(message.takeSources(), + ClangQuery clangQuery(m_filePathCache, message.takeQuery()); + + clangQuery.addFile(message.source().filePath().directory(), + message.source().filePath().name(), + message.source().unsavedFileContent(), + message.source().commandLineArguments()); + + clangQuery.findLocations(); + + client()->sourceRangesAndDiagnosticsForQueryMessage({clangQuery.takeSourceRanges(), + clangQuery.takeDiagnosticContainers()}); +} + +void RefactoringServer::requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) +{ + gatherSourceRangesForQueryMessages(message.takeSources(), message.takeUnsavedContent(), message.takeQuery()); } @@ -91,22 +103,22 @@ bool RefactoringServer::isCancelingJobs() const return m_gatherer.isFinished(); } -void RefactoringServer::pollSourceRangesAndDiagnosticsForQueryMessages() +void RefactoringServer::pollSourceRangesForQueryMessages() { for (auto &&message : m_gatherer.finishedMessages()) - client()->sourceRangesAndDiagnosticsForQueryMessage(std::move(message)); + client()->sourceRangesForQueryMessage(std::move(message)); if (!m_gatherer.isFinished()) - m_gatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + m_gatherer.startCreateNextSourceRangesMessages(); else m_pollTimer.stop(); } -void RefactoringServer::waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished() +void RefactoringServer::waitThatSourceRangesForQueryMessagesAreFinished() { while (!m_gatherer.isFinished()) { m_gatherer.waitForFinished(); - pollSourceRangesAndDiagnosticsForQueryMessages(); + pollSourceRangesForQueryMessages(); } } @@ -120,7 +132,7 @@ void RefactoringServer::setGathererProcessingSlotCount(uint count) m_gatherer.setProcessingSlotCount(count); } -void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessages( +void RefactoringServer::gatherSourceRangesForQueryMessages( std::vector<V2::FileContainer> &&sources, std::vector<V2::FileContainer> &&unsaved, Utils::SmallString &&query) diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h index 8926ce7c01..94eeb3dcc6 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.h +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h @@ -40,7 +40,7 @@ namespace ClangBackEnd { -class SourceRangesAndDiagnosticsForQueryMessage; +class SourceRangesForQueryMessage; namespace V2 { class FileContainer; @@ -48,26 +48,27 @@ class FileContainer; class RefactoringServer : public RefactoringServerInterface { - using Future = std::future<SourceRangesAndDiagnosticsForQueryMessage>; + using Future = std::future<SourceRangesForQueryMessage>; public: RefactoringServer(); void end() override; void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override; void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override; + void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override; void cancel() override; bool isCancelingJobs() const; - void pollSourceRangesAndDiagnosticsForQueryMessages(); - void waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished(); + void pollSourceRangesForQueryMessages(); + void waitThatSourceRangesForQueryMessagesAreFinished(); bool pollTimerIsActive() const; void setGathererProcessingSlotCount(uint count); private: - void gatherSourceRangesAndDiagnosticsForQueryMessages(std::vector<V2::FileContainer> &&sources, + void gatherSourceRangesForQueryMessages(std::vector<V2::FileContainer> &&sources, std::vector<V2::FileContainer> &&unsaved, Utils::SmallString &&query); diff --git a/src/tools/clangrefactoringbackend/source/sourcerangefilter.cpp b/src/tools/clangrefactoringbackend/source/sourcerangefilter.cpp index bc566ea7d4..2abf8295b4 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangefilter.cpp +++ b/src/tools/clangrefactoringbackend/source/sourcerangefilter.cpp @@ -31,29 +31,44 @@ namespace ClangBackEnd { SourceRangeFilter::SourceRangeFilter(std::size_t sourcesCount) { - m_collectedSourceRanges.reserve(sourcesCount); + m_collectedSourceRanges.reserve(sourcesCount * 100); } -SourceRangesAndDiagnosticsForQueryMessage SourceRangeFilter::removeDuplicates(SourceRangesAndDiagnosticsForQueryMessage &&message) +SourceRangesForQueryMessage SourceRangeFilter::removeDuplicates(SourceRangesForQueryMessage &&message) { - removeDuplicates(message.sourceRanges().sourceRangeWithTextContainers()); + auto sourceRanges = removeDuplicates(message.sourceRanges().takeSourceRangeWithTextContainers()); + + message.sourceRanges().setSourceRangeWithTextContainers(std::move(sourceRanges)); return std::move(message); } -void SourceRangeFilter::removeDuplicates(SourceRangeWithTextContainers &sourceRanges) +SourceRangeWithTextContainers SourceRangeFilter::removeDuplicates(SourceRangeWithTextContainers &&sourceRanges) { - auto partitionPoint = std::stable_partition(sourceRanges.begin(), - sourceRanges.end(), - [&] (const SourceRangeWithTextContainer &sourceRange) { - return m_collectedSourceRanges.find(sourceRange) == m_collectedSourceRanges.end(); - }); + SourceRangeWithTextContainers newSourceRanges; + newSourceRanges.reserve(sourceRanges.size()); + + std::sort(sourceRanges.begin(), sourceRanges.end()); + auto sourceRangesNewEnd = std::unique(sourceRanges.begin(), sourceRanges.end()); + + std::set_difference(sourceRanges.begin(), + sourceRangesNewEnd, + m_collectedSourceRanges.begin(), + m_collectedSourceRanges.end(), + std::back_inserter(newSourceRanges)); + + V2::SourceRangeContainers collectedSourceRanges; + collectedSourceRanges.reserve(m_collectedSourceRanges.size() + newSourceRanges.size()); + + std::merge(m_collectedSourceRanges.begin(), + m_collectedSourceRanges.end(), + newSourceRanges.begin(), + newSourceRanges.end(), + std::back_inserter(collectedSourceRanges)); - sourceRanges.erase(partitionPoint, sourceRanges.end()); + std::swap(m_collectedSourceRanges, collectedSourceRanges); - std::copy(sourceRanges.begin(), - sourceRanges.end(), - std::inserter(m_collectedSourceRanges, m_collectedSourceRanges.end())); + return newSourceRanges; } } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/sourcerangefilter.h b/src/tools/clangrefactoringbackend/source/sourcerangefilter.h index 8c6c3ac42f..1cddd95a75 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangefilter.h +++ b/src/tools/clangrefactoringbackend/source/sourcerangefilter.h @@ -25,9 +25,9 @@ #pragma once -#include <unordered_set> +#include <vector> -#include <sourcerangesanddiagnosticsforquerymessage.h> +#include <sourcerangesforquerymessage.h> namespace ClangBackEnd { @@ -36,12 +36,12 @@ class SourceRangeFilter public: SourceRangeFilter(std::size_t sourcesCount = 0); - SourceRangesAndDiagnosticsForQueryMessage - removeDuplicates(SourceRangesAndDiagnosticsForQueryMessage &&message); - void removeDuplicates(SourceRangeWithTextContainers &sourceRanges); + SourceRangesForQueryMessage + removeDuplicates(SourceRangesForQueryMessage &&message); + SourceRangeWithTextContainers removeDuplicates(SourceRangeWithTextContainers &&sourceRanges); private: - std::unordered_set<SourceRangeWithTextContainer> m_collectedSourceRanges; + V2::SourceRangeContainers m_collectedSourceRanges; }; } // namespace ClangBackEnd |