Clang: Add clang query pane

We now support highlighting for an example text and for the query.

Change-Id: I88c415ff871cf3e4c2d4fc83d60a8555bf0ce08a
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2017-07-03 12:35:58 +02:00
committed by Tim Jenssen
parent 8c4127ebac
commit a31eae4d0a
75 changed files with 2950 additions and 484 deletions

View File

@@ -79,7 +79,9 @@ SOURCES += $$PWD/clangcodemodelserverinterface.cpp \
$$PWD/pchmanagerclientproxy.cpp \ $$PWD/pchmanagerclientproxy.cpp \
$$PWD/projectpartpch.cpp \ $$PWD/projectpartpch.cpp \
$$PWD/precompiledheadersupdatedmessage.cpp \ $$PWD/precompiledheadersupdatedmessage.cpp \
$$PWD/removepchprojectpartsmessage.cpp $$PWD/removepchprojectpartsmessage.cpp \
$$PWD/sourcerangesforquerymessage.cpp \
$$PWD/requestsourcerangesforquerymessage.cpp
HEADERS += \ HEADERS += \
$$PWD/clangcodemodelserverinterface.h \ $$PWD/clangcodemodelserverinterface.h \
@@ -159,5 +161,10 @@ HEADERS += \
$$PWD/removepchprojectpartsmessage.h \ $$PWD/removepchprojectpartsmessage.h \
$$PWD/clangcodemodelclientmessages.h \ $$PWD/clangcodemodelclientmessages.h \
$$PWD/clangcodemodelservermessages.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 contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -128,7 +128,9 @@ enum class MessageType : quint8 {
RequestSourceLocationsForRenamingMessage, RequestSourceLocationsForRenamingMessage,
RequestSourceRangesAndDiagnosticsForQueryMessage, RequestSourceRangesAndDiagnosticsForQueryMessage,
RequestSourceRangesForQueryMessage,
SourceRangesAndDiagnosticsForQueryMessage, SourceRangesAndDiagnosticsForQueryMessage,
SourceRangesForQueryMessage,
CancelMessage, CancelMessage,
UpdatePchProjectPartsMessage, UpdatePchProjectPartsMessage,

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -34,19 +34,19 @@ class DynamicASTMatcherDiagnosticContainer
{ {
public: public:
DynamicASTMatcherDiagnosticContainer() = default; DynamicASTMatcherDiagnosticContainer() = default;
DynamicASTMatcherDiagnosticContainer(std::vector<DynamicASTMatcherDiagnosticMessageContainer> &&messages, DynamicASTMatcherDiagnosticContainer(DynamicASTMatcherDiagnosticMessageContainers &&messages,
std::vector<DynamicASTMatcherDiagnosticContextContainer> &&contexts) DynamicASTMatcherDiagnosticContextContainers &&contexts)
: m_messages(std::move(messages)), : m_messages(std::move(messages)),
m_contexts(std::move(contexts)) m_contexts(std::move(contexts))
{ {
} }
const std::vector<DynamicASTMatcherDiagnosticMessageContainer> &messages() const const DynamicASTMatcherDiagnosticMessageContainers &messages() const
{ {
return m_messages; return m_messages;
} }
const std::vector<DynamicASTMatcherDiagnosticContextContainer> &contexts() const const DynamicASTMatcherDiagnosticContextContainers &contexts() const
{ {
return m_contexts; return m_contexts;
} }
@@ -88,15 +88,16 @@ public:
DynamicASTMatcherDiagnosticContainer clone() const DynamicASTMatcherDiagnosticContainer clone() const
{ {
return DynamicASTMatcherDiagnosticContainer(Utils::clone(m_messages), return *this;
Utils::clone(m_contexts));
} }
private: private:
std::vector<DynamicASTMatcherDiagnosticMessageContainer> m_messages; DynamicASTMatcherDiagnosticMessageContainers m_messages;
std::vector<DynamicASTMatcherDiagnosticContextContainer> m_contexts; DynamicASTMatcherDiagnosticContextContainers m_contexts;
}; };
using DynamicASTMatcherDiagnosticContainers = std::vector<DynamicASTMatcherDiagnosticContainer>;
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContainer &container); CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContainer &container);
std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticContainer &container); std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticContainer &container);

View File

@@ -105,6 +105,8 @@ private:
Utils::SmallStringVector m_arguments; Utils::SmallStringVector m_arguments;
}; };
using DynamicASTMatcherDiagnosticContextContainers = std::vector<DynamicASTMatcherDiagnosticContextContainer>;
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContextContainer &container); CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticContextContainer &container);
std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticContextContainer &container); std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticContextContainer &container);

View File

@@ -105,6 +105,8 @@ private:
Utils::SmallStringVector m_arguments; Utils::SmallStringVector m_arguments;
}; };
using DynamicASTMatcherDiagnosticMessageContainers = std::vector<DynamicASTMatcherDiagnosticMessageContainer>;
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticMessageContainer &container); CMBIPC_EXPORT QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticMessageContainer &container);
std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticMessageContainer &container); std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticMessageContainer &container);

View File

@@ -86,13 +86,19 @@ public:
friend QDataStream &operator<<(QDataStream &out, const FilePath &filePath) friend QDataStream &operator<<(QDataStream &out, const FilePath &filePath)
{ {
out << filePath.m_path; out << filePath.m_path;
out << uint(filePath.m_slashIndex);
return out; return out;
} }
friend QDataStream &operator>>(QDataStream &in, FilePath &filePath) friend QDataStream &operator>>(QDataStream &in, FilePath &filePath)
{ {
uint slashIndex;
in >> filePath.m_path; in >> filePath.m_path;
in >> slashIndex;
filePath.m_slashIndex = slashIndex;
return in; return in;
} }
@@ -116,7 +122,7 @@ public:
FilePath clone() const FilePath clone() const
{ {
return FilePath(m_path.clone(), m_slashIndex); return *this;
} }
private: private:

View File

@@ -26,8 +26,7 @@
#include "refactoringclientinterface.h" #include "refactoringclientinterface.h"
#include "messageenvelop.h" #include "messageenvelop.h"
#include "sourcelocationsforrenamingmessage.h" #include "clangrefactoringclientmessages.h"
#include "sourcerangesanddiagnosticsforquerymessage.h"
#include <QDebug> #include <QDebug>
@@ -45,6 +44,9 @@ void RefactoringClientInterface::dispatch(const MessageEnvelop &messageEnvelop)
case MessageType::SourceRangesAndDiagnosticsForQueryMessage: case MessageType::SourceRangesAndDiagnosticsForQueryMessage:
sourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<SourceRangesAndDiagnosticsForQueryMessage>()); sourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<SourceRangesAndDiagnosticsForQueryMessage>());
break; break;
case MessageType::SourceRangesForQueryMessage:
sourceRangesForQueryMessage(messageEnvelop.message<SourceRangesForQueryMessage>());
break;
default: default:
qWarning() << "Unknown IpcClientMessage"; qWarning() << "Unknown IpcClientMessage";
} }

View File

@@ -33,6 +33,7 @@ namespace ClangBackEnd {
class SourceLocationsForRenamingMessage; class SourceLocationsForRenamingMessage;
class SourceRangesAndDiagnosticsForQueryMessage; class SourceRangesAndDiagnosticsForQueryMessage;
class SourceRangesForQueryMessage;
class SourceLocationsContainer; class SourceLocationsContainer;
class CMBIPC_EXPORT RefactoringClientInterface : public IpcClientInterface class CMBIPC_EXPORT RefactoringClientInterface : public IpcClientInterface
@@ -47,6 +48,7 @@ public:
virtual void alive() = 0; virtual void alive() = 0;
virtual void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) = 0; virtual void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) = 0;
virtual void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) = 0; virtual void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) = 0;
virtual void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) = 0;
virtual void setLocalRenamingCallback(RenameCallback &&localRenamingCallback) = 0; virtual void setLocalRenamingCallback(RenameCallback &&localRenamingCallback) = 0;
}; };

View File

@@ -28,8 +28,7 @@
#include "cmbalivemessage.h" #include "cmbalivemessage.h"
#include "messageenvelop.h" #include "messageenvelop.h"
#include "refactoringserverinterface.h" #include "refactoringserverinterface.h"
#include "sourcelocationsforrenamingmessage.h" #include "clangrefactoringclientmessages.h"
#include "sourcerangesanddiagnosticsforquerymessage.h"
#include <QDebug> #include <QDebug>
#include <QIODevice> #include <QIODevice>
@@ -85,4 +84,9 @@ void RefactoringClientProxy::sourceRangesAndDiagnosticsForQueryMessage(SourceRan
writeMessageBlock.write(message); writeMessageBlock.write(message);
} }
void RefactoringClientProxy::sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message)
{
writeMessageBlock.write(message);
}
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -51,6 +51,7 @@ public:
void alive() override; void alive() override;
void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) override; void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) override;
void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) override; void sourceRangesAndDiagnosticsForQueryMessage(SourceRangesAndDiagnosticsForQueryMessage &&message) override;
void sourceRangesForQueryMessage(SourceRangesForQueryMessage &&message) override;
void setLocalRenamingCallback(RenameCallback &&) final {} void setLocalRenamingCallback(RenameCallback &&) final {}

View File

@@ -26,9 +26,7 @@
#include "refactoringserverinterface.h" #include "refactoringserverinterface.h"
#include "messageenvelop.h" #include "messageenvelop.h"
#include "requestsourcelocationforrenamingmessage.h" #include "clangrefactoringservermessages.h"
#include "requestsourcerangesanddiagnosticsforquerymessage.h"
#include "cancelmessage.h"
#include <QDebug> #include <QDebug>
@@ -46,6 +44,9 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop)
case MessageType::RequestSourceRangesAndDiagnosticsForQueryMessage: case MessageType::RequestSourceRangesAndDiagnosticsForQueryMessage:
requestSourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<RequestSourceRangesAndDiagnosticsForQueryMessage>()); requestSourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<RequestSourceRangesAndDiagnosticsForQueryMessage>());
break; break;
case MessageType::RequestSourceRangesForQueryMessage:
requestSourceRangesForQueryMessage(messageEnvelop.message<RequestSourceRangesForQueryMessage>());
break;
case MessageType::CancelMessage: case MessageType::CancelMessage:
cancel(); cancel();
break; break;

View File

@@ -34,6 +34,7 @@ namespace ClangBackEnd {
class RefactoringClientInterface; class RefactoringClientInterface;
class RequestSourceLocationsForRenamingMessage; class RequestSourceLocationsForRenamingMessage;
class RequestSourceRangesAndDiagnosticsForQueryMessage; class RequestSourceRangesAndDiagnosticsForQueryMessage;
class RequestSourceRangesForQueryMessage;
class CancelMessage; class CancelMessage;
class CMBIPC_EXPORT RefactoringServerInterface : public IpcServerInterface<RefactoringClientInterface> class CMBIPC_EXPORT RefactoringServerInterface : public IpcServerInterface<RefactoringClientInterface>
@@ -44,6 +45,7 @@ public:
virtual void end() = 0; virtual void end() = 0;
virtual void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) = 0; virtual void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) = 0;
virtual void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) = 0; virtual void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) = 0;
virtual void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) = 0;
virtual void cancel() = 0; virtual void cancel() = 0;
bool isUsable() const bool isUsable() const

View File

@@ -25,12 +25,9 @@
#include "refactoringserverproxy.h" #include "refactoringserverproxy.h"
#include "cancelmessage.h"
#include "cmbendmessage.h"
#include "messageenvelop.h" #include "messageenvelop.h"
#include "refactoringclientinterface.h" #include "refactoringclientinterface.h"
#include "requestsourcelocationforrenamingmessage.h" #include "clangrefactoringservermessages.h"
#include "requestsourcerangesanddiagnosticsforquerymessage.h"
#include <QIODevice> #include <QIODevice>
#include <QVector> #include <QVector>
@@ -60,6 +57,11 @@ void RefactoringServerProxy::requestSourceRangesAndDiagnosticsForQueryMessage(Re
writeMessageBlock.write(message); writeMessageBlock.write(message);
} }
void RefactoringServerProxy::requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message)
{
writeMessageBlock.write(message);
}
void RefactoringServerProxy::cancel() void RefactoringServerProxy::cancel()
{ {
writeMessageBlock.write(CancelMessage()); writeMessageBlock.write(CancelMessage());

View File

@@ -52,6 +52,7 @@ public:
void end() override; void end() override;
void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override; void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override; void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
void cancel() override; void cancel() override;
void readMessages(); void readMessages();

View File

@@ -31,7 +31,7 @@ QDebug operator<<(QDebug debug, const RequestSourceRangesAndDiagnosticsForQueryM
{ {
debug.nospace() << "RequestSourceRangesAndDiagnosticsForQuery(" debug.nospace() << "RequestSourceRangesAndDiagnosticsForQuery("
<< message.query() << ", " << message.query() << ", "
<< message.sources() << ")"; << message.source() << ")";
return debug; return debug;
} }
@@ -40,7 +40,7 @@ std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosti
{ {
os << "(" os << "("
<< message.query() << ", " << message.query() << ", "
<< message.sources() << message.source()
<< ")"; << ")";
return os; return os;

View File

@@ -34,32 +34,20 @@ class RequestSourceRangesAndDiagnosticsForQueryMessage
public: public:
RequestSourceRangesAndDiagnosticsForQueryMessage() = default; RequestSourceRangesAndDiagnosticsForQueryMessage() = default;
RequestSourceRangesAndDiagnosticsForQueryMessage(Utils::SmallString &&query, RequestSourceRangesAndDiagnosticsForQueryMessage(Utils::SmallString &&query,
std::vector<V2::FileContainer> &&sources, V2::FileContainer &&source)
std::vector<V2::FileContainer> &&unsavedContent)
: m_query(std::move(query)), : m_query(std::move(query)),
m_sources(std::move(sources)), m_source(std::move(source))
m_unsavedContent(std::move(unsavedContent))
{} {}
const std::vector<V2::FileContainer> &sources() const const V2::FileContainer &source() const
{ {
return m_sources; return m_source;
} }
std::vector<V2::FileContainer> takeSources() V2::FileContainer takeSource()
{ {
return std::move(m_sources); return std::move(m_source);
}
const std::vector<V2::FileContainer> &unsavedContent() const
{
return m_unsavedContent;
}
std::vector<V2::FileContainer> takeUnsavedContent()
{
return std::move(m_unsavedContent);
} }
const Utils::SmallString &query() const const Utils::SmallString &query() const
@@ -75,8 +63,7 @@ public:
friend QDataStream &operator<<(QDataStream &out, const RequestSourceRangesAndDiagnosticsForQueryMessage &message) friend QDataStream &operator<<(QDataStream &out, const RequestSourceRangesAndDiagnosticsForQueryMessage &message)
{ {
out << message.m_query; out << message.m_query;
out << message.m_sources; out << message.m_source;
out << message.m_unsavedContent;
return out; return out;
} }
@@ -84,8 +71,7 @@ public:
friend QDataStream &operator>>(QDataStream &in, RequestSourceRangesAndDiagnosticsForQueryMessage &message) friend QDataStream &operator>>(QDataStream &in, RequestSourceRangesAndDiagnosticsForQueryMessage &message)
{ {
in >> message.m_query; in >> message.m_query;
in >> message.m_sources; in >> message.m_source;
in >> message.m_unsavedContent;
return in; return in;
} }
@@ -94,26 +80,21 @@ public:
const RequestSourceRangesAndDiagnosticsForQueryMessage &second) const RequestSourceRangesAndDiagnosticsForQueryMessage &second)
{ {
return first.m_query == second.m_query return first.m_query == second.m_query
&& first.m_sources == second.m_sources && first.m_source == second.m_source;
&& first.m_unsavedContent == second.m_unsavedContent;
} }
RequestSourceRangesAndDiagnosticsForQueryMessage clone() const RequestSourceRangesAndDiagnosticsForQueryMessage clone() const
{ {
return RequestSourceRangesAndDiagnosticsForQueryMessage(m_query.clone(), return *this;
Utils::clone(m_sources),
Utils::clone(m_unsavedContent));
} }
private: private:
Utils::SmallString m_query; Utils::SmallString m_query;
std::vector<V2::FileContainer> m_sources; V2::FileContainer m_source;
std::vector<V2::FileContainer> m_unsavedContent;
}; };
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestSourceRangesAndDiagnosticsForQueryMessage &message); CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestSourceRangesAndDiagnosticsForQueryMessage &message);
std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosticsForQueryMessage &message); std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosticsForQueryMessage &message);
DECLARE_MESSAGE(RequestSourceRangesAndDiagnosticsForQueryMessage) DECLARE_MESSAGE(RequestSourceRangesAndDiagnosticsForQueryMessage)
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -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

