diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri index 9664775dd1d2d9dcc4a7b62d32ec47739678d812..e930763843aef460c69cf86f52dfb314c493cc62 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 8f7f08a6eeb2dcbef3ebfe271c73d5269e42b08c..e48a05e7d994e3846175a7fe0fc4b1f84ad72035 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 0000000000000000000000000000000000000000..7b90453540ac57ff203fc2e1d3a42621b9fab27c --- /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 0000000000000000000000000000000000000000..7f6f0de69ea811e928285bfd12ceb28a5c575b90 --- /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 0000000000000000000000000000000000000000..797b3d58ef763e60dbed953e08e9ab8a88b2ca7b --- /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 63e59d9ee991609273a1021f4d82d9fa8e29bec6..09149ea35dd848da004fba444760e6b979ff74ba 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 &&messages, - std::vector &&contexts) + DynamicASTMatcherDiagnosticContainer(DynamicASTMatcherDiagnosticMessageContainers &&messages, + DynamicASTMatcherDiagnosticContextContainers &&contexts) : m_messages(std::move(messages)), m_contexts(std::move(contexts)) { } - const std::vector &messages() const + const DynamicASTMatcherDiagnosticMessageContainers &messages() const { return m_messages; } - const std::vector &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 m_messages; - std::vector m_contexts; + DynamicASTMatcherDiagnosticMessageContainers m_messages; + DynamicASTMatcherDiagnosticContextContainers m_contexts; }; +using DynamicASTMatcherDiagnosticContainers = std::vector; + 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 2ba2812efa099bb9d825055b6368ff2734a10172..61d7e2fff56d6181121c9ae509fbd5e1bff7098c 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; + 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 868346a5e0f9bab30abcca03918f3931727c273a..8f9581872d6809311a04708c1acfb193486a1c3e 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; + 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 717d0207905f09c7e3184db64ccf5d61fcc44616..a29ecf941fee14b504f98b6b1fefcb4480e564d4 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 d261ae67157350828f17e4c2772ce808467bd3a0..fc69cd0cd54cd3ef568fd3701b890aa15a1ac8b5 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 @@ -45,6 +44,9 @@ void RefactoringClientInterface::dispatch(const MessageEnvelop &messageEnvelop) case MessageType::SourceRangesAndDiagnosticsForQueryMessage: sourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message()); break; + case MessageType::SourceRangesForQueryMessage: + sourceRangesForQueryMessage(messageEnvelop.message()); + break; default: qWarning() << "Unknown IpcClientMessage"; } diff --git a/src/libs/clangbackendipc/refactoringclientinterface.h b/src/libs/clangbackendipc/refactoringclientinterface.h index 4cb6885806e8d95aa2b2e1a59bc1d24d00520d68..8f1098692960df1ec97cbdd2164fe6eb01d040c6 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 d03edc37dbbe48e48edf73f5790ec03de8d99bde..576489aa2509c93c6cfbed3e53e7efe5f65d1a7d 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 #include @@ -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 0533dfe28d11021f551418759406c5d8176a40eb..2f7c3af980cfcf42c195999f029405ee153928d4 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 9e45779140bf8d10751beedc4fdf1e23cc5ba88e..d6b0f6815b7ae7748037e9baf0fd4f2c83aa2023 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 @@ -46,6 +44,9 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop) case MessageType::RequestSourceRangesAndDiagnosticsForQueryMessage: requestSourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message()); break; + case MessageType::RequestSourceRangesForQueryMessage: + requestSourceRangesForQueryMessage(messageEnvelop.message()); + break; case MessageType::CancelMessage: cancel(); break; diff --git a/src/libs/clangbackendipc/refactoringserverinterface.h b/src/libs/clangbackendipc/refactoringserverinterface.h index a22f4c1f1feb22a04d3bc51409d9ef56d3ebea7a..c4a8ec6195cf9ac9775bebdfbfeea89503263d75 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 @@ -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 77f7e7e6faa48a1db587712df5c0942de53f5982..0cf4473f0755733484340ed51a64ee9ccb79afaf 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 #include @@ -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 44eb2065b2ed03bbda28aeffbda93384568861f4..73d165a9a05504b1a5714934d5149a65c5ded172 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 5bbc9065049e7f78d37a8086207e37b358872cad..878f11f0de443d72805925bdae10502922cbc3cf 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 bbc97aa8d159b45961105a0d9bfaae0ee2507aa1..afac9e9b6b3fca8ce691b309bb01996dd4992ac9 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 &&sources, - std::vector &&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 &sources() const + const V2::FileContainer &source() const { - return m_sources; + return m_source; } - std::vector takeSources() + V2::FileContainer takeSource() { - return std::move(m_sources); - } - - const std::vector &unsavedContent() const - { - return m_unsavedContent; - } - - std::vector 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 m_sources; - std::vector 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 0000000000000000000000000000000000000000..ab5b8d8468fe1a88505f0b688256e8f5013b3260 --- /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 0000000000000000000000000000000000000000..1dc3ca6ac5229435198d1ca8f3c7c2774a84d807 --- /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 &&sources, + std::vector &&unsavedContent) + : m_query(std::move(query)), + m_sources(std::move(sources)), + m_unsavedContent(std::move(unsavedContent)) + + {} + + const std::vector &sources() const + { + return m_sources; + } + + std::vector takeSources() + { + return std::move(m_sources); + } + + const std::vector &unsavedContent() const + { + return m_unsavedContent; + } + + std::vector 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 m_sources; + std::vector 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 6f508ae4a3dd67a255f8c2d6b33d2fb673fcd356..db54c7c0282e42925551394eca2de4f485c24752 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 7ffac75a02d20ffefa9c871ddf8c9427e951fec7..a5dba3ddf15caa5c6326714d19dc691da8142f03 100644 --- a/src/libs/clangbackendipc/sourcerangecontainerv2.h +++ b/src/libs/clangbackendipc/sourcerangecontainerv2.h @@ -27,6 +27,8 @@ #include "sourcelocationcontainerv2.h" +#include + 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; + 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 6634d50195675ceaf63cde7300ffd00a1f702787..f91db432f606b5b1c88440515fa6e4ab45877271 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 &&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 &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 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 147b7cb53aef6a1f6e719abc99d44638938202f8..6968830a6d894750b2253d493422dbb18aa9c9f5 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 &&filePathHash, - std::vector &&sourceRangeWithTextContainers) + SourceRangeWithTextContainers &&sourceRangeWithTextContainers) : SourceFilePathContainerBase(std::move(filePathHash)), m_sourceRangeWithTextContainers(std::move(sourceRangeWithTextContainers)) {} @@ -49,19 +49,19 @@ public: return found->second; } - const std::vector &sourceRangeWithTextContainers() const + const SourceRangeWithTextContainers &sourceRangeWithTextContainers() const { return m_sourceRangeWithTextContainers; } - std::vector &sourceRangeWithTextContainers() + SourceRangeWithTextContainers takeSourceRangeWithTextContainers() { - return m_sourceRangeWithTextContainers; + return std::move(m_sourceRangeWithTextContainers); } - std::vector 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 m_sourceRangeWithTextContainers; + SourceRangeWithTextContainers m_sourceRangeWithTextContainers; }; diff --git a/src/libs/clangbackendipc/sourcerangesforquerymessage.cpp b/src/libs/clangbackendipc/sourcerangesforquerymessage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e9227b3a66e24328966dba972dc6ac1cb90849ad --- /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 0000000000000000000000000000000000000000..7aa410e1aef8142ab3b4d93e44bfb032bdc13fd7 --- /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 + +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 8a92086319b7c044db8c55928c222a1c5851dc66..4edb2315509426de6a658b8ef23dfe392a9efcb3 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 -{ - 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{}(container.fileHash())}; - const result_type h2{std::hash{}(container.start().offset())}; - const result_type h3{std::hash{}(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 0000000000000000000000000000000000000000..05cb74f599cfbc09ed8a969948a2e2a081e58e8c --- /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 + +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 0000000000000000000000000000000000000000..b7f54a53259fbf6830197939933b4b430d613a28 --- /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 + +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 0000000000000000000000000000000000000000..d1ff575c0266d85ab90be1e8d7183f8918293094 --- /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 + +#include + + +namespace ClangRefactoring { + +ClangQueryExampleHighlighter::ClangQueryExampleHighlighter() + : m_marker(*this) +{ + std::array 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 0000000000000000000000000000000000000000..6c943644dc63334d13fb1c88f877cc77821c1da1 --- /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 + +#include + +namespace ClangBackEnd { +class SourceRangesContainer; +} + +namespace ClangRefactoring { + +class ClangQueryExampleHighlighter : public TextEditor::SyntaxHighlighter +{ + friend ClangQueryExampleHighlightMarker; + +public: + ClangQueryExampleHighlighter(); + + void setSourceRanges(ClangBackEnd::SourceRangesContainer &&container); + +protected: + void highlightBlock(const QString &text) override; + +private: + ClangQueryExampleHighlightMarker m_marker; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryexamplehighlightmarker.h b/src/plugins/clangrefactoring/clangqueryexamplehighlightmarker.h new file mode 100644 index 0000000000000000000000000000000000000000..07b7205a538e07216ecca6f072cbbc3740bc447a --- /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 + +#include +#include + +namespace ClangRefactoring { + +template +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 &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 &&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 m_textFormats; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp b/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19273d5edeaf0e4940b37b5f63332667ba428821 --- /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 + +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 0000000000000000000000000000000000000000..0a86f5022063a5b7e6523c734ef2a9b578a523e7 --- /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 0000000000000000000000000000000000000000..5f9e72d4be54ccc4e3112a92181511f61d7b4800 --- /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 +#include +#include + +#include + +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 0000000000000000000000000000000000000000..977f91fd1177ccc1a7a9d1c1ae41438deac0cda0 --- /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 + +#include + +namespace ClangRefactoring { + +class ClangQueryHighlighter : public TextEditor::SyntaxHighlighter +{ + friend class ClangQueryHighlightMarker; + +public: + ClangQueryHighlighter(); + + void setDiagnostics(const ClangBackEnd::DynamicASTMatcherDiagnosticContainers &diagnostics); + + bool hasDiagnostics() const; + +protected: + void highlightBlock(const QString &text) override; + +private: + ClangQueryHighlightMarker m_marker; +}; + +} // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/clangqueryhighlightmarker.h b/src/plugins/clangrefactoring/clangqueryhighlightmarker.h new file mode 100644 index 0000000000000000000000000000000000000000..8f53d59538f41a53ea39a9fa9070a074b2057eda --- /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 +#include +#include + +#include +#include + +namespace ClangRefactoring { + +template +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 + 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 + 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 + 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 e22bc7e2ad610be11b6f09ea16599ed8983663a3..2289746db34aeadeac5cd21e63808641342ad174 100644 --- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp @@ -30,20 +30,23 @@ #include "searchinterface.h" #include -#include +#include #include +#include + 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 &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 &&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 &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 d206b0531a9d5e443d480dba15fba0b641f78e40..73608557eca2e784a26ec9271bfc5a9776b8a790 100644 --- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h @@ -34,6 +34,7 @@ #include #include +#include #include @@ -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 &projectParts); + void setProjectParts(const std::vector &m_projectParts); bool isUsable() const; void setUsable(bool isUsable); SearchHandle* searchHandleForTestOnly() const; - void setUnsavedContent(std::vector &&unsavedContent); + void setUnsavedContent(std::vector &&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 unsavedContent; - std::unique_ptr searchHandle; - std::vector projectParts; - ClangBackEnd::RefactoringServerInterface &server; - SearchInterface &searchInterface; - RefactoringClient &refactoringClient; + std::vector m_unsavedContent; + std::unique_ptr m_searchHandle; + std::vector 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 0000000000000000000000000000000000000000..9fbad01f0bfcfa0d5279e3f1d75827aec67053a8 --- /dev/null +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui @@ -0,0 +1,65 @@ + + + Form + + + + 0 + 0 + 1241 + 471 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 3 + + + + + + + + + 0 + 1 + + + + + + + + + ClangRefactoring::ClangQueryExampleTextEditorWidget + QPlainTextEdit +
clangqueryexampletexteditorwidget.h
+
+ + ClangRefactoring::ClangQueryTextEditorWidget + QPlainTextEdit +
clangquerytexteditorwidget.h
+
+
+ + +
diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.cpp b/src/plugins/clangrefactoring/clangqueryprojectsfindfilterwidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2351ecbcdab496cc3529520ac8e3a53c35404177 --- /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 + +#include + +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 0000000000000000000000000000000000000000..2d9fdd785a20ed98e15cdc228bdac63a28dc94ea --- /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 0000000000000000000000000000000000000000..7ca9d9025451a61e1e60eb453216f6237b728aff --- /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 + +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 0000000000000000000000000000000000000000..85dace14323f691ff7564930eb43c63d0b688946 --- /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 24c3c4f597ec1f5aa13d9fbe157182354ec32a89..24102dfd99d52e8055c4917280f3f473e9347f6c 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 42efebd56a1bd30fe3f8ac62b2a26716dacbd218..1a8d16e3e398634fe8c0874ff6b189b6cc71f7b1 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 7fa9daab3731f26570d928567b985a79ed97ede0..b4ab35e851a1deb674f1f0e470c62925c21c4f43 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 #include #include @@ -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 createUnsavedContents() { auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports(); std::vector 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 8157779bc98067c17b35a72a33bb18ba6cf44e80..aa53cd6fd74f89ff981441877c2b69bd6355f78a 100644 --- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h +++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h @@ -27,19 +27,38 @@ #include "clangqueryprojectsfindfilter.h" +#include + 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 m_widget; }; } // namespace ClangRefactoring diff --git a/src/plugins/clangrefactoring/refactoringclient.cpp b/src/plugins/clangrefactoring/refactoringclient.cpp index 4cb954e231303bc94a3d77bc4146aead4dd171b3..e4904b53cc8bc7c6b77a730095ee0291015356c2 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 -#include -#include +#include 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 RefactoringClient::convertFilePaths( @@ -135,7 +153,7 @@ void RefactoringClient::addSearchResults(const ClangBackEnd::SourceRangesContain void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText, std::unordered_map &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 ea1abac026cebb372f9a5b14f4d6cf611593a86a..09524f314f822843c0a73bc26df98cdd2ee83b2a 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 219011eff2a5b337560c629c8e5b20d7bd4a5422..319cfaa47d1e1b0472792bec024dfc1ff91d7ed6 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.cpp @@ -41,8 +41,8 @@ ClangQueryGatherer::ClangQueryGatherer(StringCache *filePathCache, V2::FileContainer &&source, const std::vector &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 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::sourceFutures return m_sourceFutures; } -std::vector ClangQueryGatherer::allCurrentProcessedMessages() +std::vector ClangQueryGatherer::allCurrentProcessedMessages() { - std::vector messages; + std::vector messages; for (Future &future : m_sourceFutures) messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get())); @@ -131,9 +131,9 @@ std::vector ClangQueryGatherer::allCu return messages; } -std::vector ClangQueryGatherer::finishedMessages() +std::vector ClangQueryGatherer::finishedMessages() { - std::vector messages; + std::vector 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 67e662bd86cac85ecf26d05d362f066f51a037b0..7d93560eecf448d25547807e8b54d396d32a72c4 100644 --- a/src/tools/clangrefactoringbackend/source/clangquerygatherer.h +++ b/src/tools/clangrefactoringbackend/source/clangquerygatherer.h @@ -27,7 +27,7 @@ #include "sourcerangefilter.h" -#include +#include #include #include @@ -38,7 +38,7 @@ namespace ClangBackEnd { class ClangQueryGatherer { public: - using Future = std::future; + using Future = std::future; ClangQueryGatherer() = default; ClangQueryGatherer(StringCache *filePathCache, @@ -46,22 +46,22 @@ public: std::vector &&unsaved, Utils::SmallString &&query); - static SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForSource( + static SourceRangesForQueryMessage createSourceRangesForSource( StringCache *filePathCache, V2::FileContainer &&source, const std::vector &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 &sources() const; const std::vector &sourceFutures() const; - std::vector allCurrentProcessedMessages(); - std::vector finishedMessages(); + std::vector allCurrentProcessedMessages(); + std::vector finishedMessages(); void setProcessingSlotCount(uint count); diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp index 80fdbe86e3efc60078aedd53de9d33f91c8e3c5d..ff4f06babe58751ec85e348c337ff0c758de93ed 100644 --- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp +++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp @@ -29,10 +29,7 @@ #include "clangquery.h" #include -#include -#include -#include -#include +#include #include @@ -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 &&sources, std::vector &&unsaved, Utils::SmallString &&query) diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h index 8926ce7c01711f2eadaa027cea8f4416a15c7e79..94eeb3dcc6c8d2895aa2162ac8e8bc095394e460 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; + using Future = std::future; 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 &&sources, + void gatherSourceRangesForQueryMessages(std::vector &&sources, std::vector &&unsaved, Utils::SmallString &&query); diff --git a/src/tools/clangrefactoringbackend/source/sourcerangefilter.cpp b/src/tools/clangrefactoringbackend/source/sourcerangefilter.cpp index bc566ea7d40ad146f427a3063f980da50c601c4e..2abf8295b4a26f9ad64ef7e653221ea580aff3ac 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 8c6c3ac42f8ff47bd83b0a72bcbdf23be657ce06..1cddd95a756df677ac5e4f0353b983674e81d709 100644 --- a/src/tools/clangrefactoringbackend/source/sourcerangefilter.h +++ b/src/tools/clangrefactoringbackend/source/sourcerangefilter.h @@ -25,9 +25,9 @@ #pragma once -#include +#include -#include +#include 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 m_collectedSourceRanges; + V2::SourceRangeContainers m_collectedSourceRanges; }; } // namespace ClangBackEnd diff --git a/tests/unit/mockup/texteditor/syntaxhighlighter.h b/tests/unit/mockup/texteditor/syntaxhighlighter.h new file mode 100644 index 0000000000000000000000000000000000000000..b002308294ffc8f734fd8e2861e169d7b295eb01 --- /dev/null +++ b/tests/unit/mockup/texteditor/syntaxhighlighter.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 + +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE +class QTextDocument; +class QSyntaxHighlighterPrivate; +class QTextCharFormat; +class QFont; +class QColor; +class QTextBlockUserData; +class QTextEdit; +QT_END_NAMESPACE + +namespace TextEditor { + +class FontSettings; +class SyntaxHighlighterPrivate; + +class SyntaxHighlighter : public QObject +{ +public: + SyntaxHighlighter(QObject *parent = 0) {} + SyntaxHighlighter(QTextDocument *parent) {} + SyntaxHighlighter(QTextEdit *parent) {} + + void setDocument(QTextDocument *doc) { m_document = doc; } + QTextDocument *document() const { return m_document; } + + void setExtraFormats(const QTextBlock &block, QVector &formats) {} + + static QList generateColors(int n, const QColor &background) + { + return QList(); + } + + // Don't call in constructors of derived classes + virtual void setFontSettings(const TextEditor::FontSettings &fontSettings) {} + + void setNoAutomaticHighlighting(bool noAutomatic) {} + + void rehighlight() {} + void rehighlightBlock(const QTextBlock &block) {} + +protected: + void setDefaultTextFormatCategories() {} + void setTextFormatCategories(int count, std::function formatMapping) {} + QTextCharFormat formatForCategory(int categoryIndex) const { return QTextCharFormat(); } + virtual void highlightBlock(const QString &text) {} + + void setFormat(int start, int count, const QTextCharFormat &format) {} + void setFormat(int start, int count, const QColor &color) {} + void setFormat(int start, int count, const QFont &font) {} + QTextCharFormat format(int pos) const { return QTextCharFormat(); } + + void formatSpaces(const QString &text, int start = 0, int count = INT_MAX) {} + void setFormatWithSpaces(const QString &text, int start, int count, + const QTextCharFormat &format) {} + + int previousBlockState() const { return -1; } + int currentBlockState() const { return -1; } + void setCurrentBlockState(int newState) {} + + void setCurrentBlockUserData(QTextBlockUserData *data) {} + QTextBlockUserData *currentBlockUserData() const { return nullptr; } + + QTextBlock currentBlock() const { return QTextBlock(); } + +private: + void setTextFormatCategories(const QVector> &categories) {} + void reformatBlocks(int from, int charsRemoved, int charsAdded) {} + void delayedRehighlight() {} + + QTextDocument *m_document = nullptr; +}; + +} // namespace TextEditor diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp index 39f82e09555318f3a86f901f8ac89de87e329013..3b1a196e94dbad06b92e5370b2bee79f7a8ed994 100644 --- a/tests/unit/unittest/clangquery-test.cpp +++ b/tests/unit/unittest/clangquery-test.cpp @@ -26,6 +26,7 @@ #include "googletest.h" #include "sourcerangecontainer-matcher.h" #include "dynamicastmatcherdiagnosticcontainer-matcher.h" +#include "filesystem-utilities.h" #include @@ -34,9 +35,10 @@ using ClangBackEnd::ClangQuery; using ClangBackEnd::StringCache; +using testing::AllOf; +using testing::Contains; using testing::IsEmpty; using testing::Not; -using testing::AllOf; namespace { @@ -75,36 +77,48 @@ TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange) simpleFunctionQuery.findLocations(); - ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers().at(0), - IsSourceRangeWithText(1, 1, 8, 2, "int function(int* pointer, int value)\n{\n if (pointer == nullptr) {\n return value + 1;\n } else {\n return value - 1;\n }\n}")); + ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers(), + Contains(IsSourceRangeWithText(1, 1, 8, 2, "int function(int* pointer, int value)\n{\n if (pointer == nullptr) {\n return value + 1;\n } else {\n return value - 1;\n }\n}"))); } TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange) { ::ClangQuery query(filePathCache); - query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "#include \"unsaved.h\"", {"cc", "query_simplefunction.cpp", "-std=c++14"}); + query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "#include \"unsaved.h\"", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); query.setQuery("functionDecl()"); ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}}; query.addUnsavedFiles({unsavedFile}); query.findLocations(); - ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers().at(0), - IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();")); + ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), + Contains(IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();"))); +} + +TEST_F(ClangQuerySlowTest, FileIsNotExistingButTheUnsavedDataIsParsed) +{ + ::ClangQuery query(filePathCache); + query.addFile(TESTDATA_DIR, "foo.cpp", "void f() {}", {"cc", toNativePath(TESTDATA_DIR"/foo.cpp"), "-std=c++14"}); + query.setQuery("functionDecl()"); + + query.findLocations(); + + ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), + Contains(IsSourceRangeWithText(1, 1, 1, 12, "void f() {}"))); } TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOverride) // seems not to work in Clang { ::ClangQuery query(filePathCache); - query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "void f() {}", {"cc", "query_simplefunction.cpp", "-std=c++14"}); + query.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "void f() {}", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); query.setQuery("functionDecl()"); ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void unsaved();", {}}; query.addUnsavedFiles({unsavedFile}); query.findLocations(); - ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers().at(0), - IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();")); + ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), + Contains(IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();"))); } TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFieldDeclarationRange) @@ -191,7 +205,7 @@ TEST_F(ClangQuerySlowTest, DiagnosticForWrongArgumenType) void ClangQuery::SetUp() { - simpleFunctionQuery.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "", {"cc", "query_simplefunction.cpp", "-std=c++14"}); + simpleFunctionQuery.addFile(TESTDATA_DIR, "query_simplefunction.cpp", "", {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp"), "-std=c++14"}); simpleClassQuery.addFile(TESTDATA_DIR, "query_simpleclass.cpp", "", {"cc", "query_simpleclass.cpp", "-std=c++14"}); } diff --git a/tests/unit/unittest/clangqueryexamplehighlightmarker-test.cpp b/tests/unit/unittest/clangqueryexamplehighlightmarker-test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8af631774fe66421018cb3677316a987d04df875 --- /dev/null +++ b/tests/unit/unittest/clangqueryexamplehighlightmarker-test.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** 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 "googletest.h" +#include "filesystem-utilities.h" +#include "mocksyntaxhighligher.h" + +#include + +namespace { +using testing::AllOf; +using testing::Contains; +using testing::IsEmpty; +using testing::Not; +using testing::InSequence; +using testing::_; + +using SourceRange = ClangBackEnd::V2::SourceRangeContainer; +using SourceRanges = ClangBackEnd::SourceRangeWithTextContainers; +using Marker = ClangRefactoring::ClangQueryExampleHighlightMarker; +using TextFormats = std::array; + +class ClangQueryExampleHighlightMarker : public testing::Test +{ +protected: + void SetUp() override; + +protected: + TextFormats textFormats = {}; + MockSyntaxHighlighter highlighter; + Marker marker{highlighter}; + +}; + +TEST_F(ClangQueryExampleHighlightMarker, NoCallForNotSourceRanges) +{ + SourceRanges sourceRanges; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + + EXPECT_CALL(highlighter, setFormat(_, _, _)).Times(0); + + marker.highlightBlock(1, "foo"); +} + +TEST_F(ClangQueryExampleHighlightMarker, SingleLineSourceRange) +{ + SourceRanges sourceRanges{{1, 1, 3, 3, 1, 10, 10, "function"}}; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + + EXPECT_CALL(highlighter, setFormat(2, 7, textFormats[0])); + + marker.highlightBlock(1, " function"); +} + +TEST_F(ClangQueryExampleHighlightMarker, OtherSingleLineSourceRange) +{ + SourceRanges sourceRanges{{1, 2, 5, 5, 2, 11, 11, "function"}}; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + marker.highlightBlock(1, "foo"); + + EXPECT_CALL(highlighter, setFormat(4, 6, textFormats[0])); + + marker.highlightBlock(2, "void function"); +} + +TEST_F(ClangQueryExampleHighlightMarker, CascadedSingleLineSourceRanges) +{ + InSequence sequence; + SourceRanges sourceRanges{{1, 1, 2, 2, 1, 15, 15, "void function"}, + {1, 1, 2, 2, 1, 6, 6, "void"}, + {1, 1, 7, 7, 1, 15, 15, "function"}}; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + + EXPECT_CALL(highlighter, setFormat(1, 13, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(1, 4, textFormats[1])); + EXPECT_CALL(highlighter, setFormat(6, 8, textFormats[1])); + + marker.highlightBlock(1, "void function"); +} + +TEST_F(ClangQueryExampleHighlightMarker, DualLineSourceRanges) +{ + InSequence sequence; + SourceRanges sourceRanges{{1, 1, 2, 2, 2, 4, 20, "void f()\n {}"}}; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + + EXPECT_CALL(highlighter, setFormat(1, 7, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(0, 3, textFormats[0])); + + marker.highlightBlock(1, "void f()"); + marker.highlightBlock(2, " {};"); +} + +TEST_F(ClangQueryExampleHighlightMarker, MultipleLineSourceRanges) +{ + InSequence sequence; + SourceRanges sourceRanges{{1, 1, 2, 2, 3, 3, 20, "void f()\n {\n }"}}; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + + EXPECT_CALL(highlighter, setFormat(1, 7, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(0, 2, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(0, 2, textFormats[0])); + + marker.highlightBlock(1, "void f()"); + marker.highlightBlock(2, " {"); + marker.highlightBlock(3, " };"); +} + +TEST_F(ClangQueryExampleHighlightMarker, MoreMultipleLineSourceRanges) +{ + InSequence sequence; + SourceRanges sourceRanges{{1, 1, 1, 0, 4, 2, 0, ""}, + {1, 2, 2, 0, 2, 7, 0, ""}, + {1, 3, 2, 0, 3, 7, 0, ""}}; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + + EXPECT_CALL(highlighter, setFormat(0, 10, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(0, 7, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(1, 5, textFormats[1])); + EXPECT_CALL(highlighter, setFormat(0, 7, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(1, 5, textFormats[1])); + EXPECT_CALL(highlighter, setFormat(0, 1, textFormats[0])); + + marker.highlightBlock(1, "void f() {"); + marker.highlightBlock(2, " int x;"); + marker.highlightBlock(3, " int y;"); + marker.highlightBlock(4, "};"); +} + +TEST_F(ClangQueryExampleHighlightMarker, CascadedMultipleLineSourceRanges) +{ + InSequence sequence; + SourceRanges sourceRanges{{1, 1, 1, 0, 4, 2, 0, ""}, + {1, 2, 2, 0, 3, 4, 0, ""}, + {1, 2, 11, 0, 2, 16, 0, ""}}; + Marker marker(std::move(sourceRanges), highlighter, textFormats); + + EXPECT_CALL(highlighter, setFormat(0, 9, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(0, 16, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(1, 15, textFormats[1])); + EXPECT_CALL(highlighter, setFormat(10, 5, textFormats[2])); + EXPECT_CALL(highlighter, setFormat(0, 3, textFormats[0])); + EXPECT_CALL(highlighter, setFormat(0, 3, textFormats[1])); + EXPECT_CALL(highlighter, setFormat(0, 1, textFormats[0])); + + marker.highlightBlock(1, "class X {"); + marker.highlightBlock(2, " int f() { int y"); + marker.highlightBlock(3, " }"); + marker.highlightBlock(4, "};"); +} + +TEST_F(ClangQueryExampleHighlightMarker, FormatSingle) +{ + SourceRange sourceRange{1, 1, 3, 3, 1, 10, 10}; + + EXPECT_CALL(highlighter, setFormat(2, 7, textFormats[0])); + + marker.formatSourceRange(sourceRange, 1, 20, 0); +} + +TEST_F(ClangQueryExampleHighlightMarker, FormatMultipleStart) +{ + SourceRange sourceRange{1, 1, 3, 3, 2, 9, 20}; + + EXPECT_CALL(highlighter, setFormat(2, 8, textFormats[0])); + + marker.formatSourceRange(sourceRange, 1, 10, 0); +} + +TEST_F(ClangQueryExampleHighlightMarker, FormatMultipleEnd) +{ + SourceRange sourceRange{1, 1, 3, 3, 2, 8, 20}; + + EXPECT_CALL(highlighter, setFormat(0, 7, textFormats[1])); + + marker.formatSourceRange(sourceRange, 2, 10, 1); +} + +TEST_F(ClangQueryExampleHighlightMarker, FormatMultipleMiddle) +{ + SourceRange sourceRange{1, 1, 3, 3, 3, 8, 20}; + + EXPECT_CALL(highlighter, setFormat(0, 10, textFormats[2])); + + marker.formatSourceRange(sourceRange, 2, 10, 2); +} + +void ClangQueryExampleHighlightMarker::SetUp() +{ + textFormats[0].setFontItalic(true); + textFormats[1].setFontCapitalization(QFont::Capitalize); + textFormats[2].setFontItalic(true); + textFormats[2].setFontCapitalization(QFont::Capitalize); + textFormats[3].setFontOverline(true); + textFormats[4].setFontCapitalization(QFont::Capitalize); + textFormats[4].setFontOverline(true); + + marker.setTextFormats(TextFormats(textFormats)); +} + +} diff --git a/tests/unit/unittest/clangquerygatherer-test.cpp b/tests/unit/unittest/clangquerygatherer-test.cpp index d1ff0a508e323c278c33d3fb5a2e4cb37726f3c4..47719f031dec9f82304d5dfc91dcfb8873f102a6 100644 --- a/tests/unit/unittest/clangquerygatherer-test.cpp +++ b/tests/unit/unittest/clangquerygatherer-test.cpp @@ -54,7 +54,7 @@ using testing::UnorderedElementsAre; using testing::_; using ClangBackEnd::V2::FileContainer; -using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; +using ClangBackEnd::SourceRangesForQueryMessage; using ClangBackEnd::SourceRangesContainer; using ClangBackEnd::SourceRangesContainer; @@ -98,100 +98,100 @@ protected: query.clone()}; }; -TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnostics) +TEST_F(ClangQueryGatherer, CreateSourceRanges) { - auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(&filePathCache, source.clone(), {unsaved}, query.clone()); + auto sourceRangesAndDiagnostics = gatherer.createSourceRangesForSource(&filePathCache, source.clone(), {unsaved}, query.clone()); ASSERT_THAT(sourceRangesAndDiagnostics, - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(2, 1, 2, 12, "void f() {}"))))); } -TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnosticssWithUnsavedContent) +TEST_F(ClangQueryGatherer, CreateSourceRangessWithUnsavedContent) { - auto sourceRangesAndDiagnostics = gatherer.createSourceRangesAndDiagnosticsForSource(&filePathCache, source.clone(), {unsaved}, query.clone()); + auto sourceRangesAndDiagnostics = gatherer.createSourceRangesForSource(&filePathCache, source.clone(), {unsaved}, query.clone()); ASSERT_THAT(sourceRangesAndDiagnostics, - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); } -TEST_F(ClangQueryGatherer, CanCreateSourceRangesAndDiagnosticsIfItHasSources) +TEST_F(ClangQueryGatherer, CanCreateSourceRangesIfItHasSources) { - ASSERT_TRUE(gatherer.canCreateSourceRangesAndDiagnostics()); + ASSERT_TRUE(gatherer.canCreateSourceRanges()); } -TEST_F(ClangQueryGatherer, CanNotCreateSourceRangesAndDiagnosticsIfItHasNoSources) +TEST_F(ClangQueryGatherer, CanNotCreateSourceRangesIfItHasNoSources) { ClangBackEnd::ClangQueryGatherer empthyGatherer{&filePathCache, {}, {unsaved.clone()}, query.clone()}; - ASSERT_FALSE(empthyGatherer.canCreateSourceRangesAndDiagnostics()); + ASSERT_FALSE(empthyGatherer.canCreateSourceRanges()); } -TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnosticsForNextSource) +TEST_F(ClangQueryGatherer, CreateSourceRangesForNextSource) { - auto sourceRangesAndDiagnostics = gatherer.createNextSourceRangesAndDiagnostics(); + auto sourceRangesAndDiagnostics = gatherer.createNextSourceRanges(); ASSERT_THAT(sourceRangesAndDiagnostics, - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); } -TEST_F(ClangQueryGatherer, CreateSourceRangesAndDiagnosticsForNextSourcePopsSource) +TEST_F(ClangQueryGatherer, CreateSourceRangesForNextSourcePopsSource) { - manyGatherer.createNextSourceRangesAndDiagnostics(); + manyGatherer.createNextSourceRanges(); ASSERT_THAT(manyGatherer.sources(), SizeIs(2)); } -TEST_F(ClangQueryGatherer, StartCreateSourceRangesAndDiagnosticsForNextSource) +TEST_F(ClangQueryGatherer, StartCreateSourceRangesForNextSource) { - auto future = gatherer.startCreateNextSourceRangesAndDiagnosticsMessage(); + auto future = gatherer.startCreateNextSourceRangesMessage(); future.wait(); ASSERT_THAT(future.get(), - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); } -TEST_F(ClangQueryGatherer, StartCreateSourceRangesAndDiagnosticsForNextSourcePopsSource) +TEST_F(ClangQueryGatherer, StartCreateSourceRangesForNextSourcePopsSource) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessage(); + manyGatherer.startCreateNextSourceRangesMessage(); ASSERT_THAT(manyGatherer.sources(), SizeIs(2)); } -TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesAndDiagnosticsMessagesFutureCountIsTwos) +TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesMessagesFutureCountIsTwos) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); ASSERT_THAT(manyGatherer.sourceFutures(), SizeIs(2)); } -TEST_F(ClangQueryGatherer, AfterRestartCreateSourceRangesAndDiagnosticsMessagesFutureCountIsTwos) +TEST_F(ClangQueryGatherer, AfterRestartCreateSourceRangesMessagesFutureCountIsTwos) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); ASSERT_THAT(manyGatherer.sourceFutures(), SizeIs(2)); } -TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesAndDiagnosticsMessagesGetCollected) +TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesMessagesGetCollected) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); ASSERT_THAT(manyGatherer.allCurrentProcessedMessages(), UnorderedElementsAre( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre(IsSourceRangeWithText(1, 1, 1, 9, "void f();"), IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre( IsSourceRangeWithText(1, 1, 1, 13, "int header();"), @@ -200,7 +200,7 @@ TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesAndDiagnosticsMessagesGet TEST_F(ClangQueryGatherer, GetFinishedMessages) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); auto messages = manyGatherer.finishedMessages(); @@ -208,12 +208,12 @@ TEST_F(ClangQueryGatherer, GetFinishedMessages) ASSERT_THAT(messages, AllOf(SizeIs(2), UnorderedElementsAre( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre( IsSourceRangeWithText(1, 1, 1, 9, "void f();"), IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre( IsSourceRangeWithText(1, 1, 1, 13, "int header();"), @@ -222,10 +222,10 @@ TEST_F(ClangQueryGatherer, GetFinishedMessages) TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); auto messages = manyGatherer.finishedMessages(); @@ -233,7 +233,7 @@ TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass) ASSERT_THAT(messages, AllOf(SizeIs(1), ElementsAre( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre( IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); @@ -242,7 +242,7 @@ TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass) TEST_F(ClangQueryGatherer, FilterDuplicates) { manyGatherer.setProcessingSlotCount(3); - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); auto messages = manyGatherer.finishedMessages(); @@ -250,17 +250,17 @@ TEST_F(ClangQueryGatherer, FilterDuplicates) ASSERT_THAT(messages, AllOf(SizeIs(3), UnorderedElementsAre( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre( IsSourceRangeWithText(1, 1, 1, 9, "void f();"), IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre( IsSourceRangeWithText(1, 1, 1, 13, "int header();"), IsSourceRangeWithText(3, 1, 3, 15, "int function();")))), - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, UnorderedElementsAre( IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); @@ -268,7 +268,7 @@ TEST_F(ClangQueryGatherer, FilterDuplicates) TEST_F(ClangQueryGatherer, AfterGetFinishedMessagesFuturesAreReduced) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); @@ -278,21 +278,21 @@ TEST_F(ClangQueryGatherer, AfterGetFinishedMessagesFuturesAreReduced) TEST_F(ClangQueryGatherer, SourceFutureIsOneInTheSecondRun) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); ASSERT_THAT(manyGatherer.sourceFutures(), SizeIs(1)); } TEST_F(ClangQueryGatherer, GetOneMessageInTheSecondRun) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); auto messages = manyGatherer.finishedMessages(); @@ -302,7 +302,7 @@ TEST_F(ClangQueryGatherer, GetOneMessageInTheSecondRun) TEST_F(ClangQueryGatherer, IsNotFinishedIfSourcesExists) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); @@ -313,10 +313,10 @@ TEST_F(ClangQueryGatherer, IsNotFinishedIfSourcesExists) TEST_F(ClangQueryGatherer, IsNotFinishedIfSourceFuturesExists) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); bool isFinished = manyGatherer.isFinished(); @@ -325,10 +325,10 @@ TEST_F(ClangQueryGatherer, IsNotFinishedIfSourceFuturesExists) TEST_F(ClangQueryGatherer, IsFinishedIfNoSourceAndSourceFuturesExists) { - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); - manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); + manyGatherer.startCreateNextSourceRangesMessages(); manyGatherer.waitForFinished(); manyGatherer.finishedMessages(); diff --git a/tests/unit/unittest/clangqueryhighlightmarker-test.cpp b/tests/unit/unittest/clangqueryhighlightmarker-test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01d9f848f264158af91422c9d9e8363eaca2231d --- /dev/null +++ b/tests/unit/unittest/clangqueryhighlightmarker-test.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** 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 "googletest.h" +#include "filesystem-utilities.h" +#include "mocksyntaxhighligher.h" + +#include + +namespace { +using testing::AllOf; +using testing::Contains; +using testing::IsEmpty; +using testing::Not; +using testing::InSequence; +using testing::_; + +using SourceRange = ClangBackEnd::V2::SourceRangeContainer; +using Messages = ClangBackEnd::DynamicASTMatcherDiagnosticMessageContainers; +using Contexts = ClangBackEnd::DynamicASTMatcherDiagnosticContextContainers; +using Marker = ClangRefactoring::ClangQueryHighlightMarker; +using ErrorType = ClangBackEnd::ClangQueryDiagnosticErrorType; +using ContextType = ClangBackEnd::ClangQueryDiagnosticContextType; + +class ClangQueryHighlightMarker : public testing::Test +{ +protected: + void SetUp() override; + +protected: + QTextCharFormat messageTextFormat; + QTextCharFormat contextTextFormat; + MockSyntaxHighlighter highlighter; + Marker marker{highlighter}; + +}; + +TEST_F(ClangQueryHighlightMarker, NoCallForNoMessagesAndContexts) +{ + Messages messages; + Contexts contexts; + marker.setMessagesAndContexts(std::move(messages), std::move(contexts)); + + EXPECT_CALL(highlighter, setFormat(_, _, _)).Times(0); + + marker.highlightBlock(1, "foo"); +} + +TEST_F(ClangQueryHighlightMarker, CallForMessagesAndContextsForASingleLine) +{ + InSequence sequence; + Messages messages{{{1, 1, 5, 0, 1, 10, 0}, ErrorType::RegistryMatcherNotFound, {}}, + {{1, 1, 30, 0, 1, 40, 0}, ErrorType::RegistryMatcherNotFound, {}}}; + Contexts contexts{{{1, 1, 2, 0, 1, 15, 0}, ContextType::MatcherArg, {}}, + {{1, 1, 20, 0, 1, 50, 0}, ContextType::MatcherArg, {}}}; + marker.setMessagesAndContexts(std::move(messages), std::move(contexts)); + + EXPECT_CALL(highlighter, setFormat(1, 13, contextTextFormat)); + EXPECT_CALL(highlighter, setFormat(4, 5, messageTextFormat)); + EXPECT_CALL(highlighter, setFormat(19, 30, contextTextFormat)); + EXPECT_CALL(highlighter, setFormat(29, 10, messageTextFormat)); + + marker.highlightBlock(1, "foo"); +} + +TEST_F(ClangQueryHighlightMarker, CallForMessagesForAMultiLine) +{ + InSequence sequence; + Messages messages{{{1, 1, 5, 0, 3, 3, 0}, ErrorType::RegistryMatcherNotFound, {}}}; + Contexts contexts; + marker.setMessagesAndContexts(std::move(messages), std::move(contexts)); + + EXPECT_CALL(highlighter, setFormat(4, 8, messageTextFormat)); + EXPECT_CALL(highlighter, setFormat(0, 8, messageTextFormat)); + EXPECT_CALL(highlighter, setFormat(0, 2, messageTextFormat)); + + marker.highlightBlock(1, "declFunction("); + marker.highlightBlock(2, " decl()"); + marker.highlightBlock(3, " )"); +} + +TEST_F(ClangQueryHighlightMarker, CallForMessagesAndContextForAMultiLine) +{ + InSequence sequence; + Messages messages{{{1, 1, 5, 0, 3, 3, 0}, ErrorType::RegistryMatcherNotFound, {}}}; + Contexts contexts{{{1, 1, 2, 0, 3, 4, 0}, ContextType::MatcherArg, {}}}; + marker.setMessagesAndContexts(std::move(messages), std::move(contexts)); + + EXPECT_CALL(highlighter, setFormat(1, 11, contextTextFormat)); + EXPECT_CALL(highlighter, setFormat(4, 8, messageTextFormat)); + EXPECT_CALL(highlighter, setFormat(0, 8, contextTextFormat)); + EXPECT_CALL(highlighter, setFormat(0, 8, messageTextFormat)); + EXPECT_CALL(highlighter, setFormat(0, 3, contextTextFormat)); + EXPECT_CALL(highlighter, setFormat(0, 2, messageTextFormat)); + + marker.highlightBlock(1, "declFunction("); + marker.highlightBlock(2, " decl()"); + marker.highlightBlock(3, " ) "); +} + +void ClangQueryHighlightMarker::SetUp() +{ + messageTextFormat.setFontItalic(true); + contextTextFormat.setFontCapitalization(QFont::Capitalize); + + marker.setTextFormats(messageTextFormat, contextTextFormat); +} + +} diff --git a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp index 6e509ba0192b3568b57880625528c7bc1a9887b9..824905f188194fe59a6a430f16829520f43220b8 100644 --- a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp +++ b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp @@ -32,23 +32,25 @@ #include #include -#include -#include +#include #include #include namespace { -using ::testing::_; -using ::testing::NiceMock; -using ::testing::NotNull; -using ::testing::Return; -using ::testing::ReturnNew; -using ::testing::DefaultValue; -using ::testing::ByMove; +using testing::_; +using testing::AllOf; +using testing::NiceMock; +using testing::NotNull; +using testing::Property; +using testing::Return; +using testing::ReturnNew; +using testing::DefaultValue; +using testing::ByMove; using CppTools::ClangCompilerOptionsBuilder; +using ClangBackEnd::V2::FileContainer; class ClangQueryProjectFindFilter : public ::testing::Test { @@ -105,7 +107,7 @@ TEST_F(ClangQueryProjectFindFilter, ServerIsUsableForUsableFindFilter) TEST_F(ClangQueryProjectFindFilter, SearchHandleSetIsSetAfterFindAll) { - findFilter.findAll(findDeclQueryText); + findFilter.find(findDeclQueryText); auto searchHandle = refactoringClient.searchHandle(); @@ -115,47 +117,60 @@ TEST_F(ClangQueryProjectFindFilter, SearchHandleSetIsSetAfterFindAll) TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingStartNewSearch) { EXPECT_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"), - findDeclQueryText)) - .Times(1); + findDeclQueryText)); - findFilter.findAll(findDeclQueryText); + findFilter.find(findDeclQueryText); } TEST_F(ClangQueryProjectFindFilter, FindAllIsSettingExprectedResultCountInTheRefactoringClient) { - findFilter.findAll(findDeclQueryText); + findFilter.find(findDeclQueryText); ASSERT_THAT(refactoringClient.expectedResultCount(), 3); } TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage) { - ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(findDeclQueryText, - {{{"/path/to", "file1.h"}, - "", - commandLines[0].clone()}, - {{"/path/to", "file1.cpp"}, - "", - commandLines[1].clone()}, - {{"/path/to", "file2.cpp"}, - "", - commandLines[2].clone()}}, - {unsavedContent.clone()}); - - EXPECT_CALL(mockRefactoringServer, requestSourceRangesAndDiagnosticsForQueryMessage(message)) - .Times(1); - - findFilter.findAll(findDeclQueryText); + ClangBackEnd::RequestSourceRangesForQueryMessage message(findDeclQueryText, + {{{"/path/to", "file1.h"}, + "", + commandLines[0].clone()}, + {{"/path/to", "file1.cpp"}, + "", + commandLines[1].clone()}, + {{"/path/to", "file2.cpp"}, + "", + commandLines[2].clone()}}, + {unsavedContent.clone()}); + + EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message)); + + findFilter.find(findDeclQueryText); } TEST_F(ClangQueryProjectFindFilter, CancelSearch) { - EXPECT_CALL(mockRefactoringServer, cancel()) - .Times(1); + auto searchHandle = findFilter.find(findDeclQueryText); - findFilter.findAll(findDeclQueryText); + EXPECT_CALL(mockRefactoringServer, cancel()); - findFilter.searchHandleForTestOnly()->cancel(); + searchHandle->cancel(); +} + +TEST_F(ClangQueryProjectFindFilter, CallingRequestSourceRangesAndDiagnostics) +{ + using Message = ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage; + Utils::SmallString queryText = "functionDecl()"; + Utils::SmallString exampleContent = "void foo();"; + + EXPECT_CALL(mockRefactoringServer, + requestSourceRangesAndDiagnosticsForQueryMessage( + AllOf( + Property(&Message::source, + Property(&FileContainer::unsavedFileContent, exampleContent)), + Property(&Message::query, queryText)))); + + findFilter.requestSourceRangesAndDiagnostics(queryText, exampleContent); } std::vector createProjectParts() diff --git a/tests/unit/unittest/filesystem-utilities.h b/tests/unit/unittest/filesystem-utilities.h index 36b3e5ed7037d5e0fda1e98de31504f20bcc4c0d..0791c2b972a327ab799d33502542be8b55efeb02 100644 --- a/tests/unit/unittest/filesystem-utilities.h +++ b/tests/unit/unittest/filesystem-utilities.h @@ -25,6 +25,8 @@ #pragma once +#include + #include // use std::filesystem::path if it is supported by all compilers @@ -34,12 +36,25 @@ const char nativeSeperator = '\\'; const char nativeSeperator = '/'; #endif +template +std::string toNativePath(const char (&text)[Size]) +{ + std::string path = text; + +#ifdef _WIN32 + std::replace(path.begin(), path.end(), '/', '\\'); +#endif + + return path; +} + inline -std::string toNativePath(std::string &&path) +std::string toNativePath(const QString &qStringPath) { + auto path = qStringPath.toStdString(); #ifdef _WIN32 std::replace(path.begin(), path.end(), '/', '\\'); #endif - return std::move(path); + return path; } diff --git a/tests/unit/unittest/gtest-qt-printing.cpp b/tests/unit/unittest/gtest-qt-printing.cpp index 27cd5cfe1b9db924ddd7deff72a71ad9da9c9c35..b734dbb924826d3d7ad2ce1f4bae5abe845fe916 100644 --- a/tests/unit/unittest/gtest-qt-printing.cpp +++ b/tests/unit/unittest/gtest-qt-printing.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include +#include #include #include @@ -32,35 +33,54 @@ QT_BEGIN_NAMESPACE -void PrintTo(const QByteArray &byteArray, ::std::ostream *os) +std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray) { if (byteArray.contains('\n')) { QByteArray formattedArray = byteArray; formattedArray.replace("\n", "\n\t"); - *os << "\n\t"; - os->write(formattedArray.data(), formattedArray.size()); + out << "\n\t"; + out.write(formattedArray.data(), formattedArray.size()); } else { - *os << "\""; - os->write(byteArray.data(), byteArray.size()); - *os << "\""; + out << "\""; + out.write(byteArray.data(), byteArray.size()); + out << "\""; } + + return out; } -void PrintTo(const QVariant &variant, ::std::ostream *os) +std::ostream &operator<<(std::ostream &out, const QVariant &variant) { QString output; QDebug debug(&output); debug << variant; - PrintTo(output.toUtf8(), os); + return out << output; +} + +std::ostream &operator<<(std::ostream &out, const QString &text) +{ + return out << text.toUtf8(); } -void PrintTo(const QString &text, ::std::ostream *os) +std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format) { - const QByteArray utf8 = text.toUtf8(); + out << "(" + << format.fontFamily(); + + if (format.fontItalic()) + out << ", italic"; + + if (format.fontCapitalization() == QFont::Capitalize) + out << ", Capitalization"; + + if (format.fontOverline()) + out << ", overline"; + + out << ")"; - PrintTo(text.toUtf8(), os); + return out; } QT_END_NAMESPACE diff --git a/tests/unit/unittest/gtest-qt-printing.h b/tests/unit/unittest/gtest-qt-printing.h index 8e050ce3ad398f5e852d0b62a5e202aad0f6daef..2a1b37cbac1f35b96d6ca654d7eb05bede669e3e 100644 --- a/tests/unit/unittest/gtest-qt-printing.h +++ b/tests/unit/unittest/gtest-qt-printing.h @@ -33,8 +33,10 @@ QT_BEGIN_NAMESPACE class QVariant; class QString; +class QTextCharFormat; -void PrintTo(const QVariant &variant, ::std::ostream *os); -void PrintTo(const QString &text, ::std::ostream *os); -void PrintTo(const QByteArray &byteArray, ::std::ostream *os); +std::ostream &operator<<(std::ostream &out, const QVariant &variant); +std::ostream &operator<<(std::ostream &out, const QString &text); +std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray); +std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format); QT_END_NAMESPACE diff --git a/tests/unit/unittest/mockrefactoringclient.h b/tests/unit/unittest/mockrefactoringclient.h index 3a0c653038ff6f2f727ca4ee44437be9ed4d52ea..bc3d9131dbd46b2daa4ce3de61a13bc2352928d0 100644 --- a/tests/unit/unittest/mockrefactoringclient.h +++ b/tests/unit/unittest/mockrefactoringclient.h @@ -38,6 +38,8 @@ public: void (const ClangBackEnd::SourceLocationsForRenamingMessage&)); MOCK_METHOD1(sourceRangesAndDiagnosticsForQueryMessage, void (const ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage&)); + MOCK_METHOD1(sourceRangesForQueryMessage, + void (const ClangBackEnd::SourceRangesForQueryMessage&)); void sourceLocationsForRenamingMessage(ClangBackEnd::SourceLocationsForRenamingMessage &&message) override { @@ -49,6 +51,11 @@ public: sourceRangesAndDiagnosticsForQueryMessage(message); } + void sourceRangesForQueryMessage(ClangBackEnd::SourceRangesForQueryMessage &&message) override + { + sourceRangesForQueryMessage(message); + } + void setLocalRenamingCallback(RenameCallback &&) { } diff --git a/tests/unit/unittest/mockrefactoringserver.h b/tests/unit/unittest/mockrefactoringserver.h index c88ab1d36bc56931f70792ca2ab3e93de77d3606..abafc15244ecda16dd28708f7a85022490a570de 100644 --- a/tests/unit/unittest/mockrefactoringserver.h +++ b/tests/unit/unittest/mockrefactoringserver.h @@ -41,8 +41,11 @@ public: MOCK_METHOD1(requestSourceRangesAndDiagnosticsForQueryMessage, void (const ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage&)); + MOCK_METHOD1(requestSourceRangesForQueryMessage, + void (const ClangBackEnd::RequestSourceRangesForQueryMessage&)); + MOCK_METHOD0(cancel, - void ()); + void()); void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override { @@ -53,4 +56,9 @@ public: { requestSourceRangesAndDiagnosticsForQueryMessage(message); } + + void requestSourceRangesForQueryMessage(ClangBackEnd::RequestSourceRangesForQueryMessage &&message) override + { + requestSourceRangesForQueryMessage(message); + } }; diff --git a/tests/unit/unittest/mocksyntaxhighligher.h b/tests/unit/unittest/mocksyntaxhighligher.h new file mode 100644 index 0000000000000000000000000000000000000000..01cfe7909e40128dde7f385174d38e3effd1e329 --- /dev/null +++ b/tests/unit/unittest/mocksyntaxhighligher.h @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "googletest.h" + +#include + +#include + +class MockSyntaxHighlighter +{ +public: + MOCK_METHOD3(setFormat, + void (int start, int count, const QTextCharFormat &format)); +}; diff --git a/tests/unit/unittest/refactoringclient-test.cpp b/tests/unit/unittest/refactoringclient-test.cpp index 9ccc9c2d12e4184a2616b4fc71dd1f8d6c069949..5bbcb8178fc0cdb8fc72b78a6526829b3fdf99ab 100644 --- a/tests/unit/unittest/refactoringclient-test.cpp +++ b/tests/unit/unittest/refactoringclient-test.cpp @@ -32,8 +32,7 @@ #include #include -#include -#include +#include #include #include @@ -51,6 +50,7 @@ using ClangRefactoring::RefactoringEngine; using ClangBackEnd::SourceLocationsForRenamingMessage; using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; +using ClangBackEnd::SourceRangesForQueryMessage; using testing::_; using testing::Pair; @@ -83,12 +83,10 @@ protected: {{{42u, clangBackEndFilePath.clone()}}, {{42u, 1, 1, 0}, {42u, 2, 5, 10}}}, 1}; - SourceRangesAndDiagnosticsForQueryMessage queryResultMessage{{{{42u, clangBackEndFilePath.clone()}}, - {{42u, 1, 1, 0, 1, 5, 4, ""}, - {42u, 2, 1, 5, 2, 5, 10, ""}}}, - {}}; - SourceRangesAndDiagnosticsForQueryMessage emptyQueryResultMessage{{{},{}}, - {}}; + SourceRangesForQueryMessage queryResultMessage{{{{42u, clangBackEndFilePath.clone()}}, + {{42u, 1, 1, 0, 1, 5, 4, ""}, + {42u, 2, 1, 5, 2, 5, 10, ""}}}}; + SourceRangesForQueryMessage emptyQueryResultMessage{{{},{}}}; }; TEST_F(RefactoringClient, SourceLocationsForRenaming) @@ -143,7 +141,7 @@ TEST_F(RefactoringClient, CallAddResultsForEmptyQueryMessage) EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_)) .Times(0); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(emptyQueryResultMessage)); + client.sourceRangesForQueryMessage(std::move(emptyQueryResultMessage)); } TEST_F(RefactoringClient, CallAddResultsForQueryMessage) @@ -151,7 +149,7 @@ TEST_F(RefactoringClient, CallAddResultsForQueryMessage) EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_)) .Times(2); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); } TEST_F(RefactoringClient, CallFinishSearchForEmptyQueryMessage) @@ -159,7 +157,7 @@ TEST_F(RefactoringClient, CallFinishSearchForEmptyQueryMessage) EXPECT_CALL(mockSearchHandle, finishSearch()) .Times(1); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(emptyQueryResultMessage)); + client.sourceRangesForQueryMessage(std::move(emptyQueryResultMessage)); } TEST_F(RefactoringClient, CallFinishSearchQueryMessage) @@ -167,7 +165,7 @@ TEST_F(RefactoringClient, CallFinishSearchQueryMessage) EXPECT_CALL(mockSearchHandle, finishSearch()) .Times(1); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); } TEST_F(RefactoringClient, CallFinishSearchForTwoQueryMessages) @@ -177,8 +175,8 @@ TEST_F(RefactoringClient, CallFinishSearchForTwoQueryMessages) EXPECT_CALL(mockSearchHandle, finishSearch()) .Times(1); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); } TEST_F(RefactoringClient, CallSetExpectedResultCountInSearchHandle) @@ -191,7 +189,7 @@ TEST_F(RefactoringClient, CallSetExpectedResultCountInSearchHandle) TEST_F(RefactoringClient, ResultCounterIsOneAfterQueryMessage) { - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); ASSERT_THAT(client.resultCounter(), 1); } @@ -201,30 +199,28 @@ TEST_F(RefactoringClient, ResultCounterIsSetInSearchHandleToOne) EXPECT_CALL(mockSearchHandle, setResultCounter(1)) .Times(1); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); } TEST_F(RefactoringClient, ResultCounterIsSetInSearchHandleToTwo) { - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); EXPECT_CALL(mockSearchHandle, setResultCounter(2)) .Times(1); - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); } - TEST_F(RefactoringClient, ResultCounterIsZeroAfterSettingExpectedResultCount) { - client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); + client.sourceRangesForQueryMessage(std::move(queryResultMessage)); client.setExpectedResultCount(3); ASSERT_THAT(client.resultCounter(), 0); } - TEST_F(RefactoringClient, ConvertFilePaths) { std::unordered_map filePaths{{42u, clangBackEndFilePath.clone()}}; diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp index 1d7a00c25c4233e6be6d2d2443908a06830c9a27..aaac7c14335f2df238a962205a1504765f1aee31 100644 --- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp +++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp @@ -31,10 +31,7 @@ #include #include #include -#include -#include -#include -#include +#include #include #include @@ -72,8 +69,7 @@ protected: TEST_F(RefactoringClientServerInProcess, SendEndMessage) { - EXPECT_CALL(mockRefactoringServer, end()) - .Times(1); + EXPECT_CALL(mockRefactoringServer, end()); serverProxy.end(); scheduleServerMessages(); @@ -81,9 +77,7 @@ TEST_F(RefactoringClientServerInProcess, SendEndMessage) TEST_F(RefactoringClientServerInProcess, SendAliveMessage) { - - EXPECT_CALL(mockRefactoringClient, alive()) - .Times(1); + EXPECT_CALL(mockRefactoringClient, alive()); clientProxy.alive(); scheduleClientMessages(); @@ -94,8 +88,7 @@ TEST_F(RefactoringClientServerInProcess, SendSourceLocationsForRenamingMessage) ClangBackEnd::SourceLocationsContainer container; ClangBackEnd::SourceLocationsForRenamingMessage message("symbolName", std::move(container), 1); - EXPECT_CALL(mockRefactoringClient, sourceLocationsForRenamingMessage(message)) - .Times(1); + EXPECT_CALL(mockRefactoringClient, sourceLocationsForRenamingMessage(message)); clientProxy.sourceLocationsForRenamingMessage(message.clone()); scheduleClientMessages(); @@ -110,8 +103,7 @@ TEST_F(RefactoringClientServerInProcess, SendRequestSourceLocationsForRenamingMe {"cc", "renamevariable.cpp"}, 1}; - EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(message)) - .Times(1); + EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(message)); serverProxy.requestSourceLocationsForRenamingMessage(message.clone()); scheduleServerMessages(); @@ -124,36 +116,62 @@ TEST_F(RefactoringClientServerInProcess, SourceRangesAndDiagnosticsForQueryMessa ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage message(std::move(sourceRangesContainer), std::move(diagnosticContainers)); - EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage(message)) - .Times(1); + EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage(message)); clientProxy.sourceRangesAndDiagnosticsForQueryMessage(message.clone()); scheduleClientMessages(); } +TEST_F(RefactoringClientServerInProcess, SourceRangesForQueryMessage) +{ + ClangBackEnd::SourceRangesContainer sourceRangesContainer; + ClangBackEnd::SourceRangesForQueryMessage message(std::move(sourceRangesContainer)); + + EXPECT_CALL(mockRefactoringClient, sourceRangesForQueryMessage(message)); + + clientProxy.sourceRangesForQueryMessage(message.clone()); + scheduleClientMessages(); +} + TEST_F(RefactoringClientServerInProcess, RequestSourceRangesAndDiagnosticsForQueryMessage) { - RequestSourceRangesAndDiagnosticsForQueryMessage message{"functionDecl()", - {{{TESTDATA_DIR, "query_simplefunction.cpp"}, - "void f();", - {"cc", "query_simplefunction.cpp"}, - 1}}, - {{{TESTDATA_DIR, "query_simplefunction.h"}, - "void f();", - {}, - 1}}}; - - EXPECT_CALL(mockRefactoringServer, requestSourceRangesAndDiagnosticsForQueryMessage(message)) - .Times(1); - - serverProxy.requestSourceRangesAndDiagnosticsForQueryMessage(message.clone()); + RequestSourceRangesForQueryMessage message{"functionDecl()", + {{{TESTDATA_DIR, "query_simplefunction.cpp"}, + "void f();", + {"cc", "query_simplefunction.cpp"}, + 1}}, + {{{TESTDATA_DIR, "query_simplefunction.h"}, + "void f();", + {}, + 1}}}; + + EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message)); + + serverProxy.requestSourceRangesForQueryMessage(message.clone()); + scheduleServerMessages(); +} + +TEST_F(RefactoringClientServerInProcess, RequestSourceRangesForQueryMessage) +{ + RequestSourceRangesForQueryMessage message{"functionDecl()", + {{{TESTDATA_DIR, "query_simplefunction.cpp"}, + "void f();", + {"cc", "query_simplefunction.cpp"}, + 1}}, + {{{TESTDATA_DIR, "query_simplefunction.h"}, + "void f();", + {}, + 1}}}; + + EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message)); + + serverProxy.requestSourceRangesForQueryMessage(message.clone()); scheduleServerMessages(); } TEST_F(RefactoringClientServerInProcess, CancelMessage) { - EXPECT_CALL(mockRefactoringServer, cancel()) - .Times(1); + EXPECT_CALL(mockRefactoringServer, cancel()); serverProxy.cancel(); scheduleServerMessages(); diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp index 3226863d56016c2dc5e272f26f4a7ab67e708c04..5383841d8a9a30566f649cca8ec117885ed1ec6c 100644 --- a/tests/unit/unittest/refactoringengine-test.cpp +++ b/tests/unit/unittest/refactoringengine-test.cpp @@ -30,10 +30,7 @@ #include -#include -#include -#include -#include +#include #include #include diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp index 40ca87031ea6da5296e29d5b781930aaeb789b59..b07d490a12dbb24ecdfc21fe04e011b78a71918e 100644 --- a/tests/unit/unittest/refactoringserver-test.cpp +++ b/tests/unit/unittest/refactoringserver-test.cpp @@ -30,16 +30,16 @@ #include "sourcerangecontainer-matcher.h" #include -#include -#include -#include -#include -#include +#include + +#include +#include namespace { using testing::AllOf; using testing::Contains; +using testing::IsEmpty; using testing::NiceMock; using testing::Not; using testing::Pair; @@ -50,9 +50,11 @@ using testing::_; using ClangBackEnd::FilePath; using ClangBackEnd::RequestSourceLocationsForRenamingMessage; using ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage; +using ClangBackEnd::RequestSourceRangesForQueryMessage; using ClangBackEnd::SourceLocationsContainer; using ClangBackEnd::SourceLocationsForRenamingMessage; using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; +using ClangBackEnd::SourceRangesForQueryMessage; using ClangBackEnd::SourceRangesContainer; using ClangBackEnd::V2::FileContainer; @@ -80,6 +82,7 @@ protected: FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, sourceContent.clone(), {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp")}}; + QTemporaryFile temporaryFile{QDir::tempPath() + "/clangQuery-XXXXXX.cpp"}; int processingSlotCount = 2; }; @@ -88,12 +91,12 @@ using RefactoringServerVerySlowTest = RefactoringServer; TEST_F(RefactoringServerSlowTest, RequestSourceLocationsForRenamingMessage) { - RequestSourceLocationsForRenamingMessage requestSourceLocationsForRenamingMessage{{TESTDATA_DIR, "renamevariable.cpp"}, - 1, - 5, - "int v;\n\nint x = v + 3;\n", - {"cc", "renamevariable.cpp"}, - 1}; + RequestSourceLocationsForRenamingMessage message{{TESTDATA_DIR, "renamevariable.cpp"}, + 1, + 5, + "int v;\n\nint x = v + 3;\n", + {"cc", "renamevariable.cpp"}, + 1}; EXPECT_CALL(mockRefactoringClient, sourceLocationsForRenamingMessage( @@ -106,22 +109,22 @@ TEST_F(RefactoringServerSlowTest, RequestSourceLocationsForRenamingMessage) Property(&SourceLocationsContainer::filePaths, Contains(Pair(_, FilePath(TESTDATA_DIR, "renamevariable.cpp"))))))))); - refactoringServer.requestSourceLocationsForRenamingMessage(std::move(requestSourceLocationsForRenamingMessage)); + refactoringServer.requestSourceLocationsForRenamingMessage(std::move(message)); } -TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsForQueryMessage) +TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesForQueryMessage) { - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - {source.clone()}, - {}}; + RequestSourceRangesForQueryMessage message{"functionDecl()", + {source.clone()}, + {}}; EXPECT_CALL(mockRefactoringClient, - sourceRangesAndDiagnosticsForQueryMessage( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + sourceRangesForQueryMessage( + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); } TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUnsavedContentForQueryMessage) @@ -133,62 +136,62 @@ TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUns FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"}, unsavedContent.clone(), {}}; - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - {source.clone()}, - {unsaved.clone()}}; + RequestSourceRangesForQueryMessage message{"functionDecl()", + {source.clone()}, + {unsaved.clone()}}; EXPECT_CALL(mockRefactoringClient, - sourceRangesAndDiagnosticsForQueryMessage( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + sourceRangesForQueryMessage( + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 1, 9, unsavedContent)))))); - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); } -TEST_F(RefactoringServerSlowTest, RequestTwoSourceRangesAndDiagnosticsForQueryMessage) +TEST_F(RefactoringServerSlowTest, RequestTwoSourceRangesForQueryMessage) { - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - {source.clone(), source.clone()}, - {}}; + RequestSourceRangesForQueryMessage message{"functionDecl()", + {source.clone(), source.clone()}, + {}}; EXPECT_CALL(mockRefactoringClient, - sourceRangesAndDiagnosticsForQueryMessage( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + sourceRangesForQueryMessage( + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); EXPECT_CALL(mockRefactoringClient, - sourceRangesAndDiagnosticsForQueryMessage( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + sourceRangesForQueryMessage( + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))); - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); } -TEST_F(RefactoringServerVerySlowTest, RequestManySourceRangesAndDiagnosticsForQueryMessage) +TEST_F(RefactoringServerVerySlowTest, RequestManySourceRangesForQueryMessage) { std::vector sources; std::fill_n(std::back_inserter(sources), processingSlotCount + 3, source.clone()); - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - std::move(sources), - {}}; + RequestSourceRangesForQueryMessage message{"functionDecl()", + std::move(sources), + {}}; EXPECT_CALL(mockRefactoringClient, - sourceRangesAndDiagnosticsForQueryMessage( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + sourceRangesForQueryMessage( + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); EXPECT_CALL(mockRefactoringClient, - sourceRangesAndDiagnosticsForQueryMessage( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + sourceRangesForQueryMessage( + Property(&SourceRangesForQueryMessage::sourceRanges, Property(&SourceRangesContainer::sourceRangeWithTextContainers, Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))) .Times(processingSlotCount + 2); - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); } TEST_F(RefactoringServer, CancelJobs) @@ -197,10 +200,10 @@ TEST_F(RefactoringServer, CancelJobs) std::fill_n(std::back_inserter(sources), std::thread::hardware_concurrency() + 3, source.clone()); - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - std::move(sources), - {}}; - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + RequestSourceRangesForQueryMessage message{"functionDecl()", + std::move(sources), + {}}; + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); refactoringServer.cancel(); @@ -209,48 +212,87 @@ TEST_F(RefactoringServer, CancelJobs) TEST_F(RefactoringServer, PollTimerIsActiveAfterStart) { - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - {source}, - {}}; + RequestSourceRangesForQueryMessage message{"functionDecl()", + {source}, + {}}; - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); ASSERT_TRUE(refactoringServer.pollTimerIsActive()); } TEST_F(RefactoringServer, PollTimerIsNotActiveAfterFinishing) { - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - {source}, - {}}; - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + RequestSourceRangesForQueryMessage message{"functionDecl()", + {source}, + {}}; + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); - refactoringServer.waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished(); + refactoringServer.waitThatSourceRangesForQueryMessagesAreFinished(); ASSERT_FALSE(refactoringServer.pollTimerIsActive()); } TEST_F(RefactoringServer, PollTimerNotIsActiveAfterCanceling) { - RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", - {source}, - {}}; - refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); + RequestSourceRangesForQueryMessage message{"functionDecl()", + {source}, + {}}; + refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); refactoringServer.cancel(); ASSERT_FALSE(refactoringServer.pollTimerIsActive()); } +TEST_F(RefactoringServerSlowTest, ForValidRequestSourceRangesAndDiagnosticsGetSourceRange) +{ + RequestSourceRangesAndDiagnosticsForQueryMessage message("functionDecl()", + {FilePath(temporaryFile.fileName()), + "void f() {}", + {"cc", toNativePath(temporaryFile.fileName())}}); + + EXPECT_CALL(mockRefactoringClient, + sourceRangesAndDiagnosticsForQueryMessage( + AllOf( + Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 1, 12, "void f() {}")))), + Property(&SourceRangesAndDiagnosticsForQueryMessage::diagnostics, + IsEmpty())))); + + refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message)); +} + +TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGetDiagnostics) +{ + RequestSourceRangesAndDiagnosticsForQueryMessage message("func()", + {FilePath(temporaryFile.fileName()), + "void f() {}", + {"cc", toNativePath(temporaryFile.fileName())}}); + + EXPECT_CALL(mockRefactoringClient, + sourceRangesAndDiagnosticsForQueryMessage( + AllOf( + Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Property(&SourceRangesContainer::sourceRangeWithTextContainers, + IsEmpty())), + Property(&SourceRangesAndDiagnosticsForQueryMessage::diagnostics, + Not(IsEmpty()))))); + + refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message)); +} + void RefactoringServer::SetUp() { + temporaryFile.open(); refactoringServer.setClient(&mockRefactoringClient); } void RefactoringServer::TearDown() { refactoringServer.setGathererProcessingSlotCount(uint(processingSlotCount)); - refactoringServer.waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished(); + refactoringServer.waitThatSourceRangesForQueryMessagesAreFinished(); } } diff --git a/tests/unit/unittest/sourcerangefilter-test.cpp b/tests/unit/unittest/sourcerangefilter-test.cpp index 059f9827f621ba973919a5246424a3ecb1d41a9c..8620458a54ed8fd8395a35a465a6e6563b7df064 100644 --- a/tests/unit/unittest/sourcerangefilter-test.cpp +++ b/tests/unit/unittest/sourcerangefilter-test.cpp @@ -34,7 +34,7 @@ using testing::IsEmpty; using ClangBackEnd::SourceRangeWithTextContainer; using ClangBackEnd::SourceRangeWithTextContainers; -using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; +using ClangBackEnd::SourceRangesForQueryMessage; class SourceRangeFilter : public ::testing::Test { @@ -43,54 +43,56 @@ protected: protected: SourceRangeWithTextContainers sourceRanges1{{1, 1, 1, 1, 2, 1, 4, "foo"}, - {2, 1, 1, 1, 2, 1, 4, "foo"}, - {1, 1, 1, 1, 2, 2, 5, "foo"}}; - SourceRangeWithTextContainers sourceRanges2{{1, 1, 1, 1, 2, 1, 4, "foo"}, + {1, 1, 1, 1, 2, 2, 5, "foo"}, + {2, 1, 1, 1, 2, 1, 4, "foo"}}; + SourceRangeWithTextContainers sourceRanges2{{3, 1, 1, 1, 2, 1, 4, "foo"}, + {1, 1, 1, 1, 2, 1, 4, "foo"}, + {1, 1, 1, 1, 2, 3, 6, "foo"}}; + SourceRangeWithTextContainers sourceRanges3{{1, 1, 1, 1, 2, 3, 6, "foo"}, + {3, 1, 1, 1, 2, 1, 4, "foo"}}; + SourceRangeWithTextContainers sourceRanges4{{1, 1, 1, 1, 2, 3, 6, "foo"}, {3, 1, 1, 1, 2, 1, 4, "foo"}, - {1, 1, 1, 1, 2, 2, 6, "foo"}}; - SourceRangeWithTextContainers sourceRanges3{{3, 1, 1, 1, 2, 1, 4, "foo"}, - {1, 1, 1, 1, 2, 2, 6, "foo"}}; - SourceRangesAndDiagnosticsForQueryMessage message1{{{}, Utils::clone(sourceRanges1)}, {}}; - SourceRangesAndDiagnosticsForQueryMessage message2{{{}, Utils::clone(sourceRanges2)}, {}}; + {3, 1, 1, 1, 2, 1, 4, "foo"}}; + SourceRangeWithTextContainers sourceRanges5{{3, 1, 1, 1, 2, 1, 4, "foo"}, + {1, 1, 1, 1, 2, 3, 6, "foo"}}; + SourceRangesForQueryMessage message1{{{}, Utils::clone(sourceRanges1)}}; + SourceRangesForQueryMessage message2{{{}, Utils::clone(sourceRanges2)}}; ClangBackEnd::SourceRangeFilter filter{3}; }; -TEST_F(SourceRangeFilter, DontChangeForFirstTime) +TEST_F(SourceRangeFilter, DontChangeForFirstTimeIfElementsAreUnique) { - auto expectedSourceRanges = sourceRanges1; + auto sourceRange = filter.removeDuplicates(Utils::clone(sourceRanges1)); - filter.removeDuplicates(sourceRanges1); - - ASSERT_THAT(sourceRanges1, ContainerEq(expectedSourceRanges)); + ASSERT_THAT(sourceRange, ContainerEq(sourceRanges1)); } TEST_F(SourceRangeFilter, DoNotFilterNonDuplicates) { - SourceRangeWithTextContainers expectedSourceRanges = sourceRanges3; - filter.removeDuplicates(sourceRanges1); + filter.removeDuplicates(Utils::clone(sourceRanges1)); - filter.removeDuplicates(sourceRanges3); + auto sourceRange = filter.removeDuplicates(Utils::clone(sourceRanges3)); - ASSERT_THAT(sourceRanges3, ContainerEq(expectedSourceRanges)); + ASSERT_THAT(sourceRange, ContainerEq(sourceRanges3)); } TEST_F(SourceRangeFilter, FilterDuplicates) { - filter.removeDuplicates(sourceRanges1); + filter.removeDuplicates(Utils::clone(sourceRanges1)); - filter.removeDuplicates(sourceRanges2); + auto sourceRange = filter.removeDuplicates(Utils::clone(sourceRanges2)); - ASSERT_THAT(sourceRanges2, ContainerEq(sourceRanges3)); + ASSERT_THAT(sourceRange, ContainerEq(sourceRanges3)); } TEST_F(SourceRangeFilter, FilterMoreDuplicates) { - filter.removeDuplicates(sourceRanges1); - filter.removeDuplicates(sourceRanges2); + filter.removeDuplicates(Utils::clone(sourceRanges1)); + filter.removeDuplicates(Utils::clone(sourceRanges2)); - filter.removeDuplicates(sourceRanges3); + auto sourceRange = filter.removeDuplicates(Utils::clone(sourceRanges3)); - ASSERT_THAT(sourceRanges3, IsEmpty()); + ASSERT_THAT(sourceRange, IsEmpty()); } TEST_F(SourceRangeFilter, FilterDuplicatesFromMessage) @@ -103,4 +105,19 @@ TEST_F(SourceRangeFilter, FilterDuplicatesFromMessage) ContainerEq(sourceRanges3)); } +TEST_F(SourceRangeFilter, FilterDuplicatesInOneRangeSet) +{ + auto sourceRange = filter.removeDuplicates(Utils::clone(sourceRanges4)); + + ASSERT_THAT(sourceRange, ContainerEq(sourceRanges3)); +} + +TEST_F(SourceRangeFilter, SortSourceRanges) +{ + auto sourceRange = filter.removeDuplicates(Utils::clone(sourceRanges5)); + + ASSERT_THAT(sourceRange, ContainerEq(sourceRanges3)); +} + + } diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index ca7f4fdb74a62152f224f576943cb5e96a12a82e..c227eaede241b93ee42327ff629b81c7d68d5002 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -64,7 +64,9 @@ SOURCES += \ pchmanagerserver-test.cpp \ pchmanagerclientserverinprocess-test.cpp \ filepath-test.cpp \ - sourcerangefilter-test.cpp + sourcerangefilter-test.cpp \ + clangqueryexamplehighlightmarker-test.cpp \ + clangqueryhighlightmarker-test.cpp !isEmpty(LIBCLANG_LIBS) { SOURCES += \ @@ -176,7 +178,8 @@ HEADERS += \ mockpchcreator.h \ dummyclangipcclient.h \ mockclangcodemodelclient.h \ - mockclangcodemodelserver.h + mockclangcodemodelserver.h \ + mocksyntaxhighligher.h !isEmpty(LIBCLANG_LIBS) { HEADERS += \