View File

@@ -0,0 +1,117 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "filecontainerv2.h"
namespace ClangBackEnd {
class RequestSourceRangesForQueryMessage
{
public:
RequestSourceRangesForQueryMessage() = default;
RequestSourceRangesForQueryMessage(Utils::SmallString &&query,
std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsavedContent)
: m_query(std::move(query)),
m_sources(std::move(sources)),
m_unsavedContent(std::move(unsavedContent))
{}
const std::vector<V2::FileContainer> &sources() const
{
return m_sources;
}
std::vector<V2::FileContainer> takeSources()
{
return std::move(m_sources);
}
const std::vector<V2::FileContainer> &unsavedContent() const
{
return m_unsavedContent;
}
std::vector<V2::FileContainer> takeUnsavedContent()
{
return std::move(m_unsavedContent);
}
const Utils::SmallString &query() const
{
return m_query;
}
Utils::SmallString takeQuery()
{
return std::move(m_query);
}
friend QDataStream &operator<<(QDataStream &out, const RequestSourceRangesForQueryMessage &message)
{
out << message.m_query;
out << message.m_sources;
out << message.m_unsavedContent;
return out;
}
friend QDataStream &operator>>(QDataStream &in, RequestSourceRangesForQueryMessage &message)
{
in >> message.m_query;
in >> message.m_sources;
in >> message.m_unsavedContent;
return in;
}
friend bool operator==(const RequestSourceRangesForQueryMessage &first,
const RequestSourceRangesForQueryMessage &second)
{
return first.m_query == second.m_query
&& first.m_sources == second.m_sources
&& first.m_unsavedContent == second.m_unsavedContent;
}
RequestSourceRangesForQueryMessage clone() const
{
return *this;
}
private:
Utils::SmallString m_query;
std::vector<V2::FileContainer> m_sources;
std::vector<V2::FileContainer> m_unsavedContent;
};
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestSourceRangesForQueryMessage &message);
std::ostream &operator<<(std::ostream &os, const RequestSourceRangesForQueryMessage &message);
DECLARE_MESSAGE(RequestSourceRangesForQueryMessage)
} // namespace ClangBackEnd

View File

@@ -97,8 +97,14 @@ public:
{ {
return first.m_line != second.m_line return first.m_line != second.m_line
|| first.m_column != second.m_column || first.m_column != second.m_column
|| first.m_fileHash != second.m_fileHash || first.m_fileHash != second.m_fileHash;
|| first.m_offset != second.m_offset; }
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 SourceLocationContainer clone() const

View File

@@ -27,6 +27,8 @@
#include "sourcelocationcontainerv2.h" #include "sourcelocationcontainerv2.h"
#include <tuple>
namespace ClangBackEnd { namespace ClangBackEnd {
namespace V2 { namespace V2 {
@@ -89,6 +91,12 @@ public:
return first.m_start == second.m_start && first.m_end == second.m_end; 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 SourceRangeContainer clone() const
{ {
return SourceRangeContainer(m_start.clone(), m_end.clone()); return SourceRangeContainer(m_start.clone(), m_end.clone());
@@ -99,6 +107,8 @@ private:
SourceLocationContainer m_end; SourceLocationContainer m_end;
}; };
using SourceRangeContainers = std::vector<SourceRangeContainer>;
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangeContainer &container); CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangeContainer &container);
std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container); std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container);
} // namespace V2 } // namespace V2

View File

@@ -38,56 +38,61 @@ public:
SourceRangesAndDiagnosticsForQueryMessage() = default; SourceRangesAndDiagnosticsForQueryMessage() = default;
SourceRangesAndDiagnosticsForQueryMessage(SourceRangesContainer &&sourceRangesContainer, SourceRangesAndDiagnosticsForQueryMessage(SourceRangesContainer &&sourceRangesContainer,
std::vector<DynamicASTMatcherDiagnosticContainer> &&diagnosticContainers) std::vector<DynamicASTMatcherDiagnosticContainer> &&diagnosticContainers)
: sourceRangesContainer(std::move(sourceRangesContainer)), : m_sourceRangesContainer(std::move(sourceRangesContainer)),
diagnosticContainers(std::move(diagnosticContainers)) m_diagnosticContainers(std::move(diagnosticContainers))
{} {}
const SourceRangesContainer &sourceRanges() const const SourceRangesContainer &sourceRanges() const
{ {
return sourceRangesContainer; return m_sourceRangesContainer;
} }
SourceRangesContainer &sourceRanges() SourceRangesContainer &sourceRanges()
{ {
return sourceRangesContainer; return m_sourceRangesContainer;
} }
const std::vector<DynamicASTMatcherDiagnosticContainer> &diagnostics() const SourceRangesContainer takeSourceRanges()
{ {
return diagnosticContainers; return std::move(m_sourceRangesContainer);
}
const DynamicASTMatcherDiagnosticContainers &diagnostics() const
{
return m_diagnosticContainers;
} }
friend QDataStream &operator<<(QDataStream &out, const SourceRangesAndDiagnosticsForQueryMessage &message) friend QDataStream &operator<<(QDataStream &out, const SourceRangesAndDiagnosticsForQueryMessage &message)
{ {
out << message.sourceRangesContainer; out << message.m_sourceRangesContainer;
out << message.diagnosticContainers; out << message.m_diagnosticContainers;
return out; return out;
} }
friend QDataStream &operator>>(QDataStream &in, SourceRangesAndDiagnosticsForQueryMessage &message) friend QDataStream &operator>>(QDataStream &in, SourceRangesAndDiagnosticsForQueryMessage &message)
{ {
in >> message.sourceRangesContainer; in >> message.m_sourceRangesContainer;
in >> message.diagnosticContainers; in >> message.m_diagnosticContainers;
return in; return in;
} }
friend bool operator==(const SourceRangesAndDiagnosticsForQueryMessage &first, const SourceRangesAndDiagnosticsForQueryMessage &second) friend bool operator==(const SourceRangesAndDiagnosticsForQueryMessage &first, const SourceRangesAndDiagnosticsForQueryMessage &second)
{ {
return first.sourceRangesContainer == second.sourceRangesContainer return first.m_sourceRangesContainer == second.m_sourceRangesContainer
&& first.diagnosticContainers == second.diagnosticContainers; && first.m_diagnosticContainers == second.m_diagnosticContainers;
} }
SourceRangesAndDiagnosticsForQueryMessage clone() const SourceRangesAndDiagnosticsForQueryMessage clone() const
{ {
return SourceRangesAndDiagnosticsForQueryMessage(sourceRangesContainer.clone(), return SourceRangesAndDiagnosticsForQueryMessage(m_sourceRangesContainer.clone(),
Utils::clone(diagnosticContainers)); Utils::clone(m_diagnosticContainers));
} }
private: private:
SourceRangesContainer sourceRangesContainer; SourceRangesContainer m_sourceRangesContainer;
std::vector<DynamicASTMatcherDiagnosticContainer> diagnosticContainers; DynamicASTMatcherDiagnosticContainers m_diagnosticContainers;
}; };
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangesAndDiagnosticsForQueryMessage &message); CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangesAndDiagnosticsForQueryMessage &message);

View File

@@ -37,7 +37,7 @@ class SourceRangesContainer : public SourceFilePathContainerBase
public: public:
SourceRangesContainer() = default; SourceRangesContainer() = default;
SourceRangesContainer(std::unordered_map<uint, FilePath> &&filePathHash, SourceRangesContainer(std::unordered_map<uint, FilePath> &&filePathHash,
std::vector<SourceRangeWithTextContainer> &&sourceRangeWithTextContainers) SourceRangeWithTextContainers &&sourceRangeWithTextContainers)
: SourceFilePathContainerBase(std::move(filePathHash)), : SourceFilePathContainerBase(std::move(filePathHash)),
m_sourceRangeWithTextContainers(std::move(sourceRangeWithTextContainers)) m_sourceRangeWithTextContainers(std::move(sourceRangeWithTextContainers))
{} {}
@@ -49,21 +49,21 @@ public:
return found->second; return found->second;
} }
const std::vector<SourceRangeWithTextContainer> &sourceRangeWithTextContainers() const const SourceRangeWithTextContainers &sourceRangeWithTextContainers() const
{ {
return m_sourceRangeWithTextContainers; return m_sourceRangeWithTextContainers;
} }
std::vector<SourceRangeWithTextContainer> &sourceRangeWithTextContainers() SourceRangeWithTextContainers takeSourceRangeWithTextContainers()
{
return m_sourceRangeWithTextContainers;
}
std::vector<SourceRangeWithTextContainer> takeSourceRangeWithTextContainers()
{ {
return std::move(m_sourceRangeWithTextContainers); return std::move(m_sourceRangeWithTextContainers);
} }
void setSourceRangeWithTextContainers(SourceRangeWithTextContainers &&sourceRanges)
{
m_sourceRangeWithTextContainers = std::move(sourceRanges);
}
bool hasContent() const bool hasContent() const
{ {
return !m_sourceRangeWithTextContainers.empty(); return !m_sourceRangeWithTextContainers.empty();
@@ -117,10 +117,10 @@ public:
SourceRangesContainer clone() const SourceRangesContainer clone() const
{ {
return SourceRangesContainer(Utils::clone(m_filePathHash), Utils::clone(m_sourceRangeWithTextContainers)); return *this;
} }
std::vector<SourceRangeWithTextContainer> m_sourceRangeWithTextContainers; SourceRangeWithTextContainers m_sourceRangeWithTextContainers;
}; };

View File

@@ -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

View File

@@ -0,0 +1,85 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "sourcerangescontainer.h"
#include "dynamicastmatcherdiagnosticcontainer.h"
#include <utils/smallstring.h>
namespace ClangBackEnd {
class SourceRangesForQueryMessage
{
public:
SourceRangesForQueryMessage() = default;
SourceRangesForQueryMessage(SourceRangesContainer &&m_sourceRangesContainer)
: m_sourceRangesContainer(std::move(m_sourceRangesContainer))
{}
const SourceRangesContainer &sourceRanges() const
{
return m_sourceRangesContainer;
}
SourceRangesContainer &sourceRanges()
{
return m_sourceRangesContainer;
}
friend QDataStream &operator<<(QDataStream &out, const SourceRangesForQueryMessage &message)
{
out << message.m_sourceRangesContainer;
return out;
}
friend QDataStream &operator>>(QDataStream &in, SourceRangesForQueryMessage &message)
{
in >> message.m_sourceRangesContainer;
return in;
}
friend bool operator==(const SourceRangesForQueryMessage &first, const SourceRangesForQueryMessage &second)
{
return first.m_sourceRangesContainer == second.m_sourceRangesContainer;
}
SourceRangesForQueryMessage clone() const
{
return *this;
}
private:
SourceRangesContainer m_sourceRangesContainer;
};
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangesForQueryMessage &message);
std::ostream &operator<<(std::ostream &os, const SourceRangesForQueryMessage &message);
DECLARE_MESSAGE(SourceRangesForQueryMessage)
} // namespace ClangBackEnd

View File

@@ -31,7 +31,7 @@
namespace ClangBackEnd { namespace ClangBackEnd {
class SourceRangeWithTextContainer : V2::SourceRangeContainer class SourceRangeWithTextContainer : public V2::SourceRangeContainer
{ {
public: public:
SourceRangeWithTextContainer() = default; SourceRangeWithTextContainer() = default;
@@ -103,7 +103,7 @@ public:
SourceRangeWithTextContainer clone() const SourceRangeWithTextContainer clone() const
{ {
return SourceRangeWithTextContainer(base().clone(), m_text.clone()); return *this;
} }
private: private:
@@ -116,19 +116,3 @@ CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceRangeWithTextContainer
std::ostream &operator<<(std::ostream &os, const SourceRangeWithTextContainer &container); std::ostream &operator<<(std::ostream &os, const SourceRangeWithTextContainer &container);
} // namespace ClangBackEnd } // namespace ClangBackEnd
namespace std
{
template<> struct hash<ClangBackEnd::SourceRangeWithTextContainer>
{
using argument_type = ClangBackEnd::SourceRangeWithTextContainer;
using result_type = std::size_t;
result_type operator()(const argument_type &container) const
{
const result_type h1{std::hash<uint>{}(container.fileHash())};
const result_type h2{std::hash<uint>{}(container.start().offset())};
const result_type h3{std::hash<uint>{}(container.end().offset())};
return h1 ^ (h2 << 8) ^ (h3 << 16);
}
};
}

View File

@@ -0,0 +1,42 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "baseclangquerytexteditorwidget.h"
#include <texteditor/texteditorconstants.h>
namespace ClangRefactoring {
BaseClangQueryTextEditorWidget::BaseClangQueryTextEditorWidget(QWidget *parent)
: TextEditor::TextEditorWidget(parent)
{
setupFallBackEditor(Core::Id());
setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
setHighlightCurrentLine(false);
setLineNumbersVisible(false);
setParenthesesMatchingEnabled(true);
}
} // namespace ClangRefactoring

View File

@@ -0,0 +1,40 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <texteditor/texteditor.h>
namespace ClangRefactoring {
class BaseClangQueryTextEditorWidget : public TextEditor::TextEditorWidget
{
Q_OBJECT
public:
BaseClangQueryTextEditorWidget(QWidget *parent);
};
} // namespace ClangRefactoring

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "clangqueryexamplehighlighter.h"
#include <sourcerangescontainer.h>
#include <QTextBlock>
namespace ClangRefactoring {
ClangQueryExampleHighlighter::ClangQueryExampleHighlighter()
: m_marker(*this)
{
std::array<QTextCharFormat, 5> textFormats;
textFormats[0].setBackground(QColor("#c9ffc3"));
textFormats[1].setBackground(QColor("#c3d9ff"));
textFormats[2].setBackground(QColor("#e5c3ff"));
textFormats[3].setBackground(QColor("#ffc3cb"));
textFormats[4].setBackground(QColor("#ffe8c3"));
m_marker.setTextFormats(std::move(textFormats));
setNoAutomaticHighlighting(true);
}
void ClangQueryExampleHighlighter::setSourceRanges(ClangBackEnd::SourceRangesContainer &&container)
{
m_marker.setSourceRanges(container.takeSourceRangeWithTextContainers());
rehighlight();
}
void ClangQueryExampleHighlighter::highlightBlock(const QString &text)
{
int currentLineNumber = currentBlock().blockNumber() + 1;
m_marker.highlightBlock(uint(currentLineNumber), text);
}
} // namespace ClangRefactoring

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "clangqueryexamplehighlightmarker.h"
#include <texteditor/syntaxhighlighter.h>
#include <sourcerangewithtextcontainer.h>
namespace ClangBackEnd {
class SourceRangesContainer;
}
namespace ClangRefactoring {
class ClangQueryExampleHighlighter : public TextEditor::SyntaxHighlighter
{
friend ClangQueryExampleHighlightMarker<ClangQueryExampleHighlighter>;
public:
ClangQueryExampleHighlighter();
void setSourceRanges(ClangBackEnd::SourceRangesContainer &&container);
protected:
void highlightBlock(const QString &text) override;
private:
ClangQueryExampleHighlightMarker<ClangQueryExampleHighlighter> m_marker;
};
} // namespace ClangRefactoring

View File

@@ -0,0 +1,220 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <sourcerangewithtextcontainer.h>
#include <QString>
#include <QTextCharFormat>
namespace ClangRefactoring {
template<typename SyntaxHighlighter>
class ClangQueryExampleHighlightMarker
{
using SourceRange = ClangBackEnd::V2::SourceRangeContainer;
using SourceRanges = ClangBackEnd::V2::SourceRangeContainers;
using SourceRangeWithTexts = ClangBackEnd::SourceRangeWithTextContainers;
public:
ClangQueryExampleHighlightMarker(SourceRangeWithTexts &&sourceRanges,
SyntaxHighlighter &highlighter,
const std::array<QTextCharFormat, 5> &textFormats)
: m_sourceRanges(std::move(sourceRanges)),
m_currentSourceRangeIterator(m_sourceRanges.begin()),
m_highlighter(highlighter),
m_textFormats(textFormats)
{
}
ClangQueryExampleHighlightMarker(SyntaxHighlighter &highlighter)
: m_currentSourceRangeIterator(m_sourceRanges.begin()),
m_highlighter(highlighter)
{
}
void setTextFormats(std::array<QTextCharFormat, 5> &&textFormats)
{
m_textFormats = std::move(textFormats);
}
void setSourceRanges(SourceRangeWithTexts &&sourceRanges)
{
m_currentlyUsedSourceRanges.clear();
m_sourceRanges = std::move(sourceRanges);
m_currentSourceRangeIterator = m_sourceRanges.begin();
}
void highlightSourceRanges(uint currentLineNumber, const QString &currentText)
{
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 &currentText)
{
formatCurrentlyUsedSourceRanges(currentLineNumber, currentText.size());
popSourceRangeIfMultiLineEndsHereAndAllSourceRangesAreConsumed(currentLineNumber);
}
void highlightBlock(uint currentLineNumber, const QString &currentText)
{
popSourceRangeIfMultiLineEndedBefore(currentLineNumber);
highlightCurrentlyUsedSourceRanges(currentLineNumber, currentText);
highlightSourceRanges(currentLineNumber, currentText);
}
bool hasSourceRangesForCurrentLine(uint currentLineNumber) const
{
return m_currentSourceRangeIterator != m_sourceRanges.end()
&& m_currentSourceRangeIterator->start().line() == currentLineNumber;
}
bool hasOnlySCurrentlyUsedSourceRanges() const
{
return m_currentSourceRangeIterator == m_sourceRanges.end()
&& !m_currentlyUsedSourceRanges.empty();
}
void formatSingleSourceRange(const SourceRange &sourceRange,
int textFormatIndex)
{
int size = int(sourceRange.end().column() - sourceRange.start().column());
m_highlighter.setFormat(int(sourceRange.start().column()) - 1,
size,
m_textFormats[textFormatIndex]);
}
void formatStartMultipleSourceRange(const SourceRange &sourceRange,
int textSize,
int textFormatIndex)
{
int size = textSize - int(sourceRange.start().column()) + 1;
m_highlighter.setFormat(int(sourceRange.start().column()) - 1,
size,
m_textFormats[textFormatIndex]);
}
void formatEndMultipleSourceRange(const SourceRange &sourceRange,
int textFormatIndex)
{
int size = int(sourceRange.end().column()) - 1;
m_highlighter.setFormat(0, size, m_textFormats[textFormatIndex]);
}
void formatMiddleMultipleSourceRange(int textSize,
int textFormatIndex)
{
m_highlighter.setFormat(0, textSize, m_textFormats[textFormatIndex]);
}
void formatSourceRange(const SourceRange &sourceRange,
uint currentLineNumber,
int textSize,
int textFormatIndex)
{
if (sourceRange.start().line() == sourceRange.end().line())
formatSingleSourceRange(sourceRange, textFormatIndex);
else if (sourceRange.start().line() == currentLineNumber)
formatStartMultipleSourceRange(sourceRange, textSize, textFormatIndex);
else if (sourceRange.end().line() == currentLineNumber)
formatEndMultipleSourceRange(sourceRange, textFormatIndex);
else
formatMiddleMultipleSourceRange(textSize, textFormatIndex);
}
void formatCurrentlyUsedSourceRanges(uint currentLineNumber, int textSize)
{
int textFormatIndex = 0;
for (const SourceRange &sourceRange : m_currentlyUsedSourceRanges) {
formatSourceRange(sourceRange, currentLineNumber, textSize, textFormatIndex);
++textFormatIndex;
}
}
bool currentlyUsedHasEndLineAndColumnNumber(uint currentLineNumber, uint currentColumnNumber)
{
return !m_currentlyUsedSourceRanges.empty()
&& m_currentlyUsedSourceRanges.back().end().line() <= currentLineNumber
&& m_currentlyUsedSourceRanges.back().end().column() <= currentColumnNumber;
}
void popSourceRangeIfMultiLineEndsHere(uint currentLineNumber, uint currentColumnNumber)
{
while (currentlyUsedHasEndLineAndColumnNumber(currentLineNumber, currentColumnNumber))
m_currentlyUsedSourceRanges.pop_back();
}
bool currentlyUsedHasEndLineNumberAndSourceRangesAreConsumed(uint currentLineNumber)
{
return !m_currentlyUsedSourceRanges.empty()
&& m_currentSourceRangeIterator == m_sourceRanges.end()
&& m_currentlyUsedSourceRanges.back().end().line() == currentLineNumber;
}
void popSourceRangeIfMultiLineEndsHereAndAllSourceRangesAreConsumed(uint currentLineNumber)
{
while (currentlyUsedHasEndLineNumberAndSourceRangesAreConsumed(currentLineNumber))
m_currentlyUsedSourceRanges.pop_back();
}
bool currentlyUsedHasEndedBeforeLineNumber(uint currentLineNumber)
{
return !m_currentlyUsedSourceRanges.empty()
&& m_currentlyUsedSourceRanges.back().end().line() < currentLineNumber;
}
void popSourceRangeIfMultiLineEndedBefore(uint currentLineNumber)
{
while (currentlyUsedHasEndedBeforeLineNumber(currentLineNumber))
m_currentlyUsedSourceRanges.pop_back();
}
void pushSourceRangeIfMultiLine(SourceRange &sourceRange)
{
m_currentlyUsedSourceRanges.push_back(sourceRange);
}
private:
SourceRangeWithTexts m_sourceRanges;
SourceRangeWithTexts::iterator m_currentSourceRangeIterator;
SourceRanges m_currentlyUsedSourceRanges;
SyntaxHighlighter &m_highlighter;
std::array<QTextCharFormat, 5> m_textFormats;
};
} // namespace ClangRefactoring

View File

@@ -0,0 +1,46 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "clangqueryexampletexteditorwidget.h"
#include "clangqueryexamplehighlighter.h"
#include <texteditor/textdocument.h>
namespace ClangRefactoring {
ClangQueryExampleTextEditorWidget::ClangQueryExampleTextEditorWidget(QWidget *parent)
: BaseClangQueryTextEditorWidget(parent)
{
m_syntaxHighlighter = new ClangQueryExampleHighlighter;
textDocument()->setSyntaxHighlighter(m_syntaxHighlighter);
}
ClangQueryExampleHighlighter *ClangQueryExampleTextEditorWidget::syntaxHighlighter() const
{
return m_syntaxHighlighter;
}
} // namespace ClangRefactoring

View File

@@ -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

View File

@@ -0,0 +1,81 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "clangqueryhighlighter.h"
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorconstants.h>
#include <texteditor/texteditorsettings.h>
#include <QTextBlock>
namespace ClangRefactoring {
ClangQueryHighlighter::ClangQueryHighlighter()
: m_marker(*this)
{
#ifndef UNIT_TESTS
TextEditor::FontSettings fontSettings = TextEditor::TextEditorSettings::fontSettings();
m_marker.setTextFormats(fontSettings.toTextCharFormat(TextEditor::C_ERROR),
fontSettings.toTextCharFormat(TextEditor::C_ERROR_CONTEXT));
#endif
setNoAutomaticHighlighting(true);
}
void ClangQueryHighlighter::setDiagnostics(
const ClangBackEnd::DynamicASTMatcherDiagnosticContainers &diagnostics)
{
using Messages = ClangBackEnd::DynamicASTMatcherDiagnosticMessageContainers;
using Contexts = ClangBackEnd::DynamicASTMatcherDiagnosticContextContainers;
Messages messages;
Contexts contexts;
for (const ClangBackEnd::DynamicASTMatcherDiagnosticContainer &diagnostic : diagnostics) {
Messages newMessages = diagnostic.messages();
Contexts newContexts = diagnostic.contexts();
std::copy(newMessages.begin(), newMessages.end(), std::back_inserter(messages));
std::copy(newContexts.begin(), newContexts.end(), std::back_inserter(contexts));
}
m_marker.setMessagesAndContexts(std::move(messages), std::move(contexts));
rehighlight();
}
bool ClangQueryHighlighter::hasDiagnostics() const
{
return m_marker.hasMessagesOrContexts();
}
void ClangQueryHighlighter::highlightBlock(const QString &text)
{
int currentLineNumber = currentBlock().blockNumber() + 1;
m_marker.highlightBlock(uint(currentLineNumber), text);
}
} // namespace ClangRefactoring

View File

@@ -0,0 +1,54 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "clangqueryhighlightmarker.h"
#include <texteditor/syntaxhighlighter.h>
#include <dynamicastmatcherdiagnosticcontainer.h>
namespace ClangRefactoring {
class ClangQueryHighlighter : public TextEditor::SyntaxHighlighter
{
friend class ClangQueryHighlightMarker<ClangQueryHighlighter>;
public:
ClangQueryHighlighter();
void setDiagnostics(const ClangBackEnd::DynamicASTMatcherDiagnosticContainers &diagnostics);
bool hasDiagnostics() const;
protected:
void highlightBlock(const QString &text) override;
private:
ClangQueryHighlightMarker<ClangQueryHighlighter> m_marker;
};
} // namespace ClangRefactoring

View File

@@ -0,0 +1,266 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <dynamicastmatcherdiagnosticcontextcontainer.h>
#include <dynamicastmatcherdiagnosticmessagecontainer.h>
#include <sourcerangecontainerv2.h>
#include <QString>
#include <QTextCharFormat>
namespace ClangRefactoring {
template<typename SyntaxHighlighter>
class ClangQueryHighlightMarker
{
using SourceRange = ClangBackEnd::V2::SourceRangeContainer;
using Message = ClangBackEnd::DynamicASTMatcherDiagnosticMessageContainer;
using Context = ClangBackEnd::DynamicASTMatcherDiagnosticContextContainer;
using Messages = ClangBackEnd::DynamicASTMatcherDiagnosticMessageContainers;
using Contexts = ClangBackEnd::DynamicASTMatcherDiagnosticContextContainers;
public:
ClangQueryHighlightMarker(SyntaxHighlighter &highlighter)
: m_highlighter(highlighter)
{
}
void setTextFormats(const QTextCharFormat &messageTextFormat,
const QTextCharFormat &contextTextFormat)
{
m_contextTextFormat = contextTextFormat;
m_messageTextFormat = messageTextFormat;
}
void setMessagesAndContexts(Messages &&messages, Contexts &&contexts)
{
m_currentlyUsedContexts.clear();
m_currentlyUsedMessages.clear();
m_contexts = std::move(contexts);
m_messages = std::move(messages);
m_currentContextsIterator = m_contexts.begin();
m_currentMessagesIterator = m_messages.begin();
}
bool hasMessage(uint currentLineNumber) const
{
return m_currentMessagesIterator != m_messages.end()
&& m_currentMessagesIterator->sourceRange().start().line() == currentLineNumber;
}
bool hasContext(uint currentLineNumber) const
{
return m_currentContextsIterator != m_contexts.end()
&& m_currentContextsIterator->sourceRange().start().line() == currentLineNumber;
}
bool isMessageNext() const
{
return m_currentMessagesIterator->sourceRange().start().column()
< m_currentContextsIterator->sourceRange().start().column();
}
void formatSameLineSourceRange(const SourceRange &sourceRange, const QTextCharFormat &textFormat)
{
uint startColumn = sourceRange.start().column();
uint endColumn = sourceRange.end().column();
m_highlighter.setFormat(startColumn - 1, endColumn - startColumn, textFormat);
}
void formatStartLineSourceRange(const SourceRange &sourceRange,
int textSize,
const QTextCharFormat &textFormat)
{
uint startColumn = sourceRange.start().column();
m_highlighter.setFormat(startColumn - 1, textSize - startColumn, textFormat);
}
void formatEndLineSourceRange(const SourceRange &sourceRange, const QTextCharFormat &textFormat)
{
uint endColumn = sourceRange.end().column();
m_highlighter.setFormat(0, endColumn - 1, textFormat);
}
void formatMiddleLineSourceRange(int textSize, const QTextCharFormat &textFormat)
{
m_highlighter.setFormat(0, textSize, textFormat);
}
static
bool isSameLine(const SourceRange &sourceRange)
{
uint startLine = sourceRange.start().line();
uint endLine = sourceRange.end().line();
return startLine == endLine;
}
static
bool isStartLine(const SourceRange &sourceRange, uint currentLineNumber)
{
uint startLine = sourceRange.start().line();
return startLine == currentLineNumber;
}
static
bool isEndLine(const SourceRange &sourceRange, uint currentLineNumber)
{
uint endLine = sourceRange.end().line();
return endLine == currentLineNumber;
}
void formatLine(const SourceRange &sourceRange,
uint currentLineNumber,
int textSize,
const QTextCharFormat &textFormat)
{
if (isSameLine(sourceRange))
formatSameLineSourceRange(sourceRange, textFormat);
else if (isStartLine(sourceRange, currentLineNumber))
formatStartLineSourceRange(sourceRange, textSize, textFormat);
else if (isEndLine(sourceRange, currentLineNumber))
formatEndLineSourceRange(sourceRange, textFormat);
else
formatMiddleLineSourceRange(textSize, textFormat);
}
template<typename Container>
void format(Container &container,
typename Container::iterator &iterator,
uint currentLineNumber,
int textSize,
const QTextCharFormat &textFormat)
{
const SourceRange &sourceRange = iterator->sourceRange();
formatLine(sourceRange, currentLineNumber, textSize, textFormat);
if (isStartLine(sourceRange, currentLineNumber))
container.push_back(*iterator);
if (isSameLine(sourceRange) || isStartLine(sourceRange, currentLineNumber))
++iterator;
}
template<typename Container>
static
void removeEndedContainers(uint currentLineNumber, Container &container)
{
auto newEnd = std::remove_if(container.begin(),
container.end(),
[&] (const auto &entry) {
return ClangQueryHighlightMarker::isEndLine(entry.sourceRange(), currentLineNumber);
});
container.erase(newEnd, container.end());
}
template<typename Container>
void formatCurrentlyUsed(Container container,
uint currentLineNumber,
int textSize,
const QTextCharFormat &textFormat)
{
for (const auto &entry : container) {
formatLine(entry.sourceRange(), currentLineNumber, textSize, textFormat);;
}
}
void formatMessage(uint currentLineNumber, int textSize)
{
format(m_currentlyUsedMessages,
m_currentMessagesIterator,
currentLineNumber,
textSize,
m_messageTextFormat);
}
void formatContext(uint currentLineNumber, int textSize)
{
format(m_currentlyUsedContexts,
m_currentContextsIterator,
currentLineNumber,
textSize,
m_contextTextFormat);
}
void formatCurrentlyUsedMessagesAndContexts(uint currentLineNumber, int textSize)
{
formatCurrentlyUsed(m_currentlyUsedContexts, currentLineNumber, textSize, m_contextTextFormat);
formatCurrentlyUsed(m_currentlyUsedMessages, currentLineNumber, textSize, m_messageTextFormat);
removeEndedContainers(currentLineNumber, m_currentlyUsedContexts);
removeEndedContainers(currentLineNumber, m_currentlyUsedMessages);
}
void formatCurrentMessageOrContext(uint currentLineNumber, int textSize)
{
bool hasContext = this->hasContext(currentLineNumber);
bool hasMessage = this->hasMessage(currentLineNumber);
while (hasContext || hasMessage) {
if (!hasContext)
formatMessage(currentLineNumber, textSize);
else if (!hasMessage)
formatContext(currentLineNumber, textSize);
else if (isMessageNext())
formatMessage(currentLineNumber, textSize);
else
formatContext(currentLineNumber, textSize);
hasContext = this->hasContext(currentLineNumber);
hasMessage = this->hasMessage(currentLineNumber);
}
}
void highlightBlock(uint currentLineNumber, const QString &currentText)
{
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

View File

@@ -30,20 +30,23 @@
#include "searchinterface.h" #include "searchinterface.h"
#include <refactoringserverinterface.h> #include <refactoringserverinterface.h>
#include <requestsourcerangesanddiagnosticsforquerymessage.h> #include <clangrefactoringservermessages.h>
#include <cpptools/clangcompileroptionsbuilder.h> #include <cpptools/clangcompileroptionsbuilder.h>
#include <QPointer>
namespace ClangRefactoring { namespace ClangRefactoring {
ClangQueryProjectsFindFilter::ClangQueryProjectsFindFilter( ClangQueryProjectsFindFilter::ClangQueryProjectsFindFilter(
ClangBackEnd::RefactoringServerInterface &server, ClangBackEnd::RefactoringServerInterface &server,
SearchInterface &searchInterface, SearchInterface &searchInterface,
RefactoringClient &refactoringClient) RefactoringClient &refactoringClient)
: server(server), : m_server(server),
searchInterface(searchInterface), m_searchInterface(searchInterface),
refactoringClient(refactoringClient) m_refactoringClient(refactoringClient)
{ {
temporaryFile.open();
} }
QString ClangQueryProjectsFindFilter::id() const QString ClangQueryProjectsFindFilter::id() const
@@ -61,19 +64,57 @@ bool ClangQueryProjectsFindFilter::isEnabled() const
return true; 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;
searchHandle->setRefactoringServer(&server); #ifdef Q_OS_WIN
nativePath.replace('/', '\\');
#endif
refactoringClient.setSearchHandle(searchHandle.get()); return nativePath;
}
}
void ClangQueryProjectsFindFilter::requestSourceRangesAndDiagnostics(const QString &queryText,
const QString &exampleContent)
{
const QString filePath = temporaryFile.fileName();
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); auto message = createMessage(queryText);
refactoringClient.setExpectedResultCount(uint(message.sources().size())); m_refactoringClient.setExpectedResultCount(uint(message.sources().size()));
server.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message)); m_server.requestSourceRangesForQueryMessage(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 Core::FindFlags ClangQueryProjectsFindFilter::supportedFindFlags() const
@@ -83,28 +124,28 @@ Core::FindFlags ClangQueryProjectsFindFilter::supportedFindFlags() const
void ClangQueryProjectsFindFilter::setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts) void ClangQueryProjectsFindFilter::setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts)
{ {
this->projectParts = projectParts; this->m_projectParts = projectParts;
} }
bool ClangQueryProjectsFindFilter::isUsable() const bool ClangQueryProjectsFindFilter::isUsable() const
{ {
return server.isUsable(); return m_server.isUsable();
} }
void ClangQueryProjectsFindFilter::setUsable(bool isUsable) void ClangQueryProjectsFindFilter::setUsable(bool isUsable)
{ {
server.setUsable(isUsable); m_server.setUsable(isUsable);
} }
SearchHandle *ClangQueryProjectsFindFilter::searchHandleForTestOnly() const SearchHandle *ClangQueryProjectsFindFilter::searchHandleForTestOnly() const
{ {
return searchHandle.get(); return m_searchHandle.get();
} }
void ClangQueryProjectsFindFilter::setUnsavedContent( void ClangQueryProjectsFindFilter::setUnsavedContent(
std::vector<ClangBackEnd::V2::FileContainer> &&unsavedContent) std::vector<ClangBackEnd::V2::FileContainer> &&unsavedContent)
{ {
this->unsavedContent = std::move(unsavedContent); this->m_unsavedContent = std::move(unsavedContent);
} }
Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTools::ProjectPart *projectPart, Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTools::ProjectPart *projectPart,
@@ -141,6 +182,11 @@ Utils::SmallStringVector ClangQueryProjectsFindFilter::compilerArguments(CppTool
return Utils::SmallStringVector(builder.options()); return Utils::SmallStringVector(builder.options());
} }
QWidget *ClangQueryProjectsFindFilter::widget() const
{
return nullptr;
}
namespace { namespace {
Utils::SmallStringVector createCommandLine(CppTools::ProjectPart *projectPart, Utils::SmallStringVector createCommandLine(CppTools::ProjectPart *projectPart,
@@ -205,12 +251,22 @@ createSources(const std::vector<CppTools::ProjectPart::Ptr> &projectParts,
} }
ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage ClangQueryProjectsFindFilter::createMessage(const QString &queryText) const ClangBackEnd::RequestSourceRangesForQueryMessage ClangQueryProjectsFindFilter::createMessage(const QString &queryText) const
{ {
return ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage( return ClangBackEnd::RequestSourceRangesForQueryMessage(
Utils::SmallString(queryText), Utils::SmallString(queryText),
createSources(projectParts, unsavedContent), createSources(m_projectParts, m_unsavedContent),
Utils::clone(unsavedContent)); Utils::clone(m_unsavedContent));
}
QString ClangQueryProjectsFindFilter::queryText() const
{
return QString();
}
RefactoringClient &ClangQueryProjectsFindFilter::refactoringClient()
{
return m_refactoringClient;
} }

View File

@@ -34,6 +34,7 @@
#include <filecontainerv2.h> #include <filecontainerv2.h>
#include <utils/smallstringvector.h> #include <utils/smallstringvector.h>
#include <utils/temporaryfile.h>
#include <memory> #include <memory>
@@ -54,35 +55,44 @@ public:
SearchInterface &searchInterface, SearchInterface &searchInterface,
RefactoringClient &refactoringClient); RefactoringClient &refactoringClient);
QString id() const; QString id() const override;
QString displayName() const; QString displayName() const override;
bool isEnabled() const; bool isEnabled() const override;
void findAll(const QString &queryText, Core::FindFlags findFlags = 0); void requestSourceRangesAndDiagnostics(const QString &queryText, const QString &exampleContent);
Core::FindFlags supportedFindFlags() const; SearchHandle *find(const QString &queryText);
void findAll(const QString &queryText, Core::FindFlags findFlags = 0) override;
bool showSearchTermInput() const override;
Core::FindFlags supportedFindFlags() const override;
void setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts); void setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &m_projectParts);
bool isUsable() const; bool isUsable() const;
void setUsable(bool isUsable); void setUsable(bool isUsable);
SearchHandle* searchHandleForTestOnly() const; SearchHandle* searchHandleForTestOnly() const;
void setUnsavedContent(std::vector<ClangBackEnd::V2::FileContainer> &&unsavedContent); void setUnsavedContent(std::vector<ClangBackEnd::V2::FileContainer> &&m_unsavedContent);
static Utils::SmallStringVector compilerArguments(CppTools::ProjectPart *projectPart, static Utils::SmallStringVector compilerArguments(CppTools::ProjectPart *projectPart,
CppTools::ProjectFile::Kind fileKind); CppTools::ProjectFile::Kind fileKind);
protected:
virtual QWidget *widget() const;
virtual QString queryText() const;
RefactoringClient &refactoringClient();
private: private:
ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage createMessage( ClangBackEnd::RequestSourceRangesForQueryMessage createMessage(
const QString &queryText) const; const QString &queryText) const;
private: private:
std::vector<ClangBackEnd::V2::FileContainer> unsavedContent; std::vector<ClangBackEnd::V2::FileContainer> m_unsavedContent;
std::unique_ptr<SearchHandle> searchHandle; std::unique_ptr<SearchHandle> m_searchHandle;
std::vector<CppTools::ProjectPart::Ptr> projectParts; std::vector<CppTools::ProjectPart::Ptr> m_projectParts;
ClangBackEnd::RefactoringServerInterface &server; Utils::TemporaryFile temporaryFile{"clangQuery-XXXXXX.cpp"};
SearchInterface &searchInterface; ClangBackEnd::RefactoringServerInterface &m_server;
RefactoringClient &refactoringClient; SearchInterface &m_searchInterface;
RefactoringClient &m_refactoringClient;
}; };
} // namespace ClangRefactoring } // namespace ClangRefactoring

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1241</width>
<height>471</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="ClangRefactoring::ClangQueryExampleTextEditorWidget" name="exampleSourceTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>3</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="ClangRefactoring::ClangQueryTextEditorWidget" name="queryTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ClangRefactoring::ClangQueryExampleTextEditorWidget</class>
<extends>QPlainTextEdit</extends>
<header>clangqueryexampletexteditorwidget.h</header>
</customwidget>
<customwidget>
<class>ClangRefactoring::ClangQueryTextEditorWidget</class>
<extends>QPlainTextEdit</extends>
<header>clangquerytexteditorwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "clangqueryprojectsfindfilterwidget.h"
#include "clangqueryhighlighter.h"
#include <texteditor/textdocument.h>
#include <QTextDocument>
namespace ClangRefactoring {
ClangQueryProjectsFindFilterWidget::ClangQueryProjectsFindFilterWidget()
{
m_form.setupUi(this);
}
QPlainTextEdit *ClangQueryProjectsFindFilterWidget::queryTextEdit() const
{
return m_form.queryTextEdit;
}
QPlainTextEdit *ClangQueryProjectsFindFilterWidget::queryExampleTextEdit() const
{
return m_form.exampleSourceTextEdit;
}
ClangQueryExampleHighlighter *ClangQueryProjectsFindFilterWidget::clangQueryExampleHighlighter() const
{
return m_form.exampleSourceTextEdit->syntaxHighlighter();
}
ClangQueryHighlighter *ClangQueryProjectsFindFilterWidget::clangQueryHighlighter() const
{
return m_form.queryTextEdit->syntaxHighlighter();
}
bool ClangQueryProjectsFindFilterWidget::isValid() const
{
return !m_form.queryTextEdit->textDocument()->document()->isEmpty()
&& !clangQueryHighlighter()->hasDiagnostics();
}
} // namespace ClangRefactoring

View File

@@ -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

View File

@@ -0,0 +1,47 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "clangquerytexteditorwidget.h"
#include "clangqueryhighlighter.h"
#include <texteditor/textdocument.h>
namespace ClangRefactoring {
ClangQueryTextEditorWidget::ClangQueryTextEditorWidget(QWidget *parent)
: BaseClangQueryTextEditorWidget(parent)
{
m_syntaxHighlighter = new ClangQueryHighlighter;
textDocument()->setSyntaxHighlighter(m_syntaxHighlighter);
}
ClangQueryHighlighter *ClangQueryTextEditorWidget::syntaxHighlighter() const
{
return m_syntaxHighlighter;
}
} // namespace ClangRefactoring

View File

@@ -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

View File

@@ -7,7 +7,11 @@ HEADERS += \
$$PWD/searchinterface.h \ $$PWD/searchinterface.h \
$$PWD/searchhandle.h \ $$PWD/searchhandle.h \
$$PWD/projectpartutilities.h \ $$PWD/projectpartutilities.h \
$$PWD/clangqueryprojectsfindfilter.h $$PWD/clangqueryprojectsfindfilter.h \
$$PWD/clangqueryexamplehighlightmarker.h \
$$PWD/clangqueryhighlightmarker.h \
$$PWD/clangqueryexamplehighlighter.h \
$$PWD/clangqueryhighlighter.h
SOURCES += \ SOURCES += \
$$PWD/refactoringengine.cpp \ $$PWD/refactoringengine.cpp \
@@ -16,4 +20,6 @@ SOURCES += \
$$PWD/searchinterface.cpp \ $$PWD/searchinterface.cpp \
$$PWD/searchhandle.cpp \ $$PWD/searchhandle.cpp \
$$PWD/projectpartutilities.cpp \ $$PWD/projectpartutilities.cpp \
$$PWD/clangqueryprojectsfindfilter.cpp $$PWD/clangqueryprojectsfindfilter.cpp \
$$PWD/clangqueryexamplehighlighter.cpp \
$$PWD/clangqueryhighlighter.cpp

View File

@@ -7,13 +7,24 @@ include(../../shared/clang/clang_defines.pri)
requires(!isEmpty(LIBTOOLING_LIBS)) requires(!isEmpty(LIBTOOLING_LIBS))
HEADERS += \ HEADERS += \
$$PWD/clangrefactoringplugin.h \ clangrefactoringplugin.h \
qtcreatorsearch.h \ qtcreatorsearch.h \
qtcreatorsearchhandle.h \ qtcreatorsearchhandle.h \
qtcreatorclangqueryfindfilter.h qtcreatorclangqueryfindfilter.h \
clangqueryprojectsfindfilterwidget.h \
clangqueryexampletexteditorwidget.h \
clangquerytexteditorwidget.h \
baseclangquerytexteditorwidget.h
SOURCES += \ SOURCES += \
$$PWD/clangrefactoringplugin.cpp \ clangrefactoringplugin.cpp \
qtcreatorsearch.cpp \ qtcreatorsearch.cpp \
qtcreatorsearchhandle.cpp \ qtcreatorsearchhandle.cpp \
qtcreatorclangqueryfindfilter.cpp qtcreatorclangqueryfindfilter.cpp \
clangqueryprojectsfindfilterwidget.cpp \
clangqueryexampletexteditorwidget.cpp \
clangquerytexteditorwidget.cpp \
baseclangquerytexteditorwidget.cpp
FORMS += \
clangqueryprojectsfindfilter.ui

View File

@@ -25,6 +25,9 @@
#include "qtcreatorclangqueryfindfilter.h" #include "qtcreatorclangqueryfindfilter.h"
#include "clangqueryprojectsfindfilterwidget.h"
#include "refactoringclient.h"
#include <cpptools/abstracteditorsupport.h> #include <cpptools/abstracteditorsupport.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cpptools/projectinfo.h> #include <cpptools/projectinfo.h>
@@ -49,13 +52,61 @@ void QtCreatorClangQueryFindFilter::findAll(const QString &queryText, Core::Find
ClangQueryProjectsFindFilter::findAll(queryText, findFlags); 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 { namespace {
std::vector<ClangBackEnd::V2::FileContainer> createUnsavedContents() std::vector<ClangBackEnd::V2::FileContainer> createUnsavedContents()
{ {
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports(); auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
std::vector<ClangBackEnd::V2::FileContainer> unsavedContents; std::vector<ClangBackEnd::V2::FileContainer> unsavedContents;
unsavedContents.reserve(abstractEditors.size()); unsavedContents.reserve(std::size_t(abstractEditors.size()));
auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) { auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()), return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),

View File

@@ -27,19 +27,38 @@
#include "clangqueryprojectsfindfilter.h" #include "clangqueryprojectsfindfilter.h"
#include <QPointer>
namespace ClangRefactoring { namespace ClangRefactoring {
class ClangQueryProjectsFindFilterWidget;
class QtCreatorClangQueryFindFilter final : public ClangQueryProjectsFindFilter class QtCreatorClangQueryFindFilter final : public ClangQueryProjectsFindFilter
{ {
public: public:
QtCreatorClangQueryFindFilter(ClangBackEnd::RefactoringServerInterface &server, QtCreatorClangQueryFindFilter(ClangBackEnd::RefactoringServerInterface &m_server,
SearchInterface &searchInterface, SearchInterface &m_searchInterface,
RefactoringClient &refactoringClient); RefactoringClient &m_refactoringClient);
void findAll(const QString &queryText, Core::FindFlags findFlags = 0) override; 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: private:
void prepareFind(); void prepareFind();
private:
QPointer<ClangQueryProjectsFindFilterWidget> m_widget;
}; };
} // namespace ClangRefactoring } // namespace ClangRefactoring

View File

@@ -25,32 +25,40 @@
#include "refactoringclient.h" #include "refactoringclient.h"
#include "clangqueryhighlighter.h"
#include "clangqueryexamplehighlighter.h"
#include <refactoringconnectionclient.h> #include <refactoringconnectionclient.h>
#include <sourcelocationsforrenamingmessage.h> #include <clangrefactoringmessages.h>
#include <sourcerangesanddiagnosticsforquerymessage.h>
namespace ClangRefactoring { namespace ClangRefactoring {
void RefactoringClient::alive() void RefactoringClient::alive()
{ {
if (connectionClient) if (m_connectionClient)
connectionClient->resetProcessAliveTimer(); m_connectionClient->resetProcessAliveTimer();
} }
void RefactoringClient::sourceLocationsForRenamingMessage( void RefactoringClient::sourceLocationsForRenamingMessage(
ClangBackEnd::SourceLocationsForRenamingMessage &&message) ClangBackEnd::SourceLocationsForRenamingMessage &&message)
{ {
localRenamingCallback(message.symbolName().toQString(), m_localRenamingCallback(message.symbolName().toQString(),
message.sourceLocations(), message.sourceLocations(),
message.textDocumentRevision()); message.textDocumentRevision());
refactoringEngine->setUsable(true); m_refactoringEngine->setUsable(true);
} }
void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage( void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage(
ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) 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()); addSearchResults(message.sourceRanges());
setResultCounterAndSendSearchIsFinishedIfFinished(); setResultCounterAndSendSearchIsFinishedIfFinished();
} }
@@ -58,50 +66,60 @@ void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage(
void RefactoringClient::setLocalRenamingCallback( void RefactoringClient::setLocalRenamingCallback(
CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback)
{ {
this->localRenamingCallback = std::move(localRenamingCallback); m_localRenamingCallback = std::move(localRenamingCallback);
} }
void RefactoringClient::setRefactoringEngine(RefactoringEngine *refactoringEngine) void RefactoringClient::setRefactoringEngine(RefactoringEngine *refactoringEngine)
{ {
this->refactoringEngine = refactoringEngine; m_refactoringEngine = refactoringEngine;
} }
void RefactoringClient::setSearchHandle(SearchHandle *searchHandle) void RefactoringClient::setSearchHandle(SearchHandle *searchHandle)
{ {
this->searchHandle_ = searchHandle; m_searchHandle = searchHandle;
} }
SearchHandle *RefactoringClient::searchHandle() const 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 bool RefactoringClient::hasValidLocalRenamingCallback() const
{ {
return bool(localRenamingCallback); return bool(m_localRenamingCallback);
} }
void RefactoringClient::setExpectedResultCount(uint count) void RefactoringClient::setExpectedResultCount(uint count)
{ {
expectedResultCount_ = count; m_expectedResultCount = count;
resultCounter_ = 0; m_resultCounter = 0;
searchHandle_->setExpectedResultCount(count); m_searchHandle->setExpectedResultCount(count);
} }
uint RefactoringClient::expectedResultCount() const uint RefactoringClient::expectedResultCount() const
{ {
return expectedResultCount_; return m_expectedResultCount;
} }
uint RefactoringClient::resultCounter() const uint RefactoringClient::resultCounter() const
{ {
return resultCounter_; return m_resultCounter;
} }
void RefactoringClient::setRefactoringConnectionClient( void RefactoringClient::setRefactoringConnectionClient(
ClangBackEnd::RefactoringConnectionClient *connectionClient) ClangBackEnd::RefactoringConnectionClient *connectionClient)
{ {
this->connectionClient = connectionClient; m_connectionClient = connectionClient;
} }
std::unordered_map<uint, QString> RefactoringClient::convertFilePaths( std::unordered_map<uint, QString> RefactoringClient::convertFilePaths(
@@ -135,7 +153,7 @@ void RefactoringClient::addSearchResults(const ClangBackEnd::SourceRangesContain
void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText, void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText,
std::unordered_map<uint, QString> &filePaths) std::unordered_map<uint, QString> &filePaths)
{ {
searchHandle_->addResult(filePaths[sourceRangeWithText.fileHash()], m_searchHandle->addResult(filePaths[sourceRangeWithText.fileHash()],
sourceRangeWithText.text(), sourceRangeWithText.text(),
{{int(sourceRangeWithText.start().line()), {{int(sourceRangeWithText.start().line()),
int(sourceRangeWithText.start().column() - 1), int(sourceRangeWithText.start().column() - 1),
@@ -147,9 +165,9 @@ void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextC
void RefactoringClient::setResultCounterAndSendSearchIsFinishedIfFinished() void RefactoringClient::setResultCounterAndSendSearchIsFinishedIfFinished()
{ {
searchHandle_->setResultCounter(resultCounter_); m_searchHandle->setResultCounter(m_resultCounter);
if (resultCounter_ == expectedResultCount_) if (m_resultCounter == m_expectedResultCount)
searchHandle_->finishSearch(); m_searchHandle->finishSearch();
} }
} // namespace ClangRefactoring } // namespace ClangRefactoring

View File

@@ -42,6 +42,9 @@ class SourceRangeWithTextContainer;
namespace ClangRefactoring { namespace ClangRefactoring {
class ClangQueryExampleHighlighter;
class ClangQueryHighlighter;
class RefactoringClient final : public ClangBackEnd::RefactoringClientInterface class RefactoringClient final : public ClangBackEnd::RefactoringClientInterface
{ {
public: public:
@@ -50,12 +53,16 @@ public:
ClangBackEnd::SourceLocationsForRenamingMessage &&message) override; ClangBackEnd::SourceLocationsForRenamingMessage &&message) override;
void sourceRangesAndDiagnosticsForQueryMessage( void sourceRangesAndDiagnosticsForQueryMessage(
ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) override; ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) override;
void sourceRangesForQueryMessage(
ClangBackEnd::SourceRangesForQueryMessage &&message) override;
void setLocalRenamingCallback( void setLocalRenamingCallback(
CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) override; CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) override;
void setRefactoringEngine(ClangRefactoring::RefactoringEngine *refactoringEngine); void setRefactoringEngine(ClangRefactoring::RefactoringEngine *refactoringEngine);
void setSearchHandle(ClangRefactoring::SearchHandle *searchHandleInterface); void setSearchHandle(ClangRefactoring::SearchHandle *searchHandleInterface);
ClangRefactoring::SearchHandle *searchHandle() const; ClangRefactoring::SearchHandle *searchHandle() const;
void setClangQueryExampleHighlighter(ClangQueryExampleHighlighter *highlighter);
void setClangQueryHighlighter(ClangQueryHighlighter *highlighter);
bool hasValidLocalRenamingCallback() const; bool hasValidLocalRenamingCallback() const;
@@ -79,12 +86,14 @@ private:
void sendSearchIsFinished(); void sendSearchIsFinished();
private: private:
CppTools::RefactoringEngineInterface::RenameCallback localRenamingCallback; CppTools::RefactoringEngineInterface::RenameCallback m_localRenamingCallback;
ClangBackEnd::RefactoringConnectionClient *connectionClient = nullptr; ClangBackEnd::RefactoringConnectionClient *m_connectionClient = nullptr;
ClangRefactoring::SearchHandle *searchHandle_ = nullptr; SearchHandle *m_searchHandle = nullptr;
ClangRefactoring::RefactoringEngine *refactoringEngine = nullptr; RefactoringEngine *m_refactoringEngine = nullptr;
uint expectedResultCount_ = 0; ClangQueryExampleHighlighter *m_clangQueryExampleHighlighter = nullptr;
uint resultCounter_ = 0; ClangQueryHighlighter *m_clangQueryHighlighter = nullptr;
uint m_expectedResultCount = 0;
uint m_resultCounter = 0;
}; };
} // namespace ClangRefactoring } // namespace ClangRefactoring

View File

@@ -41,8 +41,8 @@ ClangQueryGatherer::ClangQueryGatherer(StringCache<Utils::PathString, std::mutex
{ {
} }
SourceRangesAndDiagnosticsForQueryMessage SourceRangesForQueryMessage
ClangQueryGatherer::createSourceRangesAndDiagnosticsForSource( ClangQueryGatherer::createSourceRangesForSource(
StringCache<Utils::PathString, std::mutex> *filePathCache, StringCache<Utils::PathString, std::mutex> *filePathCache,
V2::FileContainer &&source, V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved, const std::vector<V2::FileContainer> &unsaved,
@@ -59,29 +59,29 @@ ClangQueryGatherer::createSourceRangesAndDiagnosticsForSource(
clangQuery.findLocations(); clangQuery.findLocations();
return {clangQuery.takeSourceRanges(), clangQuery.takeDiagnosticContainers()}; return {clangQuery.takeSourceRanges()};
} }
bool ClangQueryGatherer::canCreateSourceRangesAndDiagnostics() const bool ClangQueryGatherer::canCreateSourceRanges() const
{ {
return !m_sources.empty(); return !m_sources.empty();
} }
SourceRangesAndDiagnosticsForQueryMessage ClangQueryGatherer::createNextSourceRangesAndDiagnostics() SourceRangesForQueryMessage ClangQueryGatherer::createNextSourceRanges()
{ {
auto message = createSourceRangesAndDiagnosticsForSource(m_filePathCache, auto message = createSourceRangesForSource(m_filePathCache,
std::move(m_sources.back()), std::move(m_sources.back()),
m_unsaved, m_unsaved,
m_query.clone()); m_query.clone());
m_sources.pop_back(); m_sources.pop_back();
return message; return message;
} }
ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesAndDiagnosticsMessage() ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesMessage()
{ {
Future future = std::async(std::launch::async, Future future = std::async(std::launch::async,
createSourceRangesAndDiagnosticsForSource, createSourceRangesForSource,
m_filePathCache, m_filePathCache,
std::move(m_sources.back()), std::move(m_sources.back()),
m_unsaved, m_unsaved,
@@ -92,12 +92,12 @@ ClangQueryGatherer::Future ClangQueryGatherer::startCreateNextSourceRangesAndDia
return future; return future;
} }
void ClangQueryGatherer::startCreateNextSourceRangesAndDiagnosticsMessages() void ClangQueryGatherer::startCreateNextSourceRangesMessages()
{ {
std::vector<ClangQueryGatherer::Future> futures; std::vector<ClangQueryGatherer::Future> futures;
while (!m_sources.empty() && m_sourceFutures.size() < m_processingSlotCount) while (!m_sources.empty() && m_sourceFutures.size() < m_processingSlotCount)
m_sourceFutures.push_back(startCreateNextSourceRangesAndDiagnosticsMessage()); m_sourceFutures.push_back(startCreateNextSourceRangesMessage());
} }
void ClangQueryGatherer::waitForFinished() void ClangQueryGatherer::waitForFinished()
@@ -121,9 +121,9 @@ const std::vector<ClangQueryGatherer::Future> &ClangQueryGatherer::sourceFutures
return m_sourceFutures; return m_sourceFutures;
} }
std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::allCurrentProcessedMessages() std::vector<SourceRangesForQueryMessage> ClangQueryGatherer::allCurrentProcessedMessages()
{ {
std::vector<SourceRangesAndDiagnosticsForQueryMessage> messages; std::vector<SourceRangesForQueryMessage> messages;
for (Future &future : m_sourceFutures) for (Future &future : m_sourceFutures)
messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get())); messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get()));
@@ -131,9 +131,9 @@ std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::allCu
return messages; return messages;
} }
std::vector<SourceRangesAndDiagnosticsForQueryMessage> ClangQueryGatherer::finishedMessages() std::vector<SourceRangesForQueryMessage> ClangQueryGatherer::finishedMessages()
{ {
std::vector<SourceRangesAndDiagnosticsForQueryMessage> messages; std::vector<SourceRangesForQueryMessage> messages;
for (auto &&future : finishedFutures()) for (auto &&future : finishedFutures())
messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get())); messages.push_back(m_sourceRangeFilter.removeDuplicates(future.get()));

View File

@@ -27,7 +27,7 @@
#include "sourcerangefilter.h" #include "sourcerangefilter.h"
#include <sourcerangesanddiagnosticsforquerymessage.h> #include <sourcerangesforquerymessage.h>
#include <filecontainerv2.h> #include <filecontainerv2.h>
#include <stringcache.h> #include <stringcache.h>
@@ -38,7 +38,7 @@ namespace ClangBackEnd {
class ClangQueryGatherer class ClangQueryGatherer
{ {
public: public:
using Future = std::future<SourceRangesAndDiagnosticsForQueryMessage>; using Future = std::future<SourceRangesForQueryMessage>;
ClangQueryGatherer() = default; ClangQueryGatherer() = default;
ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache, ClangQueryGatherer(StringCache<Utils::PathString, std::mutex> *filePathCache,
@@ -46,22 +46,22 @@ public:
std::vector<V2::FileContainer> &&unsaved, std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query); Utils::SmallString &&query);
static SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForSource( static SourceRangesForQueryMessage createSourceRangesForSource(
StringCache<Utils::PathString, std::mutex> *filePathCache, StringCache<Utils::PathString, std::mutex> *filePathCache,
V2::FileContainer &&source, V2::FileContainer &&source,
const std::vector<V2::FileContainer> &unsaved, const std::vector<V2::FileContainer> &unsaved,
Utils::SmallString &&query); Utils::SmallString &&query);
bool canCreateSourceRangesAndDiagnostics() const; bool canCreateSourceRanges() const;
SourceRangesAndDiagnosticsForQueryMessage createNextSourceRangesAndDiagnostics(); SourceRangesForQueryMessage createNextSourceRanges();
Future startCreateNextSourceRangesAndDiagnosticsMessage(); Future startCreateNextSourceRangesMessage();
void startCreateNextSourceRangesAndDiagnosticsMessages(); void startCreateNextSourceRangesMessages();
void waitForFinished(); void waitForFinished();
bool isFinished() const; bool isFinished() const;
const std::vector<V2::FileContainer> &sources() const; const std::vector<V2::FileContainer> &sources() const;
const std::vector<Future> &sourceFutures() const; const std::vector<Future> &sourceFutures() const;
std::vector<SourceRangesAndDiagnosticsForQueryMessage> allCurrentProcessedMessages(); std::vector<SourceRangesForQueryMessage> allCurrentProcessedMessages();
std::vector<SourceRangesAndDiagnosticsForQueryMessage> finishedMessages(); std::vector<SourceRangesForQueryMessage> finishedMessages();
void setProcessingSlotCount(uint count); void setProcessingSlotCount(uint count);

View File

@@ -29,10 +29,7 @@
#include "clangquery.h" #include "clangquery.h"
#include <refactoringclientinterface.h> #include <refactoringclientinterface.h>
#include <requestsourcelocationforrenamingmessage.h> #include <clangrefactoringmessages.h>
#include <requestsourcerangesanddiagnosticsforquerymessage.h>
#include <sourcelocationsforrenamingmessage.h>
#include <sourcerangesanddiagnosticsforquerymessage.h>
#include <QCoreApplication> #include <QCoreApplication>
@@ -47,7 +44,7 @@ RefactoringServer::RefactoringServer()
QObject::connect(&m_pollTimer, QObject::connect(&m_pollTimer,
&QTimer::timeout, &QTimer::timeout,
std::bind(&RefactoringServer::pollSourceRangesAndDiagnosticsForQueryMessages, this)); std::bind(&RefactoringServer::pollSourceRangesForQueryMessages, this));
} }
void RefactoringServer::end() void RefactoringServer::end()
@@ -74,7 +71,22 @@ void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLo
void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage( void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage(
RequestSourceRangesAndDiagnosticsForQueryMessage &&message) 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.takeUnsavedContent(),
message.takeQuery()); message.takeQuery());
} }
@@ -91,22 +103,22 @@ bool RefactoringServer::isCancelingJobs() const
return m_gatherer.isFinished(); return m_gatherer.isFinished();
} }
void RefactoringServer::pollSourceRangesAndDiagnosticsForQueryMessages() void RefactoringServer::pollSourceRangesForQueryMessages()
{ {
for (auto &&message : m_gatherer.finishedMessages()) for (auto &&message : m_gatherer.finishedMessages())
client()->sourceRangesAndDiagnosticsForQueryMessage(std::move(message)); client()->sourceRangesForQueryMessage(std::move(message));
if (!m_gatherer.isFinished()) if (!m_gatherer.isFinished())
m_gatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); m_gatherer.startCreateNextSourceRangesMessages();
else else
m_pollTimer.stop(); m_pollTimer.stop();
} }
void RefactoringServer::waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished() void RefactoringServer::waitThatSourceRangesForQueryMessagesAreFinished()
{ {
while (!m_gatherer.isFinished()) { while (!m_gatherer.isFinished()) {
m_gatherer.waitForFinished(); m_gatherer.waitForFinished();
pollSourceRangesAndDiagnosticsForQueryMessages(); pollSourceRangesForQueryMessages();
} }
} }
@@ -120,7 +132,7 @@ void RefactoringServer::setGathererProcessingSlotCount(uint count)
m_gatherer.setProcessingSlotCount(count); m_gatherer.setProcessingSlotCount(count);
} }
void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessages( void RefactoringServer::gatherSourceRangesForQueryMessages(
std::vector<V2::FileContainer> &&sources, std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved, std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query) Utils::SmallString &&query)

View File

@@ -40,7 +40,7 @@
namespace ClangBackEnd { namespace ClangBackEnd {
class SourceRangesAndDiagnosticsForQueryMessage; class SourceRangesForQueryMessage;
namespace V2 { namespace V2 {
class FileContainer; class FileContainer;
@@ -48,26 +48,27 @@ class FileContainer;
class RefactoringServer : public RefactoringServerInterface class RefactoringServer : public RefactoringServerInterface
{ {
using Future = std::future<SourceRangesAndDiagnosticsForQueryMessage>; using Future = std::future<SourceRangesForQueryMessage>;
public: public:
RefactoringServer(); RefactoringServer();
void end() override; void end() override;
void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override; void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override; void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
void cancel() override; void cancel() override;
bool isCancelingJobs() const; bool isCancelingJobs() const;
void pollSourceRangesAndDiagnosticsForQueryMessages(); void pollSourceRangesForQueryMessages();
void waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished(); void waitThatSourceRangesForQueryMessagesAreFinished();
bool pollTimerIsActive() const; bool pollTimerIsActive() const;
void setGathererProcessingSlotCount(uint count); void setGathererProcessingSlotCount(uint count);
private: private:
void gatherSourceRangesAndDiagnosticsForQueryMessages(std::vector<V2::FileContainer> &&sources, void gatherSourceRangesForQueryMessages(std::vector<V2::FileContainer> &&sources,
std::vector<V2::FileContainer> &&unsaved, std::vector<V2::FileContainer> &&unsaved,
Utils::SmallString &&query); Utils::SmallString &&query);

View File

@@ -31,29 +31,44 @@ namespace ClangBackEnd {
SourceRangeFilter::SourceRangeFilter(std::size_t sourcesCount) 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); return std::move(message);
} }
void SourceRangeFilter::removeDuplicates(SourceRangeWithTextContainers &sourceRanges) SourceRangeWithTextContainers SourceRangeFilter::removeDuplicates(SourceRangeWithTextContainers &&sourceRanges)
{ {
auto partitionPoint = std::stable_partition(sourceRanges.begin(), SourceRangeWithTextContainers newSourceRanges;
sourceRanges.end(), newSourceRanges.reserve(sourceRanges.size());
[&] (const SourceRangeWithTextContainer &sourceRange) {
return m_collectedSourceRanges.find(sourceRange) == m_collectedSourceRanges.end();
});
sourceRanges.erase(partitionPoint, sourceRanges.end()); std::sort(sourceRanges.begin(), sourceRanges.end());
auto sourceRangesNewEnd = std::unique(sourceRanges.begin(), sourceRanges.end());
std::copy(sourceRanges.begin(), std::set_difference(sourceRanges.begin(),
sourceRanges.end(), sourceRangesNewEnd,
std::inserter(m_collectedSourceRanges, m_collectedSourceRanges.end())); 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));
std::swap(m_collectedSourceRanges, collectedSourceRanges);
return newSourceRanges;
} }
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -25,9 +25,9 @@
#pragma once #pragma once
#include <unordered_set> #include <vector>
#include <sourcerangesanddiagnosticsforquerymessage.h> #include <sourcerangesforquerymessage.h>
namespace ClangBackEnd { namespace ClangBackEnd {
@@ -36,12 +36,12 @@ class SourceRangeFilter
public: public:
SourceRangeFilter(std::size_t sourcesCount = 0); SourceRangeFilter(std::size_t sourcesCount = 0);
SourceRangesAndDiagnosticsForQueryMessage SourceRangesForQueryMessage
removeDuplicates(SourceRangesAndDiagnosticsForQueryMessage &&message); removeDuplicates(SourceRangesForQueryMessage &&message);
void removeDuplicates(SourceRangeWithTextContainers &sourceRanges); SourceRangeWithTextContainers removeDuplicates(SourceRangeWithTextContainers &&sourceRanges);
private: private:
std::unordered_set<SourceRangeWithTextContainer> m_collectedSourceRanges; V2::SourceRangeContainers m_collectedSourceRanges;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -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 <texteditor/texteditorconstants.h>
#include <QObject>
#include <QTextBlock>
#include <QTextLayout>
#include <functional>
#include <limits.h>
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<QTextLayout::FormatRange> &formats) {}
static QList<QColor> generateColors(int n, const QColor &background)
{
return QList<QColor>();
}
// 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<TextStyle(int)> 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<std::pair<int, TextStyle>> &categories) {}
void reformatBlocks(int from, int charsRemoved, int charsAdded) {}
void delayedRehighlight() {}
QTextDocument *m_document = nullptr;
};
} // namespace TextEditor

View File

@@ -26,6 +26,7 @@
#include "googletest.h" #include "googletest.h"
#include "sourcerangecontainer-matcher.h" #include "sourcerangecontainer-matcher.h"
#include "dynamicastmatcherdiagnosticcontainer-matcher.h" #include "dynamicastmatcherdiagnosticcontainer-matcher.h"
#include "filesystem-utilities.h"
#include <clangquery.h> #include <clangquery.h>
@@ -34,9 +35,10 @@
using ClangBackEnd::ClangQuery; using ClangBackEnd::ClangQuery;
using ClangBackEnd::StringCache; using ClangBackEnd::StringCache;
using testing::AllOf;
using testing::Contains;
using testing::IsEmpty; using testing::IsEmpty;
using testing::Not; using testing::Not;
using testing::AllOf;
namespace { namespace {
@@ -75,36 +77,48 @@ TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange)
simpleFunctionQuery.findLocations(); simpleFunctionQuery.findLocations();
ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers().at(0), ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers(),
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}")); 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) TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange)
{ {
::ClangQuery query(filePathCache); ::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()"); query.setQuery("functionDecl()");
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}}; ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}};
query.addUnsavedFiles({unsavedFile}); query.addUnsavedFiles({unsavedFile});
query.findLocations(); query.findLocations();
ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers().at(0), ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(),
IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();")); 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 TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOverride) // seems not to work in Clang
{ {
::ClangQuery query(filePathCache); ::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()"); query.setQuery("functionDecl()");
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void unsaved();", {}}; ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void unsaved();", {}};
query.addUnsavedFiles({unsavedFile}); query.addUnsavedFiles({unsavedFile});
query.findLocations(); query.findLocations();
ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers().at(0), ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(),
IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();")); Contains(IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();")));
} }
TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFieldDeclarationRange) TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFieldDeclarationRange)
@@ -191,7 +205,7 @@ TEST_F(ClangQuerySlowTest, DiagnosticForWrongArgumenType)
void ClangQuery::SetUp() 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"}); simpleClassQuery.addFile(TESTDATA_DIR, "query_simpleclass.cpp", "", {"cc", "query_simpleclass.cpp", "-std=c++14"});
} }

View File

@@ -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 <clangqueryexamplehighlightmarker.h>
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<MockSyntaxHighlighter>;
using TextFormats = std::array<QTextCharFormat, 5>;
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));
}
}

View File

@@ -54,7 +54,7 @@ using testing::UnorderedElementsAre;
using testing::_; using testing::_;
using ClangBackEnd::V2::FileContainer; using ClangBackEnd::V2::FileContainer;
using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; using ClangBackEnd::SourceRangesForQueryMessage;
using ClangBackEnd::SourceRangesContainer; using ClangBackEnd::SourceRangesContainer;
using ClangBackEnd::SourceRangesContainer; using ClangBackEnd::SourceRangesContainer;
@@ -98,100 +98,100 @@ protected:
query.clone()}; 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, ASSERT_THAT(sourceRangesAndDiagnostics,
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(2, 1, 2, 12, "void f() {}"))))); 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, ASSERT_THAT(sourceRangesAndDiagnostics,
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); 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()}; 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, ASSERT_THAT(sourceRangesAndDiagnostics,
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); 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)); ASSERT_THAT(manyGatherer.sources(), SizeIs(2));
} }
TEST_F(ClangQueryGatherer, StartCreateSourceRangesAndDiagnosticsForNextSource) TEST_F(ClangQueryGatherer, StartCreateSourceRangesForNextSource)
{ {
auto future = gatherer.startCreateNextSourceRangesAndDiagnosticsMessage(); auto future = gatherer.startCreateNextSourceRangesMessage();
future.wait(); future.wait();
ASSERT_THAT(future.get(), ASSERT_THAT(future.get(),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); 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)); ASSERT_THAT(manyGatherer.sources(), SizeIs(2));
} }
TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesAndDiagnosticsMessagesFutureCountIsTwos) TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesMessagesFutureCountIsTwos)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
ASSERT_THAT(manyGatherer.sourceFutures(), SizeIs(2)); 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)); ASSERT_THAT(manyGatherer.sourceFutures(), SizeIs(2));
} }
TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesAndDiagnosticsMessagesGetCollected) TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesMessagesGetCollected)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
ASSERT_THAT(manyGatherer.allCurrentProcessedMessages(), ASSERT_THAT(manyGatherer.allCurrentProcessedMessages(),
UnorderedElementsAre( UnorderedElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre(IsSourceRangeWithText(1, 1, 1, 9, "void f();"), UnorderedElementsAre(IsSourceRangeWithText(1, 1, 1, 9, "void f();"),
IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre( UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 13, "int header();"), IsSourceRangeWithText(1, 1, 1, 13, "int header();"),
@@ -200,7 +200,7 @@ TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesAndDiagnosticsMessagesGet
TEST_F(ClangQueryGatherer, GetFinishedMessages) TEST_F(ClangQueryGatherer, GetFinishedMessages)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
auto messages = manyGatherer.finishedMessages(); auto messages = manyGatherer.finishedMessages();
@@ -208,12 +208,12 @@ TEST_F(ClangQueryGatherer, GetFinishedMessages)
ASSERT_THAT(messages, ASSERT_THAT(messages,
AllOf(SizeIs(2), AllOf(SizeIs(2),
UnorderedElementsAre( UnorderedElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre( UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 9, "void f();"), IsSourceRangeWithText(1, 1, 1, 9, "void f();"),
IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre( UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 13, "int header();"), IsSourceRangeWithText(1, 1, 1, 13, "int header();"),
@@ -222,10 +222,10 @@ TEST_F(ClangQueryGatherer, GetFinishedMessages)
TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass) TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
auto messages = manyGatherer.finishedMessages(); auto messages = manyGatherer.finishedMessages();
@@ -233,7 +233,7 @@ TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass)
ASSERT_THAT(messages, ASSERT_THAT(messages,
AllOf(SizeIs(1), AllOf(SizeIs(1),
ElementsAre( ElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre( UnorderedElementsAre(
IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); IsSourceRangeWithText(3, 1, 3, 15, "int function();")))))));
@@ -242,7 +242,7 @@ TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass)
TEST_F(ClangQueryGatherer, FilterDuplicates) TEST_F(ClangQueryGatherer, FilterDuplicates)
{ {
manyGatherer.setProcessingSlotCount(3); manyGatherer.setProcessingSlotCount(3);
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
auto messages = manyGatherer.finishedMessages(); auto messages = manyGatherer.finishedMessages();
@@ -250,17 +250,17 @@ TEST_F(ClangQueryGatherer, FilterDuplicates)
ASSERT_THAT(messages, ASSERT_THAT(messages,
AllOf(SizeIs(3), AllOf(SizeIs(3),
UnorderedElementsAre( UnorderedElementsAre(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre( UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 9, "void f();"), IsSourceRangeWithText(1, 1, 1, 9, "void f();"),
IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre( UnorderedElementsAre(
IsSourceRangeWithText(1, 1, 1, 13, "int header();"), IsSourceRangeWithText(1, 1, 1, 13, "int header();"),
IsSourceRangeWithText(3, 1, 3, 15, "int function();")))), IsSourceRangeWithText(3, 1, 3, 15, "int function();")))),
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
UnorderedElementsAre( UnorderedElementsAre(
IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); IsSourceRangeWithText(3, 1, 3, 15, "int function();")))))));
@@ -268,7 +268,7 @@ TEST_F(ClangQueryGatherer, FilterDuplicates)
TEST_F(ClangQueryGatherer, AfterGetFinishedMessagesFuturesAreReduced) TEST_F(ClangQueryGatherer, AfterGetFinishedMessagesFuturesAreReduced)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();
@@ -278,21 +278,21 @@ TEST_F(ClangQueryGatherer, AfterGetFinishedMessagesFuturesAreReduced)
TEST_F(ClangQueryGatherer, SourceFutureIsOneInTheSecondRun) TEST_F(ClangQueryGatherer, SourceFutureIsOneInTheSecondRun)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
ASSERT_THAT(manyGatherer.sourceFutures(), SizeIs(1)); ASSERT_THAT(manyGatherer.sourceFutures(), SizeIs(1));
} }
TEST_F(ClangQueryGatherer, GetOneMessageInTheSecondRun) TEST_F(ClangQueryGatherer, GetOneMessageInTheSecondRun)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
auto messages = manyGatherer.finishedMessages(); auto messages = manyGatherer.finishedMessages();
@@ -302,7 +302,7 @@ TEST_F(ClangQueryGatherer, GetOneMessageInTheSecondRun)
TEST_F(ClangQueryGatherer, IsNotFinishedIfSourcesExists) TEST_F(ClangQueryGatherer, IsNotFinishedIfSourcesExists)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();
@@ -313,10 +313,10 @@ TEST_F(ClangQueryGatherer, IsNotFinishedIfSourcesExists)
TEST_F(ClangQueryGatherer, IsNotFinishedIfSourceFuturesExists) TEST_F(ClangQueryGatherer, IsNotFinishedIfSourceFuturesExists)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
bool isFinished = manyGatherer.isFinished(); bool isFinished = manyGatherer.isFinished();
@@ -325,10 +325,10 @@ TEST_F(ClangQueryGatherer, IsNotFinishedIfSourceFuturesExists)
TEST_F(ClangQueryGatherer, IsFinishedIfNoSourceAndSourceFuturesExists) TEST_F(ClangQueryGatherer, IsFinishedIfNoSourceAndSourceFuturesExists)
{ {
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();
manyGatherer.startCreateNextSourceRangesAndDiagnosticsMessages(); manyGatherer.startCreateNextSourceRangesMessages();
manyGatherer.waitForFinished(); manyGatherer.waitForFinished();
manyGatherer.finishedMessages(); manyGatherer.finishedMessages();

View File

@@ -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 <clangqueryhighlightmarker.h>
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<MockSyntaxHighlighter>;
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);
}
}

View File

@@ -32,23 +32,25 @@
#include <clangqueryprojectsfindfilter.h> #include <clangqueryprojectsfindfilter.h>
#include <refactoringclient.h> #include <refactoringclient.h>
#include <requestsourcelocationforrenamingmessage.h> #include <clangrefactoringservermessages.h>
#include <requestsourcerangesanddiagnosticsforquerymessage.h>
#include <cpptools/clangcompileroptionsbuilder.h> #include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/projectpart.h> #include <cpptools/projectpart.h>
namespace { namespace {
using ::testing::_; using testing::_;
using ::testing::NiceMock; using testing::AllOf;
using ::testing::NotNull; using testing::NiceMock;
using ::testing::Return; using testing::NotNull;
using ::testing::ReturnNew; using testing::Property;
using ::testing::DefaultValue; using testing::Return;
using ::testing::ByMove; using testing::ReturnNew;
using testing::DefaultValue;
using testing::ByMove;
using CppTools::ClangCompilerOptionsBuilder; using CppTools::ClangCompilerOptionsBuilder;
using ClangBackEnd::V2::FileContainer;
class ClangQueryProjectFindFilter : public ::testing::Test class ClangQueryProjectFindFilter : public ::testing::Test
{ {
@@ -105,7 +107,7 @@ TEST_F(ClangQueryProjectFindFilter, ServerIsUsableForUsableFindFilter)
TEST_F(ClangQueryProjectFindFilter, SearchHandleSetIsSetAfterFindAll) TEST_F(ClangQueryProjectFindFilter, SearchHandleSetIsSetAfterFindAll)
{ {
findFilter.findAll(findDeclQueryText); findFilter.find(findDeclQueryText);
auto searchHandle = refactoringClient.searchHandle(); auto searchHandle = refactoringClient.searchHandle();
@@ -115,47 +117,60 @@ TEST_F(ClangQueryProjectFindFilter, SearchHandleSetIsSetAfterFindAll)
TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingStartNewSearch) TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingStartNewSearch)
{ {
EXPECT_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"), EXPECT_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"),
findDeclQueryText)) findDeclQueryText));
.Times(1);
findFilter.findAll(findDeclQueryText); findFilter.find(findDeclQueryText);
} }
TEST_F(ClangQueryProjectFindFilter, FindAllIsSettingExprectedResultCountInTheRefactoringClient) TEST_F(ClangQueryProjectFindFilter, FindAllIsSettingExprectedResultCountInTheRefactoringClient)
{ {
findFilter.findAll(findDeclQueryText); findFilter.find(findDeclQueryText);
ASSERT_THAT(refactoringClient.expectedResultCount(), 3); ASSERT_THAT(refactoringClient.expectedResultCount(), 3);
} }
TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage) TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage)
{ {
ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(findDeclQueryText, ClangBackEnd::RequestSourceRangesForQueryMessage message(findDeclQueryText,
{{{"/path/to", "file1.h"}, {{{"/path/to", "file1.h"},
"", "",
commandLines[0].clone()}, commandLines[0].clone()},
{{"/path/to", "file1.cpp"}, {{"/path/to", "file1.cpp"},
"", "",
commandLines[1].clone()}, commandLines[1].clone()},
{{"/path/to", "file2.cpp"}, {{"/path/to", "file2.cpp"},
"", "",
commandLines[2].clone()}}, commandLines[2].clone()}},
{unsavedContent.clone()}); {unsavedContent.clone()});
EXPECT_CALL(mockRefactoringServer, requestSourceRangesAndDiagnosticsForQueryMessage(message)) EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
.Times(1);
findFilter.findAll(findDeclQueryText); findFilter.find(findDeclQueryText);
} }
TEST_F(ClangQueryProjectFindFilter, CancelSearch) TEST_F(ClangQueryProjectFindFilter, CancelSearch)
{ {
EXPECT_CALL(mockRefactoringServer, cancel()) auto searchHandle = findFilter.find(findDeclQueryText);
.Times(1);
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<CppTools::ProjectPart::Ptr> createProjectParts() std::vector<CppTools::ProjectPart::Ptr> createProjectParts()

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include <utils/smallstring.h>
#include <string> #include <string>
// use std::filesystem::path if it is supported by all compilers // use std::filesystem::path if it is supported by all compilers
@@ -34,12 +36,25 @@ const char nativeSeperator = '\\';
const char nativeSeperator = '/'; const char nativeSeperator = '/';
#endif #endif
inline template <std::size_t Size>
std::string toNativePath(std::string &&path) std::string toNativePath(const char (&text)[Size])
{ {
std::string path = text;
#ifdef _WIN32 #ifdef _WIN32
std::replace(path.begin(), path.end(), '/', '\\'); std::replace(path.begin(), path.end(), '/', '\\');
#endif #endif
return std::move(path); return path;
}
inline
std::string toNativePath(const QString &qStringPath)
{
auto path = qStringPath.toStdString();
#ifdef _WIN32
std::replace(path.begin(), path.end(), '/', '\\');
#endif
return path;
} }

View File

@@ -24,6 +24,7 @@
****************************************************************************/ ****************************************************************************/
#include <QString> #include <QString>
#include <QTextCharFormat>
#include <QDebug> #include <QDebug>
#include <gtest/gtest-printers.h> #include <gtest/gtest-printers.h>
@@ -32,35 +33,54 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
void PrintTo(const QByteArray &byteArray, ::std::ostream *os) std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray)
{ {
if (byteArray.contains('\n')) { if (byteArray.contains('\n')) {
QByteArray formattedArray = byteArray; QByteArray formattedArray = byteArray;
formattedArray.replace("\n", "\n\t"); formattedArray.replace("\n", "\n\t");
*os << "\n\t"; out << "\n\t";
os->write(formattedArray.data(), formattedArray.size()); out.write(formattedArray.data(), formattedArray.size());
} else { } else {
*os << "\""; out << "\"";
os->write(byteArray.data(), byteArray.size()); out.write(byteArray.data(), byteArray.size());
*os << "\""; out << "\"";
} }
return out;
} }
void PrintTo(const QVariant &variant, ::std::ostream *os) std::ostream &operator<<(std::ostream &out, const QVariant &variant)
{ {
QString output; QString output;
QDebug debug(&output); QDebug debug(&output);
debug << variant; debug << variant;
PrintTo(output.toUtf8(), os); return out << output;
} }
void PrintTo(const QString &text, ::std::ostream *os) std::ostream &operator<<(std::ostream &out, const QString &text)
{ {
const QByteArray utf8 = text.toUtf8(); return out << text.toUtf8();
}
PrintTo(text.toUtf8(), os); std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format)
{
out << "("
<< format.fontFamily();
if (format.fontItalic())
out << ", italic";
if (format.fontCapitalization() == QFont::Capitalize)
out << ", Capitalization";
if (format.fontOverline())
out << ", overline";
out << ")";
return out;
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -33,8 +33,10 @@ QT_BEGIN_NAMESPACE
class QVariant; class QVariant;
class QString; class QString;
class QTextCharFormat;
void PrintTo(const QVariant &variant, ::std::ostream *os); std::ostream &operator<<(std::ostream &out, const QVariant &variant);
void PrintTo(const QString &text, ::std::ostream *os); std::ostream &operator<<(std::ostream &out, const QString &text);
void PrintTo(const QByteArray &byteArray, ::std::ostream *os); std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray);
std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format);
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -38,6 +38,8 @@ public:
void (const ClangBackEnd::SourceLocationsForRenamingMessage&)); void (const ClangBackEnd::SourceLocationsForRenamingMessage&));
MOCK_METHOD1(sourceRangesAndDiagnosticsForQueryMessage, MOCK_METHOD1(sourceRangesAndDiagnosticsForQueryMessage,
void (const ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage&)); void (const ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage&));
MOCK_METHOD1(sourceRangesForQueryMessage,
void (const ClangBackEnd::SourceRangesForQueryMessage&));
void sourceLocationsForRenamingMessage(ClangBackEnd::SourceLocationsForRenamingMessage &&message) override void sourceLocationsForRenamingMessage(ClangBackEnd::SourceLocationsForRenamingMessage &&message) override
{ {
@@ -49,6 +51,11 @@ public:
sourceRangesAndDiagnosticsForQueryMessage(message); sourceRangesAndDiagnosticsForQueryMessage(message);
} }
void sourceRangesForQueryMessage(ClangBackEnd::SourceRangesForQueryMessage &&message) override
{
sourceRangesForQueryMessage(message);
}
void setLocalRenamingCallback(RenameCallback &&) void setLocalRenamingCallback(RenameCallback &&)
{ {
} }

View File

@@ -41,8 +41,11 @@ public:
MOCK_METHOD1(requestSourceRangesAndDiagnosticsForQueryMessage, MOCK_METHOD1(requestSourceRangesAndDiagnosticsForQueryMessage,
void (const ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage&)); void (const ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage&));
MOCK_METHOD1(requestSourceRangesForQueryMessage,
void (const ClangBackEnd::RequestSourceRangesForQueryMessage&));
MOCK_METHOD0(cancel, MOCK_METHOD0(cancel,
void ()); void());
void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override
{ {
@@ -53,4 +56,9 @@ public:
{ {
requestSourceRangesAndDiagnosticsForQueryMessage(message); requestSourceRangesAndDiagnosticsForQueryMessage(message);
} }
void requestSourceRangesForQueryMessage(ClangBackEnd::RequestSourceRangesForQueryMessage &&message) override
{
requestSourceRangesForQueryMessage(message);
}
}; };

View File

@@ -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 <refactoringclientinterface.h>
#include <QTextCharFormat>
class MockSyntaxHighlighter
{
public:
MOCK_METHOD3(setFormat,
void (int start, int count, const QTextCharFormat &format));
};

View File

@@ -32,8 +32,7 @@
#include <refactoringengine.h> #include <refactoringengine.h>
#include <refactoringconnectionclient.h> #include <refactoringconnectionclient.h>
#include <sourcelocationsforrenamingmessage.h> #include <clangrefactoringclientmessages.h>
#include <sourcerangesanddiagnosticsforquerymessage.h>
#include <cpptools/clangcompileroptionsbuilder.h> #include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/projectpart.h> #include <cpptools/projectpart.h>
@@ -51,6 +50,7 @@ using ClangRefactoring::RefactoringEngine;
using ClangBackEnd::SourceLocationsForRenamingMessage; using ClangBackEnd::SourceLocationsForRenamingMessage;
using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage;
using ClangBackEnd::SourceRangesForQueryMessage;
using testing::_; using testing::_;
using testing::Pair; using testing::Pair;
@@ -83,12 +83,10 @@ protected:
{{{42u, clangBackEndFilePath.clone()}}, {{{42u, clangBackEndFilePath.clone()}},
{{42u, 1, 1, 0}, {42u, 2, 5, 10}}}, {{42u, 1, 1, 0}, {42u, 2, 5, 10}}},
1}; 1};
SourceRangesAndDiagnosticsForQueryMessage queryResultMessage{{{{42u, clangBackEndFilePath.clone()}}, SourceRangesForQueryMessage queryResultMessage{{{{42u, clangBackEndFilePath.clone()}},
{{42u, 1, 1, 0, 1, 5, 4, ""}, {{42u, 1, 1, 0, 1, 5, 4, ""},
{42u, 2, 1, 5, 2, 5, 10, ""}}}, {42u, 2, 1, 5, 2, 5, 10, ""}}}};
{}}; SourceRangesForQueryMessage emptyQueryResultMessage{{{},{}}};
SourceRangesAndDiagnosticsForQueryMessage emptyQueryResultMessage{{{},{}},
{}};
}; };
TEST_F(RefactoringClient, SourceLocationsForRenaming) TEST_F(RefactoringClient, SourceLocationsForRenaming)
@@ -143,7 +141,7 @@ TEST_F(RefactoringClient, CallAddResultsForEmptyQueryMessage)
EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_)) EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_))
.Times(0); .Times(0);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(emptyQueryResultMessage)); client.sourceRangesForQueryMessage(std::move(emptyQueryResultMessage));
} }
TEST_F(RefactoringClient, CallAddResultsForQueryMessage) TEST_F(RefactoringClient, CallAddResultsForQueryMessage)
@@ -151,7 +149,7 @@ TEST_F(RefactoringClient, CallAddResultsForQueryMessage)
EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_)) EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_))
.Times(2); .Times(2);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
} }
TEST_F(RefactoringClient, CallFinishSearchForEmptyQueryMessage) TEST_F(RefactoringClient, CallFinishSearchForEmptyQueryMessage)
@@ -159,7 +157,7 @@ TEST_F(RefactoringClient, CallFinishSearchForEmptyQueryMessage)
EXPECT_CALL(mockSearchHandle, finishSearch()) EXPECT_CALL(mockSearchHandle, finishSearch())
.Times(1); .Times(1);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(emptyQueryResultMessage)); client.sourceRangesForQueryMessage(std::move(emptyQueryResultMessage));
} }
TEST_F(RefactoringClient, CallFinishSearchQueryMessage) TEST_F(RefactoringClient, CallFinishSearchQueryMessage)
@@ -167,7 +165,7 @@ TEST_F(RefactoringClient, CallFinishSearchQueryMessage)
EXPECT_CALL(mockSearchHandle, finishSearch()) EXPECT_CALL(mockSearchHandle, finishSearch())
.Times(1); .Times(1);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
} }
TEST_F(RefactoringClient, CallFinishSearchForTwoQueryMessages) TEST_F(RefactoringClient, CallFinishSearchForTwoQueryMessages)
@@ -177,8 +175,8 @@ TEST_F(RefactoringClient, CallFinishSearchForTwoQueryMessages)
EXPECT_CALL(mockSearchHandle, finishSearch()) EXPECT_CALL(mockSearchHandle, finishSearch())
.Times(1); .Times(1);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
} }
TEST_F(RefactoringClient, CallSetExpectedResultCountInSearchHandle) TEST_F(RefactoringClient, CallSetExpectedResultCountInSearchHandle)
@@ -191,7 +189,7 @@ TEST_F(RefactoringClient, CallSetExpectedResultCountInSearchHandle)
TEST_F(RefactoringClient, ResultCounterIsOneAfterQueryMessage) TEST_F(RefactoringClient, ResultCounterIsOneAfterQueryMessage)
{ {
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
ASSERT_THAT(client.resultCounter(), 1); ASSERT_THAT(client.resultCounter(), 1);
} }
@@ -201,30 +199,28 @@ TEST_F(RefactoringClient, ResultCounterIsSetInSearchHandleToOne)
EXPECT_CALL(mockSearchHandle, setResultCounter(1)) EXPECT_CALL(mockSearchHandle, setResultCounter(1))
.Times(1); .Times(1);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
} }
TEST_F(RefactoringClient, ResultCounterIsSetInSearchHandleToTwo) TEST_F(RefactoringClient, ResultCounterIsSetInSearchHandleToTwo)
{ {
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
EXPECT_CALL(mockSearchHandle, setResultCounter(2)) EXPECT_CALL(mockSearchHandle, setResultCounter(2))
.Times(1); .Times(1);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
} }
TEST_F(RefactoringClient, ResultCounterIsZeroAfterSettingExpectedResultCount) TEST_F(RefactoringClient, ResultCounterIsZeroAfterSettingExpectedResultCount)
{ {
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage)); client.sourceRangesForQueryMessage(std::move(queryResultMessage));
client.setExpectedResultCount(3); client.setExpectedResultCount(3);
ASSERT_THAT(client.resultCounter(), 0); ASSERT_THAT(client.resultCounter(), 0);
} }
TEST_F(RefactoringClient, ConvertFilePaths) TEST_F(RefactoringClient, ConvertFilePaths)
{ {
std::unordered_map<uint, ClangBackEnd::FilePath> filePaths{{42u, clangBackEndFilePath.clone()}}; std::unordered_map<uint, ClangBackEnd::FilePath> filePaths{{42u, clangBackEndFilePath.clone()}};

View File

@@ -31,10 +31,7 @@
#include <writemessageblock.h> #include <writemessageblock.h>
#include <refactoringclientproxy.h> #include <refactoringclientproxy.h>
#include <refactoringserverproxy.h> #include <refactoringserverproxy.h>
#include <sourcelocationsforrenamingmessage.h> #include <clangrefactoringmessages.h>
#include <sourcerangesanddiagnosticsforquerymessage.h>
#include <requestsourcelocationforrenamingmessage.h>
#include <requestsourcerangesanddiagnosticsforquerymessage.h>
#include <QBuffer> #include <QBuffer>
#include <QString> #include <QString>
@@ -72,8 +69,7 @@ protected:
TEST_F(RefactoringClientServerInProcess, SendEndMessage) TEST_F(RefactoringClientServerInProcess, SendEndMessage)
{ {
EXPECT_CALL(mockRefactoringServer, end()) EXPECT_CALL(mockRefactoringServer, end());
.Times(1);
serverProxy.end(); serverProxy.end();
scheduleServerMessages(); scheduleServerMessages();
@@ -81,9 +77,7 @@ TEST_F(RefactoringClientServerInProcess, SendEndMessage)
TEST_F(RefactoringClientServerInProcess, SendAliveMessage) TEST_F(RefactoringClientServerInProcess, SendAliveMessage)
{ {
EXPECT_CALL(mockRefactoringClient, alive());
EXPECT_CALL(mockRefactoringClient, alive())
.Times(1);
clientProxy.alive(); clientProxy.alive();
scheduleClientMessages(); scheduleClientMessages();
@@ -94,8 +88,7 @@ TEST_F(RefactoringClientServerInProcess, SendSourceLocationsForRenamingMessage)
ClangBackEnd::SourceLocationsContainer container; ClangBackEnd::SourceLocationsContainer container;
ClangBackEnd::SourceLocationsForRenamingMessage message("symbolName", std::move(container), 1); ClangBackEnd::SourceLocationsForRenamingMessage message("symbolName", std::move(container), 1);
EXPECT_CALL(mockRefactoringClient, sourceLocationsForRenamingMessage(message)) EXPECT_CALL(mockRefactoringClient, sourceLocationsForRenamingMessage(message));
.Times(1);
clientProxy.sourceLocationsForRenamingMessage(message.clone()); clientProxy.sourceLocationsForRenamingMessage(message.clone());
scheduleClientMessages(); scheduleClientMessages();
@@ -110,8 +103,7 @@ TEST_F(RefactoringClientServerInProcess, SendRequestSourceLocationsForRenamingMe
{"cc", "renamevariable.cpp"}, {"cc", "renamevariable.cpp"},
1}; 1};
EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(message)) EXPECT_CALL(mockRefactoringServer, requestSourceLocationsForRenamingMessage(message));
.Times(1);
serverProxy.requestSourceLocationsForRenamingMessage(message.clone()); serverProxy.requestSourceLocationsForRenamingMessage(message.clone());
scheduleServerMessages(); scheduleServerMessages();
@@ -124,36 +116,62 @@ TEST_F(RefactoringClientServerInProcess, SourceRangesAndDiagnosticsForQueryMessa
ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage message(std::move(sourceRangesContainer), ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage message(std::move(sourceRangesContainer),
std::move(diagnosticContainers)); std::move(diagnosticContainers));
EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage(message)) EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage(message));
.Times(1);
clientProxy.sourceRangesAndDiagnosticsForQueryMessage(message.clone()); clientProxy.sourceRangesAndDiagnosticsForQueryMessage(message.clone());
scheduleClientMessages(); 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) TEST_F(RefactoringClientServerInProcess, RequestSourceRangesAndDiagnosticsForQueryMessage)
{ {
RequestSourceRangesAndDiagnosticsForQueryMessage message{"functionDecl()", RequestSourceRangesForQueryMessage message{"functionDecl()",
{{{TESTDATA_DIR, "query_simplefunction.cpp"}, {{{TESTDATA_DIR, "query_simplefunction.cpp"},
"void f();", "void f();",
{"cc", "query_simplefunction.cpp"}, {"cc", "query_simplefunction.cpp"},
1}}, 1}},
{{{TESTDATA_DIR, "query_simplefunction.h"}, {{{TESTDATA_DIR, "query_simplefunction.h"},
"void f();", "void f();",
{}, {},
1}}}; 1}}};
EXPECT_CALL(mockRefactoringServer, requestSourceRangesAndDiagnosticsForQueryMessage(message)) EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
.Times(1);
serverProxy.requestSourceRangesAndDiagnosticsForQueryMessage(message.clone()); 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(); scheduleServerMessages();
} }
TEST_F(RefactoringClientServerInProcess, CancelMessage) TEST_F(RefactoringClientServerInProcess, CancelMessage)
{ {
EXPECT_CALL(mockRefactoringServer, cancel()) EXPECT_CALL(mockRefactoringServer, cancel());
.Times(1);
serverProxy.cancel(); serverProxy.cancel();
scheduleServerMessages(); scheduleServerMessages();

View File

@@ -30,10 +30,7 @@
#include <refactoringengine.h> #include <refactoringengine.h>
#include <requestsourcelocationforrenamingmessage.h> #include <clangrefactoringmessages.h>
#include <requestsourcerangesanddiagnosticsforquerymessage.h>
#include <sourcelocationsforrenamingmessage.h>
#include <sourcerangesanddiagnosticsforquerymessage.h>
#include <cpptools/clangcompileroptionsbuilder.h> #include <cpptools/clangcompileroptionsbuilder.h>
#include <cpptools/projectpart.h> #include <cpptools/projectpart.h>

View File

@@ -30,16 +30,16 @@
#include "sourcerangecontainer-matcher.h" #include "sourcerangecontainer-matcher.h"
#include <refactoringserver.h> #include <refactoringserver.h>
#include <requestsourcelocationforrenamingmessage.h> #include <clangrefactoringmessages.h>
#include <requestsourcerangesanddiagnosticsforquerymessage.h>
#include <sourcelocationsforrenamingmessage.h> #include <QDir>
#include <sourcerangesanddiagnosticsforquerymessage.h> #include <QTemporaryFile>
#include <sourcelocationscontainer.h>
namespace { namespace {
using testing::AllOf; using testing::AllOf;
using testing::Contains; using testing::Contains;
using testing::IsEmpty;
using testing::NiceMock; using testing::NiceMock;
using testing::Not; using testing::Not;
using testing::Pair; using testing::Pair;
@@ -50,9 +50,11 @@ using testing::_;
using ClangBackEnd::FilePath; using ClangBackEnd::FilePath;
using ClangBackEnd::RequestSourceLocationsForRenamingMessage; using ClangBackEnd::RequestSourceLocationsForRenamingMessage;
using ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage; using ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage;
using ClangBackEnd::RequestSourceRangesForQueryMessage;
using ClangBackEnd::SourceLocationsContainer; using ClangBackEnd::SourceLocationsContainer;
using ClangBackEnd::SourceLocationsForRenamingMessage; using ClangBackEnd::SourceLocationsForRenamingMessage;
using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage;
using ClangBackEnd::SourceRangesForQueryMessage;
using ClangBackEnd::SourceRangesContainer; using ClangBackEnd::SourceRangesContainer;
using ClangBackEnd::V2::FileContainer; using ClangBackEnd::V2::FileContainer;
@@ -80,6 +82,7 @@ protected:
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
sourceContent.clone(), sourceContent.clone(),
{"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp")}}; {"cc", toNativePath(TESTDATA_DIR"/query_simplefunction.cpp")}};
QTemporaryFile temporaryFile{QDir::tempPath() + "/clangQuery-XXXXXX.cpp"};
int processingSlotCount = 2; int processingSlotCount = 2;
}; };
@@ -88,12 +91,12 @@ using RefactoringServerVerySlowTest = RefactoringServer;
TEST_F(RefactoringServerSlowTest, RequestSourceLocationsForRenamingMessage) TEST_F(RefactoringServerSlowTest, RequestSourceLocationsForRenamingMessage)
{ {
RequestSourceLocationsForRenamingMessage requestSourceLocationsForRenamingMessage{{TESTDATA_DIR, "renamevariable.cpp"}, RequestSourceLocationsForRenamingMessage message{{TESTDATA_DIR, "renamevariable.cpp"},
1, 1,
5, 5,
"int v;\n\nint x = v + 3;\n", "int v;\n\nint x = v + 3;\n",
{"cc", "renamevariable.cpp"}, {"cc", "renamevariable.cpp"},
1}; 1};
EXPECT_CALL(mockRefactoringClient, EXPECT_CALL(mockRefactoringClient,
sourceLocationsForRenamingMessage( sourceLocationsForRenamingMessage(
@@ -106,22 +109,22 @@ TEST_F(RefactoringServerSlowTest, RequestSourceLocationsForRenamingMessage)
Property(&SourceLocationsContainer::filePaths, Property(&SourceLocationsContainer::filePaths,
Contains(Pair(_, FilePath(TESTDATA_DIR, "renamevariable.cpp"))))))))); 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()", RequestSourceRangesForQueryMessage message{"functionDecl()",
{source.clone()}, {source.clone()},
{}}; {}};
EXPECT_CALL(mockRefactoringClient, EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage( sourceRangesForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))));
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); refactoringServer.requestSourceRangesForQueryMessage(std::move(message));
} }
TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUnsavedContentForQueryMessage) TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUnsavedContentForQueryMessage)
@@ -133,62 +136,62 @@ TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUns
FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"}, FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"},
unsavedContent.clone(), unsavedContent.clone(),
{}}; {}};
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", RequestSourceRangesForQueryMessage message{"functionDecl()",
{source.clone()}, {source.clone()},
{unsaved.clone()}}; {unsaved.clone()}};
EXPECT_CALL(mockRefactoringClient, EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage( sourceRangesForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 1, 9, unsavedContent)))))); 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()", RequestSourceRangesForQueryMessage message{"functionDecl()",
{source.clone(), source.clone()}, {source.clone(), source.clone()},
{}}; {}};
EXPECT_CALL(mockRefactoringClient, EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage( sourceRangesForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))));
EXPECT_CALL(mockRefactoringClient, EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage( sourceRangesForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))); 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<FileContainer> sources; std::vector<FileContainer> sources;
std::fill_n(std::back_inserter(sources), std::fill_n(std::back_inserter(sources),
processingSlotCount + 3, processingSlotCount + 3,
source.clone()); source.clone());
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", RequestSourceRangesForQueryMessage message{"functionDecl()",
std::move(sources), std::move(sources),
{}}; {}};
EXPECT_CALL(mockRefactoringClient, EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage( sourceRangesForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))));
EXPECT_CALL(mockRefactoringClient, EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage( sourceRangesForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, Property(&SourceRangesForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers, Property(&SourceRangesContainer::sourceRangeWithTextContainers,
Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))) Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))))
.Times(processingSlotCount + 2); .Times(processingSlotCount + 2);
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); refactoringServer.requestSourceRangesForQueryMessage(std::move(message));
} }
TEST_F(RefactoringServer, CancelJobs) TEST_F(RefactoringServer, CancelJobs)
@@ -197,10 +200,10 @@ TEST_F(RefactoringServer, CancelJobs)
std::fill_n(std::back_inserter(sources), std::fill_n(std::back_inserter(sources),
std::thread::hardware_concurrency() + 3, std::thread::hardware_concurrency() + 3,
source.clone()); source.clone());
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", RequestSourceRangesForQueryMessage message{"functionDecl()",
std::move(sources), std::move(sources),
{}}; {}};
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); refactoringServer.requestSourceRangesForQueryMessage(std::move(message));
refactoringServer.cancel(); refactoringServer.cancel();
@@ -209,48 +212,87 @@ TEST_F(RefactoringServer, CancelJobs)
TEST_F(RefactoringServer, PollTimerIsActiveAfterStart) TEST_F(RefactoringServer, PollTimerIsActiveAfterStart)
{ {
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", RequestSourceRangesForQueryMessage message{"functionDecl()",
{source}, {source},
{}}; {}};
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); refactoringServer.requestSourceRangesForQueryMessage(std::move(message));
ASSERT_TRUE(refactoringServer.pollTimerIsActive()); ASSERT_TRUE(refactoringServer.pollTimerIsActive());
} }
TEST_F(RefactoringServer, PollTimerIsNotActiveAfterFinishing) TEST_F(RefactoringServer, PollTimerIsNotActiveAfterFinishing)
{ {
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", RequestSourceRangesForQueryMessage message{"functionDecl()",
{source}, {source},
{}}; {}};
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); refactoringServer.requestSourceRangesForQueryMessage(std::move(message));
refactoringServer.waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished(); refactoringServer.waitThatSourceRangesForQueryMessagesAreFinished();
ASSERT_FALSE(refactoringServer.pollTimerIsActive()); ASSERT_FALSE(refactoringServer.pollTimerIsActive());
} }
TEST_F(RefactoringServer, PollTimerNotIsActiveAfterCanceling) TEST_F(RefactoringServer, PollTimerNotIsActiveAfterCanceling)
{ {
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", RequestSourceRangesForQueryMessage message{"functionDecl()",
{source}, {source},
{}}; {}};
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage)); refactoringServer.requestSourceRangesForQueryMessage(std::move(message));
refactoringServer.cancel(); refactoringServer.cancel();
ASSERT_FALSE(refactoringServer.pollTimerIsActive()); 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() void RefactoringServer::SetUp()
{ {
temporaryFile.open();
refactoringServer.setClient(&mockRefactoringClient); refactoringServer.setClient(&mockRefactoringClient);
} }
void RefactoringServer::TearDown() void RefactoringServer::TearDown()
{ {
refactoringServer.setGathererProcessingSlotCount(uint(processingSlotCount)); refactoringServer.setGathererProcessingSlotCount(uint(processingSlotCount));
refactoringServer.waitThatSourceRangesAndDiagnosticsForQueryMessagesAreFinished(); refactoringServer.waitThatSourceRangesForQueryMessagesAreFinished();
} }
} }

View File

@@ -34,7 +34,7 @@ using testing::IsEmpty;
using ClangBackEnd::SourceRangeWithTextContainer; using ClangBackEnd::SourceRangeWithTextContainer;
using ClangBackEnd::SourceRangeWithTextContainers; using ClangBackEnd::SourceRangeWithTextContainers;
using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage; using ClangBackEnd::SourceRangesForQueryMessage;
class SourceRangeFilter : public ::testing::Test class SourceRangeFilter : public ::testing::Test
{ {
@@ -43,54 +43,56 @@ protected:
protected: protected:
SourceRangeWithTextContainers sourceRanges1{{1, 1, 1, 1, 2, 1, 4, "foo"}, 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"},
{1, 1, 1, 1, 2, 2, 5, "foo"}}; {2, 1, 1, 1, 2, 1, 4, "foo"}};
SourceRangeWithTextContainers sourceRanges2{{1, 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"}, {3, 1, 1, 1, 2, 1, 4, "foo"},
{1, 1, 1, 1, 2, 2, 6, "foo"}}; {3, 1, 1, 1, 2, 1, 4, "foo"}};
SourceRangeWithTextContainers sourceRanges3{{3, 1, 1, 1, 2, 1, 4, "foo"}, SourceRangeWithTextContainers sourceRanges5{{3, 1, 1, 1, 2, 1, 4, "foo"},
{1, 1, 1, 1, 2, 2, 6, "foo"}}; {1, 1, 1, 1, 2, 3, 6, "foo"}};
SourceRangesAndDiagnosticsForQueryMessage message1{{{}, Utils::clone(sourceRanges1)}, {}}; SourceRangesForQueryMessage message1{{{}, Utils::clone(sourceRanges1)}};
SourceRangesAndDiagnosticsForQueryMessage message2{{{}, Utils::clone(sourceRanges2)}, {}}; SourceRangesForQueryMessage message2{{{}, Utils::clone(sourceRanges2)}};
ClangBackEnd::SourceRangeFilter filter{3}; 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(sourceRange, ContainerEq(sourceRanges1));
ASSERT_THAT(sourceRanges1, ContainerEq(expectedSourceRanges));
} }
TEST_F(SourceRangeFilter, DoNotFilterNonDuplicates) TEST_F(SourceRangeFilter, DoNotFilterNonDuplicates)
{ {
SourceRangeWithTextContainers expectedSourceRanges = sourceRanges3; filter.removeDuplicates(Utils::clone(sourceRanges1));
filter.removeDuplicates(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) 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) TEST_F(SourceRangeFilter, FilterMoreDuplicates)
{ {
filter.removeDuplicates(sourceRanges1); filter.removeDuplicates(Utils::clone(sourceRanges1));
filter.removeDuplicates(sourceRanges2); 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) TEST_F(SourceRangeFilter, FilterDuplicatesFromMessage)
@@ -103,4 +105,19 @@ TEST_F(SourceRangeFilter, FilterDuplicatesFromMessage)
ContainerEq(sourceRanges3)); 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));
}
} }

View File

@@ -64,7 +64,9 @@ SOURCES += \
pchmanagerserver-test.cpp \ pchmanagerserver-test.cpp \
pchmanagerclientserverinprocess-test.cpp \ pchmanagerclientserverinprocess-test.cpp \
filepath-test.cpp \ filepath-test.cpp \
sourcerangefilter-test.cpp sourcerangefilter-test.cpp \
clangqueryexamplehighlightmarker-test.cpp \
clangqueryhighlightmarker-test.cpp
!isEmpty(LIBCLANG_LIBS) { !isEmpty(LIBCLANG_LIBS) {
SOURCES += \ SOURCES += \
@@ -176,7 +178,8 @@ HEADERS += \
mockpchcreator.h \ mockpchcreator.h \
dummyclangipcclient.h \ dummyclangipcclient.h \
mockclangcodemodelclient.h \ mockclangcodemodelclient.h \
mockclangcodemodelserver.h mockclangcodemodelserver.h \
mocksyntaxhighligher.h
!isEmpty(LIBCLANG_LIBS) { !isEmpty(LIBCLANG_LIBS) {
HEADERS += \ HEADERS += \