summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@qt.io>2016-11-23 13:13:38 +0100
committerTim Jenssen <tim.jenssen@qt.io>2016-11-23 12:16:04 +0000
commit7f757884c5a04484820a97e592afae74beff95a9 (patch)
treed5066d8a24965523b5024ba37d210c74cd68446c
parent52fc4a4ebdc840cc351a0ed465a6523d5bc53ac2 (diff)
downloadqt-creator-7f757884c5a04484820a97e592afae74beff95a9.tar.gz
Clang: Extend clang query
It's a first step to introduce clang query. Change-Id: I4d001a8883f56066765ce6bc561fa3f49611c0a4 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
-rw-r--r--src/libs/clangbackendipc/cancelmessage.cpp44
-rw-r--r--src/libs/clangbackendipc/cancelmessage.h55
-rw-r--r--src/libs/clangbackendipc/clangbackendipc-lib.pri7
-rw-r--r--src/libs/clangbackendipc/clangbackendipc_global.h6
-rw-r--r--src/libs/clangbackendipc/refactoringserverinterface.cpp4
-rw-r--r--src/libs/clangbackendipc/refactoringserverinterface.h2
-rw-r--r--src/libs/clangbackendipc/refactoringserverproxy.cpp6
-rw-r--r--src/libs/clangbackendipc/refactoringserverproxy.h7
-rw-r--r--src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h4
-rw-r--r--src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp32
-rw-r--r--src/libs/clangbackendipc/sourcefilepathcontainerbase.h8
-rw-r--r--src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp16
-rw-r--r--src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.cpp129
-rw-r--r--src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.h82
-rw-r--r--src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp65
-rw-r--r--src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h17
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring-source.pri2
-rw-r--r--src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp52
-rw-r--r--src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h6
-rw-r--r--src/plugins/clangrefactoring/qtcreatorsearch.cpp25
-rw-r--r--src/plugins/clangrefactoring/qtcreatorsearch.h9
-rw-r--r--src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp23
-rw-r--r--src/plugins/clangrefactoring/qtcreatorsearchhandle.h16
-rw-r--r--src/plugins/clangrefactoring/refactoringclient.cpp45
-rw-r--r--src/plugins/clangrefactoring/refactoringclient.h24
-rw-r--r--src/plugins/clangrefactoring/searchhandle.cpp44
-rw-r--r--src/plugins/clangrefactoring/searchhandle.h56
-rw-r--r--src/plugins/clangrefactoring/searchhandleinterface.cpp9
-rw-r--r--src/plugins/clangrefactoring/searchhandleinterface.h23
-rw-r--r--src/plugins/clangrefactoring/searchinterface.cpp4
-rw-r--r--src/plugins/clangrefactoring/searchinterface.h7
m---------src/shared/qbs0
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquery.cpp51
-rw-r--r--src/tools/clangrefactoringbackend/source/clangquery.h3
-rw-r--r--src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri10
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.cpp18
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.h2
-rw-r--r--src/tools/clangrefactoringbackend/source/collectincludesaction.h88
-rw-r--r--src/tools/clangrefactoringbackend/source/collectincludespreprocessorcallbacks.h120
-rw-r--r--src/tools/clangrefactoringbackend/source/collectincludestoolaction.h54
-rw-r--r--src/tools/clangrefactoringbackend/source/includecollector.cpp75
-rw-r--r--src/tools/clangrefactoringbackend/source/includecollector.h49
-rw-r--r--src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.cpp (renamed from src/tools/clangrefactoringbackend/source/sourcefilecallbacks.cpp)12
-rw-r--r--src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h (renamed from src/tools/clangrefactoringbackend/source/sourcefilecallbacks.h)4
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.cpp48
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.h10
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcelocationsutils.h71
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp178
-rw-r--r--src/tools/clangrefactoringbackend/source/sourcerangeextractor.h88
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolfinder.cpp2
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolfinder.h4
-rw-r--r--tests/unit/unittest/clangquery-test.cpp4
-rw-r--r--tests/unit/unittest/clangquerycurrentfilefindfilter-test.cpp156
-rw-r--r--tests/unit/unittest/clangqueryprojectfindfilter-test.cpp92
-rw-r--r--tests/unit/unittest/data/sourcerangeextractor_location.cpp2
-rw-r--r--tests/unit/unittest/googletest.h4
-rw-r--r--tests/unit/unittest/gtest-clang-printing.cpp88
-rw-r--r--tests/unit/unittest/gtest-clang-printing.h50
-rw-r--r--tests/unit/unittest/mockrefactoringclient.h2
-rw-r--r--tests/unit/unittest/mockrefactoringserver.h3
-rw-r--r--tests/unit/unittest/mocksearch.h4
-rw-r--r--tests/unit/unittest/mocksearchhandle.h15
-rw-r--r--tests/unit/unittest/refactoringclient-test.cpp60
-rw-r--r--tests/unit/unittest/refactoringclientserverinprocess-test.cpp10
-rw-r--r--tests/unit/unittest/refactoringserver-test.cpp50
-rw-r--r--tests/unit/unittest/sourcerangecontainer-matcher.h4
-rw-r--r--tests/unit/unittest/sourcerangeextractor-test.cpp186
-rw-r--r--tests/unit/unittest/testclangtool.cpp53
-rw-r--r--tests/unit/unittest/testclangtool.h45
-rw-r--r--tests/unit/unittest/unittest.pro16
70 files changed, 1914 insertions, 646 deletions
diff --git a/src/libs/clangbackendipc/cancelmessage.cpp b/src/libs/clangbackendipc/cancelmessage.cpp
new file mode 100644
index 0000000000..470b8263c7
--- /dev/null
+++ b/src/libs/clangbackendipc/cancelmessage.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "cancelmessage.h"
+
+#include <QDebug>
+
+namespace ClangBackEnd {
+
+QDebug operator<<(QDebug debug, const CancelMessage &)
+{
+ debug.nospace() << "CancelMessage()";
+
+ return debug;
+}
+
+void PrintTo(const CancelMessage &, ::std::ostream* os)
+{
+ *os << "CancelMessage()";
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/cancelmessage.h b/src/libs/clangbackendipc/cancelmessage.h
new file mode 100644
index 0000000000..1107fee21e
--- /dev/null
+++ b/src/libs/clangbackendipc/cancelmessage.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** 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 "clangbackendipc_global.h"
+
+namespace ClangBackEnd {
+
+class CancelMessage
+{
+public:
+ friend QDataStream &operator<<(QDataStream &out, const CancelMessage &/*message*/)
+ {
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, CancelMessage &/*message*/)
+ {
+ return in;
+ }
+
+ friend bool operator==(const CancelMessage &/*first*/, const CancelMessage &/*second*/)
+ {
+ return true;
+ }
+};
+
+CMBIPC_EXPORT QDebug operator<<(QDebug debug, const CancelMessage &message);
+void PrintTo(const CancelMessage &message, ::std::ostream* os);
+
+DECLARE_MESSAGE(CancelMessage)
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri
index 8cc4a89171..ced97b0d31 100644
--- a/src/libs/clangbackendipc/clangbackendipc-lib.pri
+++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri
@@ -59,6 +59,7 @@ SOURCES += $$PWD/clangcodemodelserverinterface.cpp \
$$PWD/requestsourcelocationforrenamingmessage.cpp \
$$PWD/filepath.cpp \
$$PWD/sourcerangescontainer.cpp \
+ $$PWD/sourcefilepathcontainerbase.cpp \
$$PWD/sourcerangecontainerv2.cpp \
$$PWD/dynamicastmatcherdiagnosticcontainer.cpp \
$$PWD/dynamicastmatcherdiagnosticcontextcontainer.cpp \
@@ -66,7 +67,8 @@ SOURCES += $$PWD/clangcodemodelserverinterface.cpp \
$$PWD/requestsourcerangesanddiagnosticsforquerymessage.cpp \
$$PWD/sourcerangesanddiagnosticsforquerymessage.cpp \
$$PWD/sourcerangewithtextcontainer.cpp \
- $$PWD/filecontainerv2.cpp
+ $$PWD/filecontainerv2.cpp \
+ $$PWD/cancelmessage.cpp
HEADERS += \
$$PWD/clangcodemodelserverinterface.h \
@@ -130,6 +132,7 @@ HEADERS += \
$$PWD/requestsourcerangesanddiagnosticsforquerymessage.h \
$$PWD/sourcerangesanddiagnosticsforquerymessage.h \
$$PWD/sourcerangewithtextcontainer.h \
- $$PWD/filecontainerv2.h
+ $$PWD/filecontainerv2.h \
+ $$PWD/cancelmessage.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangbackendipc/clangbackendipc_global.h b/src/libs/clangbackendipc/clangbackendipc_global.h
index 33e1c8883d..306a9d085a 100644
--- a/src/libs/clangbackendipc/clangbackendipc_global.h
+++ b/src/libs/clangbackendipc/clangbackendipc_global.h
@@ -46,7 +46,7 @@
#endif
namespace Utils {
-template<uint Size>
+template <uint Size>
class BasicSmallString;
using SmallString = BasicSmallString<31>;
}
@@ -122,7 +122,9 @@ enum class MessageType : quint8 {
RequestSourceLocationsForRenamingMessage,
RequestSourceRangesAndDiagnosticsForQueryMessage,
- SourceRangesAndDiagnosticsForQueryMessage
+ SourceRangesAndDiagnosticsForQueryMessage,
+
+ CancelMessage
};
template<MessageType messageEnumeration>
diff --git a/src/libs/clangbackendipc/refactoringserverinterface.cpp b/src/libs/clangbackendipc/refactoringserverinterface.cpp
index fe1cc7103f..9e45779140 100644
--- a/src/libs/clangbackendipc/refactoringserverinterface.cpp
+++ b/src/libs/clangbackendipc/refactoringserverinterface.cpp
@@ -28,6 +28,7 @@
#include "messageenvelop.h"
#include "requestsourcelocationforrenamingmessage.h"
#include "requestsourcerangesanddiagnosticsforquerymessage.h"
+#include "cancelmessage.h"
#include <QDebug>
@@ -45,6 +46,9 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop)
case MessageType::RequestSourceRangesAndDiagnosticsForQueryMessage:
requestSourceRangesAndDiagnosticsForQueryMessage(messageEnvelop.message<RequestSourceRangesAndDiagnosticsForQueryMessage>());
break;
+ case MessageType::CancelMessage:
+ cancel();
+ break;
default:
qWarning() << "Unknown IpcClientMessage";
}
diff --git a/src/libs/clangbackendipc/refactoringserverinterface.h b/src/libs/clangbackendipc/refactoringserverinterface.h
index f06a5904bf..a22f4c1f1f 100644
--- a/src/libs/clangbackendipc/refactoringserverinterface.h
+++ b/src/libs/clangbackendipc/refactoringserverinterface.h
@@ -34,6 +34,7 @@ namespace ClangBackEnd {
class RefactoringClientInterface;
class RequestSourceLocationsForRenamingMessage;
class RequestSourceRangesAndDiagnosticsForQueryMessage;
+class CancelMessage;
class CMBIPC_EXPORT RefactoringServerInterface : public IpcServerInterface<RefactoringClientInterface>
{
@@ -43,6 +44,7 @@ public:
virtual void end() = 0;
virtual void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) = 0;
virtual void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) = 0;
+ virtual void cancel() = 0;
bool isUsable() const
{
diff --git a/src/libs/clangbackendipc/refactoringserverproxy.cpp b/src/libs/clangbackendipc/refactoringserverproxy.cpp
index be6ee5457c..77f7e7e6fa 100644
--- a/src/libs/clangbackendipc/refactoringserverproxy.cpp
+++ b/src/libs/clangbackendipc/refactoringserverproxy.cpp
@@ -25,6 +25,7 @@
#include "refactoringserverproxy.h"
+#include "cancelmessage.h"
#include "cmbendmessage.h"
#include "messageenvelop.h"
#include "refactoringclientinterface.h"
@@ -59,6 +60,11 @@ void RefactoringServerProxy::requestSourceRangesAndDiagnosticsForQueryMessage(Re
writeMessageBlock.write(message);
}
+void RefactoringServerProxy::cancel()
+{
+ writeMessageBlock.write(CancelMessage());
+}
+
void RefactoringServerProxy::readMessages()
{
for (const auto &message : readMessageBlock.readAll())
diff --git a/src/libs/clangbackendipc/refactoringserverproxy.h b/src/libs/clangbackendipc/refactoringserverproxy.h
index 43f1b354a3..44eb2065b2 100644
--- a/src/libs/clangbackendipc/refactoringserverproxy.h
+++ b/src/libs/clangbackendipc/refactoringserverproxy.h
@@ -42,7 +42,7 @@ namespace ClangBackEnd {
class RefactoringClientInterface;
-class CMBIPC_EXPORT RefactoringServerProxy : public RefactoringServerInterface
+class CMBIPC_EXPORT RefactoringServerProxy final : public RefactoringServerInterface
{
public:
explicit RefactoringServerProxy(RefactoringClientInterface *client, QIODevice *ioDevice);
@@ -50,8 +50,9 @@ public:
const RefactoringServerProxy &operator=(const RefactoringServerProxy&) = delete;
void end() override;
- void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override;
- void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message);
+ void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
+ void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
+ void cancel() override;
void readMessages();
diff --git a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h b/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h
index a6a2b50960..d56a536d1c 100644
--- a/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h
+++ b/src/libs/clangbackendipc/requestsourcerangesanddiagnosticsforquerymessage.h
@@ -25,13 +25,11 @@
#pragma once
-#include "clangbackendipc_global.h"
-
#include "filecontainerv2.h"
namespace ClangBackEnd {
-class CMBIPC_EXPORT RequestSourceRangesAndDiagnosticsForQueryMessage
+class RequestSourceRangesAndDiagnosticsForQueryMessage
{
public:
RequestSourceRangesAndDiagnosticsForQueryMessage() = default;
diff --git a/src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp b/src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp
new file mode 100644
index 0000000000..66d44d8827
--- /dev/null
+++ b/src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "sourcefilepathcontainerbase.h"
+
+namespace ClangBackEnd {
+
+
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/sourcefilepathcontainerbase.h b/src/libs/clangbackendipc/sourcefilepathcontainerbase.h
index fc59613a9c..40a5a68db6 100644
--- a/src/libs/clangbackendipc/sourcefilepathcontainerbase.h
+++ b/src/libs/clangbackendipc/sourcefilepathcontainerbase.h
@@ -44,9 +44,11 @@ public:
void insertFilePath(uint fileId, Utils::SmallString &&fileDirectory, Utils::SmallString &&fileName)
{
- filePathHash.emplace(std::piecewise_construct,
- std::forward_as_tuple(fileId),
- std::forward_as_tuple(std::move(fileDirectory), std::move(fileName)));
+ if (filePathHash.find(fileId) == filePathHash.end()) {
+ filePathHash.emplace(std::piecewise_construct,
+ std::forward_as_tuple(fileId),
+ std::forward_as_tuple(std::move(fileDirectory), std::move(fileName)));
+ }
}
void reserve(std::size_t size)
diff --git a/src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp b/src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp
index a418af0488..2be07150da 100644
--- a/src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp
+++ b/src/libs/clangbackendipc/sourcerangewithtextcontainer.cpp
@@ -25,6 +25,10 @@
#include "sourcerangewithtextcontainer.h"
+#ifdef UNIT_TESTS
+#include <gtest/gtest.h>
+#endif
+
namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const SourceRangeWithTextContainer &container)
@@ -40,12 +44,18 @@ QDebug operator<<(QDebug debug, const SourceRangeWithTextContainer &container)
void PrintTo(const SourceRangeWithTextContainer &container, ::std::ostream* os)
{
+ Q_UNUSED(container)
+ Q_UNUSED(os)
+#ifdef UNIT_TESTS
*os << "(("
<< container.start().line() << ", "
- << container.start().column() << "), ("
+ << container.start().column() << ", "
+ << container.start().offset() << "), ("
<< container.end().line() << ", "
<< container.end().column() << ", "
- << "\"" << container.text() << "\""
- << "))";
+ << container.end().offset() << "), "
+ << testing::PrintToString(container.text())
+ << ")";
+#endif
}
} // namespace ClangBackEnd
diff --git a/src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.cpp b/src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.cpp
deleted file mode 100644
index 5df78f9bdc..0000000000
--- a/src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-****************************************************************************/
-
-#include "clangquerycurrentfilefindfilter.h"
-
-#include "projectpartutilities.h"
-#include "refactoringclient.h"
-#include "refactoringcompileroptionsbuilder.h"
-#include "searchinterface.h"
-
-#include <refactoringserverinterface.h>
-#include <requestsourcerangesanddiagnosticsforquerymessage.h>
-
-namespace ClangRefactoring {
-
-ClangQueryCurrentFileFindFilter::ClangQueryCurrentFileFindFilter(
- ClangBackEnd::RefactoringServerInterface &server,
- SearchInterface &searchInterface,
- RefactoringClient &refactoringClient)
- : server(server),
- searchInterface(searchInterface),
- refactoringClient(refactoringClient)
-{
-}
-
-QString ClangQueryCurrentFileFindFilter::id() const
-{
- return QStringLiteral("Clang Query Current File");
-}
-
-QString ClangQueryCurrentFileFindFilter::displayName() const
-{
- return tr("Clang Query Current File");
-}
-
-bool ClangQueryCurrentFileFindFilter::isEnabled() const
-{
- return true;
-}
-
-void ClangQueryCurrentFileFindFilter::findAll(const QString &queryText, Core::FindFlags)
-{
- searchHandle = searchInterface.startNewSearch(tr("Clang Query"), queryText);
-
- refactoringClient.setSearchHandle(searchHandle.get());
-
- server.requestSourceRangesAndDiagnosticsForQueryMessage(createMessage(queryText));
-}
-
-Core::FindFlags ClangQueryCurrentFileFindFilter::supportedFindFlags() const
-{
- return 0;
-}
-
-void ClangQueryCurrentFileFindFilter::setCurrentDocumentFilePath(const QString &filePath)
-{
- currentDocumentFilePath = filePath;
-}
-
-void ClangQueryCurrentFileFindFilter::setUnsavedDocumentContent(const QString &unsavedContent)
-{
- unsavedDocumentContent = unsavedContent;
-}
-
-void ClangQueryCurrentFileFindFilter::setProjectPart(const CppTools::ProjectPart::Ptr &projectPart)
-{
- this->projectPart = projectPart;
-}
-
-void ClangQueryCurrentFileFindFilter::setUsable(bool isUsable)
-{
- server.setUsable(isUsable);
-}
-
-bool ClangQueryCurrentFileFindFilter::isUsable() const
-{
- return server.isUsable();
-}
-
-ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage
-ClangQueryCurrentFileFindFilter::createMessage(const QString &queryText) const
-{
- std::vector<ClangBackEnd::V2::FileContainer> fileContainers;
- fileContainers.emplace_back(ClangBackEnd::FilePath(currentDocumentFilePath),
- unsavedDocumentContent,
- createCommandLine());
-
- return ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage(
- Utils::SmallString(queryText),
- std::move(fileContainers));
-}
-
-Utils::SmallStringVector ClangQueryCurrentFileFindFilter::createCommandLine() const
-{
- using ClangRefactoring::RefactoringCompilerOptionsBuilder;
-
- auto commandLine = RefactoringCompilerOptionsBuilder::build(
- projectPart.data(),
- fileKindInProjectPart(projectPart.data(), currentDocumentFilePath),
- RefactoringCompilerOptionsBuilder::PchUsage::None);
-
- commandLine.push_back(currentDocumentFilePath);
-
- return commandLine;
-}
-
-} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.h b/src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.h
deleted file mode 100644
index d51f862613..0000000000
--- a/src/plugins/clangrefactoring/clangquerycurrentfilefindfilter.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** 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 "searchhandleinterface.h"
-
-#include <cpptools/projectpart.h>
-
-#include <coreplugin/find/ifindfilter.h>
-
-#include <utils/smallstringvector.h>
-
-namespace ClangBackEnd {
-class RefactoringServerInterface;
-class RequestSourceRangesAndDiagnosticsForQueryMessage;
-}
-
-namespace ClangRefactoring {
-
-class RefactoringClient;
-class SearchInterface;
-
-class ClangQueryCurrentFileFindFilter : public Core::IFindFilter
-{
-public:
- ClangQueryCurrentFileFindFilter(ClangBackEnd::RefactoringServerInterface &server,
- SearchInterface &searchInterface,
- RefactoringClient &refactoringClient);
- QString id() const;
- QString displayName() const;
- bool isEnabled() const;
- void findAll(const QString &queryText, Core::FindFlags findFlags = 0);
- Core::FindFlags supportedFindFlags() const;
-
- void setCurrentDocumentFilePath(const QString &filePath);
- void setUnsavedDocumentContent(const QString &unsavedContent);
- void setCurrentDocumentRevision(int revision);
- void setProjectPart(const CppTools::ProjectPart::Ptr &projectPart);
-
- void setUsable(bool isUsable);
- bool isUsable() const;
-
-private:
- ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage createMessage(
- const QString &queryText) const;
-
- Utils::SmallStringVector createCommandLine() const;
-
-private:
- QString currentDocumentFilePath;
- QString unsavedDocumentContent;
- std::unique_ptr<SearchHandleInterface> searchHandle;
- CppTools::ProjectPart::Ptr projectPart;
- ClangBackEnd::RefactoringServerInterface &server;
- SearchInterface &searchInterface;
- RefactoringClient &refactoringClient;
-};
-
-} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
index 56f9dc1e21..a97658db0d 100644
--- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
+++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
@@ -25,10 +25,13 @@
#include "clangqueryprojectsfindfilter.h"
+#include "projectpartutilities.h"
#include "refactoringclient.h"
+#include "refactoringcompileroptionsbuilder.h"
#include "searchinterface.h"
#include <refactoringserverinterface.h>
+#include <requestsourcerangesanddiagnosticsforquerymessage.h>
namespace ClangRefactoring {
@@ -61,9 +64,15 @@ void ClangQueryProjectsFindFilter::findAll(const QString &queryText, Core::FindF
{
searchHandle = searchInterface.startNewSearch(tr("Clang Query"), queryText);
+ searchHandle->setRefactoringServer(&server);
+
refactoringClient.setSearchHandle(searchHandle.get());
- //server.requestSourceRangesAndDiagnosticsForQueryMessage(createMessage(queryText));
+ auto message = createMessage(queryText);
+
+ refactoringClient.setExpectedResultCount(message.fileContainers().size());
+
+ server.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message));
}
Core::FindFlags ClangQueryProjectsFindFilter::supportedFindFlags() const
@@ -71,6 +80,11 @@ Core::FindFlags ClangQueryProjectsFindFilter::supportedFindFlags() const
return 0;
}
+void ClangQueryProjectsFindFilter::setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts)
+{
+ this->projectParts = projectParts;
+}
+
bool ClangQueryProjectsFindFilter::isUsable() const
{
return server.isUsable();
@@ -81,4 +95,53 @@ void ClangQueryProjectsFindFilter::setUsable(bool isUsable)
server.setUsable(isUsable);
}
+SearchHandle *ClangQueryProjectsFindFilter::searchHandleForTestOnly() const
+{
+ return searchHandle.get();
+}
+
+namespace {
+
+Utils::SmallStringVector createCommandLine(CppTools::ProjectPart *projectPart,
+ const QString &documentFilePath,
+ CppTools::ProjectFile::Kind fileKind)
+{
+ using ClangRefactoring::RefactoringCompilerOptionsBuilder;
+
+ auto commandLine = RefactoringCompilerOptionsBuilder::build(projectPart,
+ fileKind,
+ CppTools::CompilerOptionsBuilder::PchUsage::None);
+
+ commandLine.push_back(documentFilePath);
+
+ return commandLine;
+}
+
+std::vector<ClangBackEnd::V2::FileContainer>
+createFileContainers(const std::vector<CppTools::ProjectPart::Ptr> &projectParts)
+{
+ std::vector<ClangBackEnd::V2::FileContainer> fileContainers;
+
+ for (const CppTools::ProjectPart::Ptr &projectPart : projectParts) {
+ for (const CppTools::ProjectFile &projectFile : projectPart->files) {
+ fileContainers.emplace_back(ClangBackEnd::FilePath(projectFile.path),
+ "",
+ createCommandLine(projectPart.data(),
+ projectFile.path,
+ projectFile.kind));
+ }
+ }
+
+ return fileContainers;
+}
+}
+
+ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage ClangQueryProjectsFindFilter::createMessage(const QString &queryText) const
+{
+ return ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage(
+ Utils::SmallString(queryText),
+ createFileContainers(projectParts));
+}
+
+
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h
index 5cefbe5d21..29bd24a0bc 100644
--- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h
+++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h
@@ -25,10 +25,14 @@
#pragma once
-#include "searchhandleinterface.h"
+#include "searchhandle.h"
+
+#include <cpptools/projectpart.h>
#include <coreplugin/find/ifindfilter.h>
+#include <utils/smallstringvector.h>
+
#include <memory>
namespace ClangBackEnd {
@@ -54,11 +58,20 @@ public:
void findAll(const QString &queryText, Core::FindFlags findFlags = 0);
Core::FindFlags supportedFindFlags() const;
+ void setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts);
+
bool isUsable() const;
void setUsable(bool isUsable);
+ SearchHandle* searchHandleForTestOnly() const;
+
+private:
+ ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage createMessage(
+ const QString &queryText) const;
+
private:
- std::unique_ptr<SearchHandleInterface> searchHandle;
+ std::unique_ptr<SearchHandle> searchHandle;
+ std::vector<CppTools::ProjectPart::Ptr> projectParts;
ClangBackEnd::RefactoringServerInterface &server;
SearchInterface &searchInterface;
RefactoringClient &refactoringClient;
diff --git a/src/plugins/clangrefactoring/clangrefactoring-source.pri b/src/plugins/clangrefactoring/clangrefactoring-source.pri
index f3d0297bc9..52093ffbda 100644
--- a/src/plugins/clangrefactoring/clangrefactoring-source.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring-source.pri
@@ -8,7 +8,6 @@ HEADERS += \
$$PWD/searchinterface.h \
$$PWD/searchhandleinterface.h \
$$PWD/projectpartutilities.h \
- $$PWD/clangquerycurrentfilefindfilter.h \
$$PWD/clangqueryprojectsfindfilter.h
SOURCES += \
@@ -19,5 +18,4 @@ SOURCES += \
$$PWD/searchinterface.cpp \
$$PWD/searchhandleinterface.cpp \
$$PWD/projectpartutilities.cpp \
- $$PWD/clangquerycurrentfilefindfilter.cpp \
$$PWD/clangqueryprojectsfindfilter.cpp
diff --git a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp
index 2a4e0de514..4dcdec43b2 100644
--- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp
+++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp
@@ -25,66 +25,48 @@
#include "qtcreatorclangqueryfindfilter.h"
-#include <texteditor/textdocument.h>
-
#include <cpptools/cppmodelmanager.h>
-#include <cpptools/baseeditordocumentparser.h>
+#include <cpptools/projectinfo.h>
-#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/editormanager/ieditor.h>
+#include <projectexplorer/session.h>
namespace ClangRefactoring {
QtCreatorClangQueryFindFilter::QtCreatorClangQueryFindFilter(ClangBackEnd::RefactoringServerInterface &server,
SearchInterface &searchInterface,
RefactoringClient &refactoringClient)
- : ClangQueryCurrentFileFindFilter(server, searchInterface, refactoringClient)
+ : ClangQueryProjectsFindFilter(server, searchInterface, refactoringClient)
{
}
-namespace {
-CppTools::CppModelManager *cppToolManager()
+void QtCreatorClangQueryFindFilter::findAll(const QString &queryText, Core::FindFlags findFlags)
{
- return CppTools::CppModelManager::instance();
-}
+ prepareFind();
-bool isCppEditor(Core::IEditor *currentEditor)
-{
- return cppToolManager()->isCppEditor(currentEditor);
+ ClangQueryProjectsFindFilter::findAll(queryText, findFlags);
}
-CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath)
+namespace {
+std::vector<CppTools::ProjectPart::Ptr>
+convertProjectParts(const QList<CppTools::ProjectPart::Ptr> &projectPartList)
{
- if (const auto parser = CppTools::BaseEditorDocumentParser::get(filePath))
- return parser->projectPart();
- return CppTools::ProjectPart::Ptr();
-}
+ std::vector<CppTools::ProjectPart::Ptr> projectPartVector;
+ projectPartVector.reserve(projectPartList.size());
-}
+ std::copy(projectPartList.begin(), projectPartList.end(), std::back_inserter(projectPartVector));
-void QtCreatorClangQueryFindFilter::findAll(const QString &queryText, Core::FindFlags findFlags)
-{
- prepareFind();
+ return projectPartVector;
+}
- ClangQueryCurrentFileFindFilter::findAll(queryText, findFlags);
}
void QtCreatorClangQueryFindFilter::prepareFind()
{
- Core::IEditor *currentEditor = Core::EditorManager::currentEditor();
-
- if (isCppEditor(currentEditor)) {
- Core::IDocument *currentDocument = currentEditor->document();
- auto currentTextDocument = static_cast<TextEditor::TextDocument*>(currentDocument);
- const QString filePath = currentDocument->filePath().toString();
+ ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::startupProject();
- setCurrentDocumentFilePath(filePath);
- setCurrentDocumentRevision(currentTextDocument->document()->revision());
- setProjectPart(projectPartForFile(filePath));
+ const CppTools::ProjectInfo projectInfo = CppTools::CppModelManager::instance()->projectInfo(currentProject);
- if (currentTextDocument->isModified())
- setUnsavedDocumentContent(currentTextDocument->document()->toPlainText());
- }
+ setProjectParts(convertProjectParts(projectInfo.projectParts()));
}
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h
index 937e591a7c..8157779bc9 100644
--- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h
+++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h
@@ -25,18 +25,18 @@
#pragma once
-#include "clangquerycurrentfilefindfilter.h"
+#include "clangqueryprojectsfindfilter.h"
namespace ClangRefactoring {
-class QtCreatorClangQueryFindFilter final : public ClangQueryCurrentFileFindFilter
+class QtCreatorClangQueryFindFilter final : public ClangQueryProjectsFindFilter
{
public:
QtCreatorClangQueryFindFilter(ClangBackEnd::RefactoringServerInterface &server,
SearchInterface &searchInterface,
RefactoringClient &refactoringClient);
- void findAll(const QString &queryText, Core::FindFlags findFlags = 0);
+ void findAll(const QString &queryText, Core::FindFlags findFlags = 0) override;
private:
void prepareFind();
diff --git a/src/plugins/clangrefactoring/qtcreatorsearch.cpp b/src/plugins/clangrefactoring/qtcreatorsearch.cpp
index 43d303e198..61f317c22a 100644
--- a/src/plugins/clangrefactoring/qtcreatorsearch.cpp
+++ b/src/plugins/clangrefactoring/qtcreatorsearch.cpp
@@ -27,6 +27,10 @@
#include "qtcreatorsearchhandle.h"
+#include <coreplugin/editormanager/editormanager.h>
+
+#include <QDir>
+
namespace ClangRefactoring {
QtCreatorSearch::QtCreatorSearch(Core::SearchResultWindow &searchResultWindow)
@@ -34,7 +38,7 @@ QtCreatorSearch::QtCreatorSearch(Core::SearchResultWindow &searchResultWindow)
{
}
-std::unique_ptr<SearchHandleInterface> QtCreatorSearch::startNewSearch(const QString &searchLabel,
+std::unique_ptr<SearchHandle> QtCreatorSearch::startNewSearch(const QString &searchLabel,
const QString &searchTerm)
{
Core::SearchResult *searchResult = searchResultWindow.startNewSearch(
@@ -44,7 +48,24 @@ std::unique_ptr<SearchHandleInterface> QtCreatorSearch::startNewSearch(const QSt
Core::SearchResultWindow::SearchOnly,
Core::SearchResultWindow::PreserveCaseEnabled);
- return std::unique_ptr<SearchHandleInterface>(new QtCreatorSearchHandle(searchResult));
+ QObject::connect(searchResult,
+ &Core::SearchResult::activated,
+ &QtCreatorSearch::openEditor);
+
+ auto searchHandle = std::unique_ptr<SearchHandle>(new QtCreatorSearchHandle(searchResult));
+
+ QObject::connect(searchResult,
+ &Core::SearchResult::cancelled,
+ [handle=searchHandle.get()] () { handle->cancel(); });
+
+ return searchHandle;
+}
+
+void QtCreatorSearch::openEditor(const Core::SearchResultItem &item)
+{
+ Core::EditorManager::openEditorAt(QDir::fromNativeSeparators(item.path.first()),
+ item.mainRange.begin.line,
+ item.mainRange.begin.column);
}
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/qtcreatorsearch.h b/src/plugins/clangrefactoring/qtcreatorsearch.h
index 50c2f629ea..68d884a180 100644
--- a/src/plugins/clangrefactoring/qtcreatorsearch.h
+++ b/src/plugins/clangrefactoring/qtcreatorsearch.h
@@ -29,6 +29,10 @@
#include <coreplugin/find/searchresultwindow.h>
+namespace Core {
+class SearchResultItem;
+}
+
namespace ClangRefactoring {
class QtCreatorSearch final : public SearchInterface
@@ -36,10 +40,13 @@ class QtCreatorSearch final : public SearchInterface
public:
QtCreatorSearch(Core::SearchResultWindow &searchResultWindow);
- std::unique_ptr<SearchHandleInterface> startNewSearch(const QString &searchLabel,
+ std::unique_ptr<SearchHandle> startNewSearch(const QString &searchLabel,
const QString &searchTerm);
private:
+ static void openEditor(const Core::SearchResultItem &item);
+
+private:
Core::SearchResultWindow &searchResultWindow;
};
diff --git a/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp b/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp
index 5f16d5dfcb..6308c641ec 100644
--- a/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp
+++ b/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp
@@ -25,21 +25,40 @@
#include "qtcreatorsearchhandle.h"
+#include <coreplugin/progressmanager/progressmanager.h>
+
+#include <QCoreApplication>
+
namespace ClangRefactoring {
QtCreatorSearchHandle::QtCreatorSearchHandle(Core::SearchResult *searchResult)
: searchResult(searchResult)
{
+ auto title = QCoreApplication::translate("QtCreatorSearchHandle", "Clang Query");
+ Core::ProgressManager::addTask(promise.future(), title, "clang query", 0);
+}
+
+void QtCreatorSearchHandle::addResult(const QString &fileName,
+ const QString &lineText,
+ Core::TextRange textRange)
+{
+ searchResult->addResult(fileName, lineText, textRange);
+}
+
+void QtCreatorSearchHandle::setExpectedResultCount(uint count)
+{
+ promise.setExpectedResultCount(count);
}
-void QtCreatorSearchHandle::addResult(const QString &fileName, int lineNumber, const QString &lineText, int searchTermStart, int searchTermLength)
+void QtCreatorSearchHandle::setResultCounter(uint counter)
{
- searchResult->addResult(fileName, lineNumber, lineText, searchTermStart, searchTermLength);
+ promise.setProgressValue(counter);
}
void QtCreatorSearchHandle::finishSearch()
{
searchResult->finishSearch(false);
+ promise.reportFinished();
}
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/qtcreatorsearchhandle.h b/src/plugins/clangrefactoring/qtcreatorsearchhandle.h
index a0741ba9f9..76932edb1f 100644
--- a/src/plugins/clangrefactoring/qtcreatorsearchhandle.h
+++ b/src/plugins/clangrefactoring/qtcreatorsearchhandle.h
@@ -25,27 +25,31 @@
#pragma once
-#include "searchhandleinterface.h"
+#include "searchhandle.h"
#include <coreplugin/find/searchresultwindow.h>
+#include <QFutureInterface>
+
namespace ClangRefactoring {
-class QtCreatorSearchHandle final : public SearchHandleInterface
+class QtCreatorSearchHandle final : public SearchHandle
{
public:
QtCreatorSearchHandle(Core::SearchResult *searchResult);
void addResult(const QString &fileName,
- int lineNumber,
const QString &lineText,
- int searchTermStart,
- int searchTermLength);
+ Core::TextRange textRange) override;
+
+ void setExpectedResultCount(uint count) override;
+ void setResultCounter(uint counter) override;
- void finishSearch();
+ void finishSearch() override;
private:
Core::SearchResult *searchResult;
+ QFutureInterface<void> promise;
};
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/refactoringclient.cpp b/src/plugins/clangrefactoring/refactoringclient.cpp
index 87ee586430..da0701c2f5 100644
--- a/src/plugins/clangrefactoring/refactoringclient.cpp
+++ b/src/plugins/clangrefactoring/refactoringclient.cpp
@@ -48,8 +48,9 @@ void RefactoringClient::sourceLocationsForRenamingMessage(
void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage(
ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message)
{
+ ++resultCounter_;
addSearchResults(message.sourceRanges());
- sendSearchIsFinished();
+ setResultCounterAndSendSearchIsFinishedIfFinished();
}
void RefactoringClient::setLocalRenamingCallback(
@@ -63,14 +64,14 @@ void RefactoringClient::setRefactoringEngine(RefactoringEngine *refactoringEngin
this->refactoringEngine = refactoringEngine;
}
-void RefactoringClient::setSearchHandle(SearchHandleInterface *searchHandleInterface)
+void RefactoringClient::setSearchHandle(SearchHandle *searchHandle)
{
- this->searchHandleInterface = searchHandleInterface;
+ this->searchHandle_ = searchHandle;
}
-SearchHandleInterface *RefactoringClient::searchHandle() const
+SearchHandle *RefactoringClient::searchHandle() const
{
- return searchHandleInterface;
+ return searchHandle_;
}
bool RefactoringClient::hasValidLocalRenamingCallback() const
@@ -78,6 +79,23 @@ bool RefactoringClient::hasValidLocalRenamingCallback() const
return bool(localRenamingCallback);
}
+void RefactoringClient::setExpectedResultCount(uint count)
+{
+ expectedResultCount_ = count;
+ resultCounter_ = 0;
+ searchHandle_->setExpectedResultCount(count);
+}
+
+uint RefactoringClient::expectedResultCount() const
+{
+ return expectedResultCount_;
+}
+
+uint RefactoringClient::resultCounter() const
+{
+ return resultCounter_;
+}
+
namespace {
Utils::SmallString concatenateFilePath(const ClangBackEnd::FilePath &filePath)
@@ -122,16 +140,19 @@ void RefactoringClient::addSearchResults(const ClangBackEnd::SourceRangesContain
void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText,
std::unordered_map<uint, QString> &filePaths)
{
- searchHandleInterface->addResult(filePaths[sourceRangeWithText.fileHash()],
- int(sourceRangeWithText.start().line()),
- sourceRangeWithText.text(),
- int(sourceRangeWithText.start().column()),
- int(sourceRangeWithText.end().column()));
+ searchHandle_->addResult(filePaths[sourceRangeWithText.fileHash()],
+ sourceRangeWithText.text(),
+ {{int(sourceRangeWithText.start().line()),
+ int(sourceRangeWithText.start().column())},
+ {int(sourceRangeWithText.end().line()),
+ int(sourceRangeWithText.end().column())}});
}
-void RefactoringClient::sendSearchIsFinished()
+void RefactoringClient::setResultCounterAndSendSearchIsFinishedIfFinished()
{
- searchHandleInterface->finishSearch();
+ searchHandle_->setResultCounter(resultCounter_);
+ if (resultCounter_ == expectedResultCount_)
+ searchHandle_->finishSearch();
}
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/refactoringclient.h b/src/plugins/clangrefactoring/refactoringclient.h
index aa8b9a4e59..c1de5fff31 100644
--- a/src/plugins/clangrefactoring/refactoringclient.h
+++ b/src/plugins/clangrefactoring/refactoringclient.h
@@ -27,7 +27,7 @@
#include "refactoringengine.h"
-#include <searchhandleinterface.h>
+#include <searchhandle.h>
#include <refactoringclientinterface.h>
@@ -53,23 +53,35 @@ public:
void setLocalRenamingCallback(
CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) final;
void setRefactoringEngine(ClangRefactoring::RefactoringEngine *refactoringEngine);
- void setSearchHandle(ClangRefactoring::SearchHandleInterface *searchHandleInterface);
- ClangRefactoring::SearchHandleInterface *searchHandle() const;
+ void setSearchHandle(ClangRefactoring::SearchHandle *searchHandleInterface);
+ ClangRefactoring::SearchHandle *searchHandle() const;
bool hasValidLocalRenamingCallback() const;
static std::unordered_map<uint, QString> convertFilePaths(
const std::unordered_map<uint, ClangBackEnd::FilePath> &filePaths);
-private:
- void addSearchResults(const ClangBackEnd::SourceRangesContainer &sourceRanges);
+ void setExpectedResultCount(uint count);
+ uint expectedResultCount() const;
+ uint resultCounter() const;
+
+
+UNIT_TEST_PUBLIC:
void addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRange,
std::unordered_map<uint, QString> &filePaths);
+
+private:
+ void addSearchResults(const ClangBackEnd::SourceRangesContainer &sourceRanges);
+
+ void setResultCounterAndSendSearchIsFinishedIfFinished();
void sendSearchIsFinished();
+
private:
CppTools::RefactoringEngineInterface::RenameCallback localRenamingCallback;
- ClangRefactoring::SearchHandleInterface *searchHandleInterface = nullptr;
+ ClangRefactoring::SearchHandle *searchHandle_ = nullptr;
ClangRefactoring::RefactoringEngine *refactoringEngine = nullptr;
+ uint expectedResultCount_ = 0;
+ uint resultCounter_ = 0;
};
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/searchhandle.cpp b/src/plugins/clangrefactoring/searchhandle.cpp
new file mode 100644
index 0000000000..c73aa4e96c
--- /dev/null
+++ b/src/plugins/clangrefactoring/searchhandle.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "searchhandle.h"
+
+namespace ClangRefactoring {
+
+SearchHandle::~SearchHandle()
+{
+}
+
+void SearchHandle::cancel()
+{
+ server->cancel();
+}
+
+void SearchHandle::setRefactoringServer(ClangBackEnd::RefactoringServerInterface *server)
+{
+ this->server = server;
+}
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/searchhandle.h b/src/plugins/clangrefactoring/searchhandle.h
new file mode 100644
index 0000000000..185be306a2
--- /dev/null
+++ b/src/plugins/clangrefactoring/searchhandle.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** 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 <coreplugin/find/searchresultitem.h>
+
+#include <refactoringserverinterface.h>
+
+namespace ClangRefactoring {
+
+class SearchHandle
+{
+public:
+ virtual ~SearchHandle();
+
+ virtual void addResult(const QString &fileName,
+ const QString &lineText,
+ Core::Search::TextRange textRange) = 0;
+
+ virtual void setExpectedResultCount(uint count) = 0;
+ virtual void setResultCounter(uint counter) = 0;
+
+ virtual void finishSearch() = 0;
+
+ void cancel();
+
+ void setRefactoringServer(ClangBackEnd::RefactoringServerInterface *server);
+
+private:
+ ClangBackEnd::RefactoringServerInterface *server = nullptr;
+};
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/searchhandleinterface.cpp b/src/plugins/clangrefactoring/searchhandleinterface.cpp
index 6be77457cb..8eed7e59be 100644
--- a/src/plugins/clangrefactoring/searchhandleinterface.cpp
+++ b/src/plugins/clangrefactoring/searchhandleinterface.cpp
@@ -27,13 +27,18 @@
namespace ClangRefactoring {
-SearchHandleInterface::SearchHandleInterface()
+SearchHandle::~SearchHandle()
{
+}
+void SearchHandle::cancel()
+{
+ server->cancel();
}
-SearchHandleInterface::~SearchHandleInterface()
+void SearchHandle::setRefactoringServer(ClangBackEnd::RefactoringServerInterface *server)
{
+ this->server = server;
}
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/searchhandleinterface.h b/src/plugins/clangrefactoring/searchhandleinterface.h
index 7e41cc7f32..185be306a2 100644
--- a/src/plugins/clangrefactoring/searchhandleinterface.h
+++ b/src/plugins/clangrefactoring/searchhandleinterface.h
@@ -25,23 +25,32 @@
#pragma once
-#include <QString>
+#include <coreplugin/find/searchresultitem.h>
+
+#include <refactoringserverinterface.h>
namespace ClangRefactoring {
-class SearchHandleInterface
+class SearchHandle
{
public:
- SearchHandleInterface();
- virtual ~SearchHandleInterface();
+ virtual ~SearchHandle();
virtual void addResult(const QString &fileName,
- int lineNumber,
const QString &lineText,
- int searchTermStart,
- int searchTermLength) = 0;
+ Core::Search::TextRange textRange) = 0;
+
+ virtual void setExpectedResultCount(uint count) = 0;
+ virtual void setResultCounter(uint counter) = 0;
virtual void finishSearch() = 0;
+
+ void cancel();
+
+ void setRefactoringServer(ClangBackEnd::RefactoringServerInterface *server);
+
+private:
+ ClangBackEnd::RefactoringServerInterface *server = nullptr;
};
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/searchinterface.cpp b/src/plugins/clangrefactoring/searchinterface.cpp
index f39d38e04c..666da7eb26 100644
--- a/src/plugins/clangrefactoring/searchinterface.cpp
+++ b/src/plugins/clangrefactoring/searchinterface.cpp
@@ -27,5 +27,9 @@
namespace ClangRefactoring {
+SearchInterface::~SearchInterface()
+{
+
+}
} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/searchinterface.h b/src/plugins/clangrefactoring/searchinterface.h
index 32ef07b080..72e921b76f 100644
--- a/src/plugins/clangrefactoring/searchinterface.h
+++ b/src/plugins/clangrefactoring/searchinterface.h
@@ -25,7 +25,7 @@
#pragma once
-#include "searchhandleinterface.h"
+#include "searchhandle.h"
#include <QString>
@@ -36,9 +36,8 @@ namespace ClangRefactoring {
class SearchInterface
{
public:
- virtual ~SearchInterface() {}
-
- virtual std::unique_ptr<SearchHandleInterface> startNewSearch(const QString &searchLabel,
+ virtual ~SearchInterface();
+ virtual std::unique_ptr<SearchHandle> startNewSearch(const QString &searchLabel,
const QString &searchTerm) = 0;
};
diff --git a/src/shared/qbs b/src/shared/qbs
-Subproject ab14d325eaa1ee762dacc8b9fbbc902dae4d5e6
+Subproject 0971e0b7453439f01c72551870d8a2a14075859
diff --git a/src/tools/clangrefactoringbackend/source/clangquery.cpp b/src/tools/clangrefactoringbackend/source/clangquery.cpp
index 2fd5b0689b..95ec23affb 100644
--- a/src/tools/clangrefactoringbackend/source/clangquery.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangquery.cpp
@@ -26,6 +26,7 @@
#include "clangquery.h"
#include "sourcelocationsutils.h"
+#include "sourcerangeextractor.h"
#include <sourcerangescontainer.h>
@@ -76,16 +77,7 @@ void ClangQuery::findLocations()
std::vector<std::unique_ptr<clang::ASTUnit>> asts;
- {
- QTime timer;
- timer.start();
- tool.buildASTs(asts);
-
- qWarning() << "ASTs are built: " << timer.elapsed();
- }
-
- std::vector<clang::SourceRange> sourceRanges;
- sourceRanges.reserve(100);
+ tool.buildASTs(asts);
std::for_each (std::make_move_iterator(asts.begin()),
std::make_move_iterator(asts.end()),
@@ -95,7 +87,7 @@ void ClangQuery::findLocations()
nullptr,
&diagnostics);
parseDiagnostics(diagnostics);
- matchLocation(optionalMatcher, std::move(ast), sourceRanges);
+ matchLocation(optionalMatcher, std::move(ast));
});
}
@@ -189,10 +181,28 @@ void ClangQuery::parseDiagnostics(const clang::ast_matchers::dynamic::Diagnostic
}
}
+namespace {
+std::vector<clang::SourceRange> generateSourceRangesFromMatches(const std::vector<BoundNodes> &matches)
+{
+ std::vector<clang::SourceRange> sourceRanges;
+ sourceRanges.reserve(matches.size());
+
+ for (const auto boundNodes : matches) {
+ for (const auto &mapEntry : boundNodes.getMap()) {
+ const auto sourceRange = mapEntry.second.getSourceRange();
+ if (sourceRange.isValid())
+ sourceRanges.push_back(sourceRange);
+ }
+
+ }
+
+ return sourceRanges;
+}
+}
+
void ClangQuery::matchLocation(
const llvm::Optional< clang::ast_matchers::internal::DynTypedMatcher> &optionalStartMatcher,
- std::unique_ptr<clang::ASTUnit> ast,
- std::vector<clang::SourceRange> &sourceRanges)
+ std::unique_ptr<clang::ASTUnit> ast)
{
if (optionalStartMatcher) {
auto matcher = *optionalStartMatcher;
@@ -207,18 +217,13 @@ void ClangQuery::matchLocation(
finder.matchAST(ast->getASTContext());
- for (const auto &boundNodes : matches) {
- for (const auto &mapEntry : boundNodes.getMap()) {
- const auto sourceRange = mapEntry.second.getSourceRange();
- if (sourceRange.isValid())
- sourceRanges.push_back(sourceRange);
- }
+ auto sourceRanges = generateSourceRangesFromMatches(matches);
- }
+ SourceRangeExtractor extractor(ast->getSourceManager(),
+ ast->getLangOpts(),
+ sourceRangesContainer);
+ extractor.addSourceRanges(sourceRanges);
- appendSourceRangesToSourceRangesContainer(sourceRangesContainer,
- sourceRanges,
- ast->getSourceManager());
}
}
diff --git a/src/tools/clangrefactoringbackend/source/clangquery.h b/src/tools/clangrefactoringbackend/source/clangquery.h
index b1a5be3648..93190449a5 100644
--- a/src/tools/clangrefactoringbackend/source/clangquery.h
+++ b/src/tools/clangrefactoringbackend/source/clangquery.h
@@ -61,8 +61,7 @@ public:
private:
void parseDiagnostics(const clang::ast_matchers::dynamic::Diagnostics &diagnostics);
void matchLocation(const llvm::Optional< clang::ast_matchers::internal::DynTypedMatcher> &optionalStartMatcher,
- std::unique_ptr<clang::ASTUnit> ast,
- std::vector<clang::SourceRange> &sourceRanges);
+ std::unique_ptr<clang::ASTUnit> ast);
private:
SourceRangesContainer sourceRangesContainer;
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
index 45eb821a18..3cd46a5e25 100644
--- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
+++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
@@ -5,11 +5,12 @@ SOURCES += \
$$PWD/symbolfinder.cpp \
$$PWD/symbollocationfinderaction.cpp \
$$PWD/refactoringserver.cpp \
- $$PWD/sourcefilecallbacks.cpp \
$$PWD/macropreprocessorcallbacks.cpp \
$$PWD/findusrforcursoraction.cpp \
$$PWD/clangquery.cpp \
- $$PWD/clangtool.cpp
+ $$PWD/clangtool.cpp \
+ $$PWD/sourcerangeextractor.cpp \
+ $$PWD/locationsourcefilecallbacks.cpp
HEADERS += \
$$PWD/refactoringcompilationdatabase.h \
@@ -17,11 +18,12 @@ HEADERS += \
$$PWD/symbolfinder.h \
$$PWD/symbollocationfinderaction.h \
$$PWD/refactoringserver.h \
- $$PWD/sourcefilecallbacks.h \
$$PWD/macropreprocessorcallbacks.h \
$$PWD/sourcelocationsutils.h \
$$PWD/findcursorusr.h \
$$PWD/findusrforcursoraction.h \
$$PWD/findlocationsofusrs.h \
$$PWD/clangquery.h \
- $$PWD/clangtool.h
+ $$PWD/clangtool.h \
+ $$PWD/sourcerangeextractor.h \
+ $$PWD/locationsourcefilecallbacks.h
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.cpp b/src/tools/clangrefactoringbackend/source/clangtool.cpp
index d447121379..aaef2845e0 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangtool.cpp
@@ -57,6 +57,24 @@ void ClangTool::addFile(std::string &&directory,
sourceFilePaths.push_back(fileContent.filePath);
}
+void ClangTool::addFiles(const Utils::SmallStringVector &filePaths,
+ const Utils::SmallStringVector &arguments)
+{
+ for (const Utils::SmallString &filePath : filePaths) {
+ auto found = std::find(filePath.rbegin(), filePath.rend(), '/');
+
+ auto fileNameBegin = found.base();
+
+ std::vector<std::string> commandLine(arguments.begin(), arguments.end());
+ commandLine.push_back(filePath);
+
+ addFile({filePath.begin(), std::prev(fileNameBegin)},
+ {fileNameBegin, filePath.end()},
+ {},
+ std::move(commandLine));
+ }
+}
+
clang::tooling::ClangTool ClangTool::createTool() const
{
clang::tooling::ClangTool tool(compilationDatabase, sourceFilePaths);
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h
index 8627798d97..b16b7a94dd 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.h
+++ b/src/tools/clangrefactoringbackend/source/clangtool.h
@@ -74,6 +74,8 @@ public:
std::string &&fileName,
std::string &&content,
std::vector<std::string> &&commandLine);
+ void addFiles(const Utils::SmallStringVector &filePaths,
+ const Utils::SmallStringVector &arguments);
clang::tooling::ClangTool createTool() const;
diff --git a/src/tools/clangrefactoringbackend/source/collectincludesaction.h b/src/tools/clangrefactoringbackend/source/collectincludesaction.h
new file mode 100644
index 0000000000..1586ba3f8b
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectincludesaction.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 <collectincludespreprocessorcallbacks.h>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include <clang/Frontend/FrontendActions.h>
+#include <clang/Frontend/CompilerInstance.h>
+#include <clang/Lex/Preprocessor.h>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+namespace ClangBackEnd {
+
+class CollectIncludesAction final : public clang::PreprocessOnlyAction
+{
+public:
+ CollectIncludesAction(Utils::SmallStringVector &includes,
+ const std::vector<uint> &excludedIncludeUID,
+ std::vector<uint> &alreadyIncludedFileUIDs)
+ : includes(includes),
+ excludedIncludeUID(excludedIncludeUID),
+ alreadyIncludedFileUIDs(alreadyIncludedFileUIDs)
+ {
+ }
+
+ bool BeginSourceFileAction(clang::CompilerInstance &compilerInstance,
+ llvm::StringRef filename) override
+ {
+ if (clang::PreprocessOnlyAction::BeginSourceFileAction(compilerInstance, filename)) {
+ auto &preprocessor = compilerInstance.getPreprocessor();
+ auto &headerSearch = preprocessor.getHeaderSearchInfo();
+
+ auto macroPreprocessorCallbacks = new CollectIncludesPreprocessorCallbacks(headerSearch,
+ includes,
+ excludedIncludeUID,
+ alreadyIncludedFileUIDs);
+
+ preprocessor.addPPCallbacks(std::unique_ptr<clang::PPCallbacks>(macroPreprocessorCallbacks));
+
+ return true;
+ }
+
+ return false;
+ }
+
+ void EndSourceFileAction() override
+ {
+ clang::PreprocessOnlyAction::EndSourceFileAction();
+ }
+
+private:
+ Utils::SmallStringVector &includes;
+ const std::vector<uint> &excludedIncludeUID;
+ std::vector<uint> &alreadyIncludedFileUIDs;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangrefactoringbackend/source/collectincludespreprocessorcallbacks.h
new file mode 100644
index 0000000000..b1f3d2c202
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectincludespreprocessorcallbacks.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** 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
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include <clang/Basic/SourceManager.h>
+#include <clang/Lex/MacroInfo.h>
+#include <clang/Lex/HeaderSearch.h>
+#include <clang/Lex/PPCallbacks.h>
+#include <clang/Lex/Preprocessor.h>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+#include <utils/smallstringvector.h>
+
+#include <algorithm>
+
+#include <QDebug>
+
+namespace ClangBackEnd {
+
+class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks
+{
+public:
+ CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch,
+ Utils::SmallStringVector &includes,
+ const std::vector<uint> &excludedIncludeUID,
+ std::vector<uint> &alreadyIncludedFileUIDs)
+ : headerSearch(headerSearch),
+ includes(includes),
+ excludedIncludeUID(excludedIncludeUID),
+ alreadyIncludedFileUIDs(alreadyIncludedFileUIDs)
+ {}
+
+ void InclusionDirective(clang::SourceLocation /*hashLocation*/,
+ const clang::Token &/*includeToken*/,
+ llvm::StringRef fileName,
+ bool /*isAngled*/,
+ clang::CharSourceRange /*fileNameRange*/,
+ const clang::FileEntry *file,
+ llvm::StringRef /*searchPath*/,
+ llvm::StringRef /*relativePath*/,
+ const clang::Module */*imported*/) override
+ {
+ auto fileUID = file->getUID();
+
+ flagIncludeAlreadyRead(file);
+
+ if (isNotInExcludedIncludeUID(fileUID)) {
+ auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID);
+ if (notAlreadyIncluded.first) {
+ alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, file->getUID());
+ includes.emplace_back(fileName.data(), fileName.size());
+ }
+ }
+ }
+
+ bool isNotInExcludedIncludeUID(uint uid) const
+ {
+ return !std::binary_search(excludedIncludeUID.begin(),
+ excludedIncludeUID.end(),
+ uid);
+ }
+
+
+ std::pair<bool, std::vector<uint>::iterator> isNotAlreadyIncluded(uint uid)
+ {
+ auto range = std::equal_range(alreadyIncludedFileUIDs.begin(),
+ alreadyIncludedFileUIDs.end(),
+ uid);
+
+ return {range.first == range.second, range.first};
+ }
+
+ void flagIncludeAlreadyRead(const clang::FileEntry *file)
+ {
+ auto &headerFileInfo = headerSearch.getFileInfo(file);
+
+ headerFileInfo.isImport = true;
+ ++headerFileInfo.NumIncludes;
+
+ }
+
+private:
+ clang::HeaderSearch &headerSearch;
+ std::vector<Utils::SmallString> &includes;
+ const std::vector<uint> &excludedIncludeUID;
+ std::vector<uint> &alreadyIncludedFileUIDs;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectincludestoolaction.h b/src/tools/clangrefactoringbackend/source/collectincludestoolaction.h
new file mode 100644
index 0000000000..017b2efe2a
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/collectincludestoolaction.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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 "collectincludesaction.h"
+
+#include <clang/Tooling/Tooling.h>
+
+namespace ClangBackEnd {
+
+class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory
+{
+public:
+ CollectIncludesToolAction(Utils::SmallStringVector &includes,
+ const std::vector<uint> &excludedIncludeUIDs)
+ : includes(includes),
+ excludedIncludeUIDs(excludedIncludeUIDs)
+ {}
+
+ clang::FrontendAction *create()
+ {
+ return new CollectIncludesAction(includes, excludedIncludeUIDs, alreadyIncludedFileUIDs);
+ }
+
+private:
+ Utils::SmallStringVector &includes;
+ const std::vector<uint> &excludedIncludeUIDs;
+ std::vector<uint> alreadyIncludedFileUIDs;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/includecollector.cpp b/src/tools/clangrefactoringbackend/source/includecollector.cpp
new file mode 100644
index 0000000000..914df823c1
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/includecollector.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "includecollector.h"
+
+#include "collectincludestoolaction.h"
+
+namespace ClangBackEnd {
+
+void IncludeCollector::collectIncludes()
+{
+ clang::tooling::ClangTool tool = createTool();
+
+ auto excludedIncludeFileUIDs = generateExcludedIncludeFileUIDs(tool.getFiles());
+
+ auto action = std::unique_ptr<CollectIncludesToolAction>(
+ new CollectIncludesToolAction(includes, excludedIncludeFileUIDs));
+
+ tool.run(action.get());
+}
+
+void IncludeCollector::setExcludedIncludes(Utils::SmallStringVector &&excludedIncludes)
+{
+ this->excludedIncludes = std::move(excludedIncludes);
+}
+
+Utils::SmallStringVector IncludeCollector::takeIncludes()
+{
+ std::sort(includes.begin(), includes.end());
+
+ return std::move(includes);
+}
+
+std::vector<uint> IncludeCollector::generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
+{
+ std::vector<uint> fileUIDs;
+ fileUIDs.reserve(excludedIncludes.size());
+
+ auto generateUID = [&] (const Utils::SmallString &filePath) {
+ return fileManager.getFile({filePath.data(), filePath.size()})->getUID();
+ };
+
+ std::transform(excludedIncludes.begin(),
+ excludedIncludes.end(),
+ std::back_inserter(fileUIDs),
+ generateUID);
+
+ std::sort(fileUIDs.begin(), fileUIDs.end());
+
+ return fileUIDs;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/includecollector.h b/src/tools/clangrefactoringbackend/source/includecollector.h
new file mode 100644
index 0000000000..738ff077d2
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/includecollector.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** 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 "clangtool.h"
+
+namespace ClangBackEnd {
+
+class IncludeCollector : public ClangTool
+{
+public:
+ void collectIncludes();
+
+ void setExcludedIncludes(Utils::SmallStringVector &&excludedIncludes);
+
+ Utils::SmallStringVector takeIncludes();
+
+private:
+ std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const;
+
+private:
+ Utils::SmallStringVector excludedIncludes;
+ Utils::SmallStringVector includes;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/sourcefilecallbacks.cpp b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.cpp
index 3963fbb6f5..c5f2d4edde 100644
--- a/src/tools/clangrefactoringbackend/source/sourcefilecallbacks.cpp
+++ b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.cpp
@@ -23,7 +23,7 @@
**
****************************************************************************/
-#include "sourcefilecallbacks.h"
+#include "locationsourcefilecallbacks.h"
#include "macropreprocessorcallbacks.h"
@@ -43,13 +43,13 @@
namespace ClangBackEnd {
-SourceFileCallbacks::SourceFileCallbacks(uint line, uint column)
+LocationSourceFileCallbacks::LocationSourceFileCallbacks(uint line, uint column)
: line(line),
column(column)
{
}
-bool SourceFileCallbacks::handleBeginSource(clang::CompilerInstance &compilerInstance, llvm::StringRef /*fileName*/)
+bool LocationSourceFileCallbacks::handleBeginSource(clang::CompilerInstance &compilerInstance, llvm::StringRef /*fileName*/)
{
auto &preprocessor = compilerInstance.getPreprocessor();
@@ -64,17 +64,17 @@ bool SourceFileCallbacks::handleBeginSource(clang::CompilerInstance &compilerIns
return true;
}
-SourceLocationsContainer SourceFileCallbacks::takeSourceLocations()
+SourceLocationsContainer LocationSourceFileCallbacks::takeSourceLocations()
{
return std::move(sourceLocationsContainer);
}
-Utils::SmallString SourceFileCallbacks::takeSymbolName()
+Utils::SmallString LocationSourceFileCallbacks::takeSymbolName()
{
return std::move(symbolName);
}
-bool SourceFileCallbacks::hasSourceLocations() const
+bool LocationSourceFileCallbacks::hasSourceLocations() const
{
return sourceLocationsContainer.hasContent();
}
diff --git a/src/tools/clangrefactoringbackend/source/sourcefilecallbacks.h b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h
index 9a8b1cfe4b..98f4cb9aea 100644
--- a/src/tools/clangrefactoringbackend/source/sourcefilecallbacks.h
+++ b/src/tools/clangrefactoringbackend/source/locationsourcefilecallbacks.h
@@ -51,10 +51,10 @@ namespace ClangBackEnd {
class MacroPreprocessorCallbacks;
class SourceLocationsContainer;
-class SourceFileCallbacks : public clang::tooling::SourceFileCallbacks
+class LocationSourceFileCallbacks : public clang::tooling::SourceFileCallbacks
{
public:
- SourceFileCallbacks(uint line, uint column);
+ LocationSourceFileCallbacks(uint line, uint column);
bool handleBeginSource(clang::CompilerInstance &compilerInstance,
llvm::StringRef fileName) override;
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
index e66dce78c7..debc827968 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
@@ -39,11 +39,13 @@
#include <algorithm>
#include <chrono>
#include <future>
+#include <atomic>
namespace ClangBackEnd {
RefactoringServer::RefactoringServer()
{
+ pollEventLoop = [] () { QCoreApplication::processEvents(); };
}
void RefactoringServer::end()
@@ -67,19 +69,43 @@ void RefactoringServer::requestSourceLocationsForRenamingMessage(RequestSourceLo
message.textDocumentRevision()});
}
+void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage(
+ RequestSourceRangesAndDiagnosticsForQueryMessage &&message)
+{
+ gatherSourceRangesAndDiagnosticsForQueryMessage(message.takeFileContainers(), message.takeQuery());
+}
+
+void RefactoringServer::cancel()
+{
+ cancelWork = true;
+}
+
+bool RefactoringServer::isCancelingJobs() const
+{
+ return cancelWork;
+}
+
+void RefactoringServer::supersedePollEventLoop(std::function<void ()> &&pollEventLoop)
+{
+ this->pollEventLoop = std::move(pollEventLoop);
+}
+
namespace {
SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForQueryMessage(
V2::FileContainer &&fileContainer,
- Utils::SmallString &&query) {
+ Utils::SmallString &&query,
+ const std::atomic_bool &cancelWork) {
ClangQuery clangQuery(std::move(query));
- clangQuery.addFile(fileContainer.filePath().directory(),
- fileContainer.filePath().name(),
- fileContainer.takeUnsavedFileContent(),
- fileContainer.takeCommandLineArguments());
+ if (!cancelWork) {
+ clangQuery.addFile(fileContainer.filePath().directory(),
+ fileContainer.filePath().name(),
+ fileContainer.takeUnsavedFileContent(),
+ fileContainer.takeCommandLineArguments());
- clangQuery.findLocations();
+ clangQuery.findLocations();
+ }
return {clangQuery.takeSourceRanges(), clangQuery.takeDiagnosticContainers()};
}
@@ -87,12 +113,6 @@ SourceRangesAndDiagnosticsForQueryMessage createSourceRangesAndDiagnosticsForQue
}
-void RefactoringServer::requestSourceRangesAndDiagnosticsForQueryMessage(
- RequestSourceRangesAndDiagnosticsForQueryMessage &&message)
-{
- gatherSourceRangesAndDiagnosticsForQueryMessage(message.takeFileContainers(), message.takeQuery());
-}
-
void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessage(
std::vector<V2::FileContainer> &&fileContainers,
Utils::SmallString &&query)
@@ -108,7 +128,7 @@ void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessage(
Future &&future = std::async(std::launch::async,
createSourceRangesAndDiagnosticsForQueryMessage,
std::move(fileContainers.back()),
- query.clone());
+ query.clone(), std::ref(cancelWork));
fileContainers.pop_back();
futures.emplace_back(std::move(future));
@@ -122,6 +142,8 @@ void RefactoringServer::gatherSourceRangesAndDiagnosticsForQueryMessage(
std::size_t RefactoringServer::waitForNewSourceRangesAndDiagnosticsForQueryMessage(std::vector<Future> &futures)
{
while (true) {
+ pollEventLoop();
+
std::vector<Future> readyFutures;
readyFutures.reserve(futures.size());
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h
index 47615a9f3f..f61509e60d 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.h
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h
@@ -47,11 +47,21 @@ public:
void end() override;
void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
+ void cancel() override;
+
+ bool isCancelingJobs() const;
+
+ void supersedePollEventLoop(std::function<void()> &&pollEventLoop);
private:
void gatherSourceRangesAndDiagnosticsForQueryMessage(std::vector<V2::FileContainer> &&fileContainers,
Utils::SmallString &&query);
std::size_t waitForNewSourceRangesAndDiagnosticsForQueryMessage(std::vector<Future> &futures);
+
+private:
+ std::function<void()> pollEventLoop;
+ std::atomic_bool cancelWork{false};
+
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h
index 8e3dba86b2..eda4accf70 100644
--- a/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h
+++ b/src/tools/clangrefactoringbackend/source/sourcelocationsutils.h
@@ -34,6 +34,7 @@
#endif
#include <clang/Basic/SourceManager.h>
+#include <clang/Lex/Lexer.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/FileUtilities.h>
@@ -41,6 +42,7 @@
#pragma GCC diagnostic pop
#endif
+#include <iterator>
#include <cctype>
namespace ClangBackEnd {
@@ -68,75 +70,6 @@ Utils::SmallString fromNativePath(Container container)
return path;
}
-inline Utils::SmallString getSourceText(const clang::FullSourceLoc &startFullSourceLocation,
- uint startOffset,
- uint endOffset)
-{
- auto startBuffer = startFullSourceLocation.getBufferData();
- const auto bufferSize = endOffset - startOffset;
-
- return Utils::SmallString(startBuffer.data() + startOffset, bufferSize + 1);
-}
-
-inline void makePrintable(Utils::SmallString &text)
-{
- text.replace("\n", " ");
- text.replace("\t", " ");
-
- auto end = std::unique(text.begin(), text.end(), [](char l, char r){
- return std::isspace(l) && std::isspace(r) && l == r;
- });
- text.resize(std::distance(text.begin(), end));
-}
-
-inline void appendSourceRangeToSourceRangesContainer(
- const clang::SourceRange &sourceRange,
- ClangBackEnd::SourceRangesContainer &sourceRangesContainer,
- const clang::SourceManager &sourceManager)
-{
- clang::FullSourceLoc startFullSourceLocation(sourceRange.getBegin(), sourceManager);
- clang::FullSourceLoc endFullSourceLocation(sourceRange.getEnd(), sourceManager);
- if (startFullSourceLocation.isFileID() && endFullSourceLocation.isFileID()) {
- const auto startDecomposedLoction = startFullSourceLocation.getDecomposedLoc();
- const auto endDecomposedLoction = endFullSourceLocation.getDecomposedLoc();
- const auto fileId = startDecomposedLoction.first;
- const auto startOffset = startDecomposedLoction.second;
- const auto endOffset = endDecomposedLoction.second;
- const auto fileEntry = sourceManager.getFileEntryForID(fileId);
- auto filePath = absolutePath(fileEntry->getName());
- const auto fileName = llvm::sys::path::filename(filePath);
- llvm::sys::path::remove_filename(filePath);
- Utils::SmallString content = getSourceText(startFullSourceLocation,
- startOffset,
- endOffset);
- makePrintable(content);
-
- sourceRangesContainer.insertFilePath(fileId.getHashValue(),
- fromNativePath(filePath),
- fromNativePath(fileName));
- sourceRangesContainer.insertSourceRange(fileId.getHashValue(),
- startFullSourceLocation.getSpellingLineNumber(),
- startFullSourceLocation.getSpellingColumnNumber(),
- startOffset,
- endFullSourceLocation.getSpellingLineNumber(),
- endFullSourceLocation.getSpellingColumnNumber(),
- endOffset,
- std::move(content));
- }
-}
-
-inline
-void appendSourceRangesToSourceRangesContainer(
- ClangBackEnd::SourceRangesContainer &sourceRangesContainer,
- const std::vector<clang::SourceRange> &sourceRanges,
- const clang::SourceManager &sourceManager)
-{
- sourceRangesContainer.reserve(sourceRanges.size());
-
- for (const auto &sourceRange : sourceRanges)
- appendSourceRangeToSourceRangesContainer(sourceRange, sourceRangesContainer, sourceManager);
-}
-
inline
void appendSourceLocationsToSourceLocationsContainer(
ClangBackEnd::SourceLocationsContainer &sourceLocationsContainer,
diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
new file mode 100644
index 0000000000..2a79260349
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "sourcerangeextractor.h"
+
+#include "sourcelocationsutils.h"
+
+#include <sourcerangescontainer.h>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include <clang/Basic/SourceManager.h>
+#include <clang/Lex/Lexer.h>
+#include <llvm/Support/FileSystem.h>
+#include <llvm/Support/FileUtilities.h>
+#include <llvm/ADT/SmallVector.h>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+namespace ClangBackEnd {
+
+SourceRangeExtractor::SourceRangeExtractor(const clang::SourceManager &sourceManager,
+ const clang::LangOptions &languageOptions,
+ SourceRangesContainer &sourceRangesContainer)
+ : sourceManager(sourceManager),
+ languageOptions(languageOptions),
+ sourceRangesContainer(sourceRangesContainer)
+{
+}
+
+const char *SourceRangeExtractor::findStartOfLineInBuffer(llvm::StringRef buffer, uint startOffset)
+{
+ auto beginText = buffer.begin() + startOffset;
+ auto reverseEnd = std::make_reverse_iterator(buffer.begin());
+
+ auto found = std::find_if(std::make_reverse_iterator(beginText),
+ reverseEnd,
+ [] (const char character) {
+ return character == '\n' || character == '\r';
+ });
+
+ if (found != reverseEnd)
+ return found.base();
+
+ return buffer.begin();
+}
+
+const char *SourceRangeExtractor::findEndOfLineInBuffer(llvm::StringRef buffer, uint endOffset)
+{
+ auto beginText = buffer.begin() + endOffset;
+
+ auto found = std::find_if(beginText,
+ buffer.end(),
+ [] (const char character) {
+ return character == '\n' || character == '\r';
+ });
+
+ if (found != buffer.end())
+ return found;
+
+ return buffer.end();
+}
+
+Utils::SmallString SourceRangeExtractor::getExpandedText(llvm::StringRef buffer,
+ uint startOffset,
+ uint endOffset)
+{
+ auto startBuffer = findStartOfLineInBuffer(buffer, startOffset);
+ auto endBuffer = findEndOfLineInBuffer(buffer, endOffset);
+
+ return Utils::SmallString(startBuffer, endBuffer);
+}
+
+const clang::SourceRange SourceRangeExtractor::extendSourceRangeToLastTokenEnd(const clang::SourceRange sourceRange)
+{
+ auto endLocation = sourceRange.getEnd();
+ uint length = clang::Lexer::MeasureTokenLength(sourceManager.getSpellingLoc(endLocation),
+ sourceManager,
+ languageOptions);
+ endLocation = endLocation.getLocWithOffset(length);
+
+ return {sourceRange.getBegin(), endLocation};
+}
+
+void SourceRangeExtractor::insertSourceRange(uint fileHash,
+ Utils::SmallString &&directoryPath,
+ Utils::SmallString &&fileName,
+ const clang::FullSourceLoc &startLocation,
+ uint startOffset,
+ const clang::FullSourceLoc &endLocation,
+ uint endOffset,
+ Utils::SmallString &&lineSnippet)
+{
+ sourceRangesContainer.insertFilePath(fileHash,
+ std::move(directoryPath),
+ std::move(fileName));
+ sourceRangesContainer.insertSourceRange(fileHash,
+ startLocation.getSpellingLineNumber(),
+ startLocation.getSpellingColumnNumber(),
+ startOffset,
+ endLocation.getSpellingLineNumber(),
+ endLocation.getSpellingColumnNumber(),
+ endOffset,
+ std::move(lineSnippet));
+}
+
+void SourceRangeExtractor::addSourceRange(const clang::SourceRange &sourceRange)
+{
+ auto extendedSourceRange = extendSourceRangeToLastTokenEnd(sourceRange);
+
+ clang::FullSourceLoc startSourceLocation(extendedSourceRange.getBegin(), sourceManager);
+ clang::FullSourceLoc endSourceLocation(extendedSourceRange.getEnd(), sourceManager);
+ if (startSourceLocation.isFileID() && endSourceLocation.isFileID()) {
+ const auto startDecomposedLoction = startSourceLocation.getDecomposedLoc();
+ const auto endDecomposedLoction = endSourceLocation.getDecomposedLoc();
+ const auto fileId = startDecomposedLoction.first;
+ const auto startOffset = startDecomposedLoction.second;
+ const auto endOffset = endDecomposedLoction.second;
+ const auto fileEntry = sourceManager.getFileEntryForID(fileId);
+ auto filePath = absolutePath(fileEntry->getName());
+ const auto fileName = llvm::sys::path::filename(filePath);
+ llvm::sys::path::remove_filename(filePath);
+ Utils::SmallString lineSnippet = getExpandedText(startSourceLocation.getBufferData(),
+ startOffset,
+ endOffset);
+ insertSourceRange(fileId.getHashValue(),
+ fromNativePath(filePath),
+ {fileName.data(), fileName.size()},
+ startSourceLocation,
+ startOffset,
+ endSourceLocation,
+ endOffset,
+ std::move(lineSnippet));
+
+ }
+}
+
+void SourceRangeExtractor::addSourceRanges(const std::vector<clang::SourceRange> &sourceRanges)
+{
+ sourceRangesContainer.reserve(sourceRanges.size() + sourceRangeWithTextContainers().size());
+
+ for (const clang::SourceRange &sourceRange : sourceRanges)
+ addSourceRange(sourceRange);
+}
+
+const std::vector<SourceRangeWithTextContainer> &SourceRangeExtractor::sourceRangeWithTextContainers() const
+{
+ return sourceRangesContainer.sourceRangeWithTextContainers();
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
new file mode 100644
index 0000000000..05ba1f7132
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/sourcerangeextractor.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 <vector>
+
+using uint = unsigned int;
+
+namespace Utils {
+template <uint Size>
+class BasicSmallString;
+using SmallString = BasicSmallString<31>;
+}
+
+namespace llvm {
+class StringRef;
+}
+
+namespace clang {
+class SourceManager;
+class LangOptions;
+class SourceRange;
+class FullSourceLoc;
+}
+
+namespace ClangBackEnd {
+
+class SourceRangesContainer;
+class SourceRangeWithTextContainer;
+
+class SourceRangeExtractor
+{
+public:
+ SourceRangeExtractor(const clang::SourceManager &sourceManager,
+ const clang::LangOptions &languageOptions,
+ SourceRangesContainer &sourceRangesContainer);
+
+ void addSourceRange(const clang::SourceRange &sourceRange);
+ void addSourceRanges(const std::vector<clang::SourceRange> &sourceRanges);
+
+ const std::vector<SourceRangeWithTextContainer> &sourceRangeWithTextContainers() const;
+
+ static const char *findStartOfLineInBuffer(const llvm::StringRef buffer, uint startOffset);
+ static const char *findEndOfLineInBuffer(llvm::StringRef buffer, uint endOffset);
+ static Utils::SmallString getExpandedText(llvm::StringRef buffer, uint startOffset, uint endOffset);
+
+ const clang::SourceRange extendSourceRangeToLastTokenEnd(const clang::SourceRange sourceRange);
+
+private:
+ void insertSourceRange(uint fileHash,
+ Utils::SmallString &&directoryPath,
+ Utils::SmallString &&fileName,
+ const clang::FullSourceLoc &startLocation,
+ uint startOffset,
+ const clang::FullSourceLoc &endLocation,
+ uint endOffset,
+ Utils::SmallString &&lineSnippet);
+
+private:
+ const clang::SourceManager &sourceManager;
+ const clang::LangOptions &languageOptions;
+ SourceRangesContainer &sourceRangesContainer;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolfinder.cpp b/src/tools/clangrefactoringbackend/source/symbolfinder.cpp
index 198a889ce1..02f727b614 100644
--- a/src/tools/clangrefactoringbackend/source/symbolfinder.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolfinder.cpp
@@ -25,7 +25,7 @@
#include "symbolfinder.h"
-#include "sourcefilecallbacks.h"
+#include "locationsourcefilecallbacks.h"
#include "symbollocationfinderaction.h"
namespace ClangBackEnd {
diff --git a/src/tools/clangrefactoringbackend/source/symbolfinder.h b/src/tools/clangrefactoringbackend/source/symbolfinder.h
index fb1ddae5e1..3a9999f66b 100644
--- a/src/tools/clangrefactoringbackend/source/symbolfinder.h
+++ b/src/tools/clangrefactoringbackend/source/symbolfinder.h
@@ -28,7 +28,7 @@
#include "clangtool.h"
#include "findusrforcursoraction.h"
#include "symbollocationfinderaction.h"
-#include "sourcefilecallbacks.h"
+#include "locationsourcefilecallbacks.h"
#include <sourcelocationscontainer.h>
@@ -61,7 +61,7 @@ private:
Utils::SmallString symbolName;
USRFindingAction usrFindingAction;
SymbolLocationFinderAction symbolLocationFinderAction;
- SourceFileCallbacks sourceFileCallbacks;
+ LocationSourceFileCallbacks sourceFileCallbacks;
ClangBackEnd::SourceLocationsContainer sourceLocations_;
};
diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp
index bfb47fc7fc..91947f4ae6 100644
--- a/tests/unit/unittest/clangquery-test.cpp
+++ b/tests/unit/unittest/clangquery-test.cpp
@@ -71,7 +71,7 @@ TEST_F(ClangQuery, RootSourceRangeForSimpleFunctionDeclarationRange)
simpleFunctionQuery.findLocations();
ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers().at(0),
- IsSourceRangeWithText(1, 1, 8, 1, "int function(int* pointer, int value) { if (pointer == nullptr) { return value + 1; } else { return value - 1; } }"));
+ 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(ClangQuery, RootSourceRangeForSimpleFieldDeclarationRange)
@@ -81,7 +81,7 @@ TEST_F(ClangQuery, RootSourceRangeForSimpleFieldDeclarationRange)
simpleClassQuery.findLocations();
ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers().at(0),
- IsSourceRangeWithText(4, 5, 4, 9, "int x"));
+ IsSourceRangeWithText(4, 5, 4, 10, " int x;"));
}
TEST_F(ClangQuery, NoSourceRangesForEmptyQuery)
diff --git a/tests/unit/unittest/clangquerycurrentfilefindfilter-test.cpp b/tests/unit/unittest/clangquerycurrentfilefindfilter-test.cpp
deleted file mode 100644
index c83680d335..0000000000
--- a/tests/unit/unittest/clangquerycurrentfilefindfilter-test.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-****************************************************************************/
-
-#include "googletest.h"
-
-#include "mockrefactoringserver.h"
-#include "mocksearch.h"
-#include "mocksearchhandle.h"
-
-#include <clangquerycurrentfilefindfilter.h>
-#include <refactoringcompileroptionsbuilder.h>
-#include <refactoringclient.h>
-
-#include <requestsourcelocationforrenamingmessage.h>
-#include <requestsourcerangesanddiagnosticsforquerymessage.h>
-#include <sourcelocationsforrenamingmessage.h>
-#include <sourcerangesanddiagnosticsforquerymessage.h>
-
-#include <cpptools/projectpart.h>
-
-namespace {
-
-using ::testing::_;
-using ::testing::NiceMock;
-using ::testing::NotNull;
-using ::testing::ReturnNew;
-using ::testing::DefaultValue;
-
-using ClangRefactoring::RefactoringCompilerOptionsBuilder;
-
-class ClangQueryCurrentFileFindFilter : public ::testing::Test
-{
-protected:
- void SetUp();
-
-protected:
- NiceMock<MockRefactoringServer> mockRefactoringServer;
- NiceMock<MockSearch> mockSearch;
- ClangRefactoring::RefactoringClient refactoringClient;
- ClangRefactoring::ClangQueryCurrentFileFindFilter findFilter{mockRefactoringServer, mockSearch, refactoringClient};
- QString findDeclQueryText{"functionDecl()"};
- QString curentDocumentFilePath{"/path/to/file.cpp"};
- QString unsavedDocumentContent{"void f();"};
- Utils::SmallStringVector commandLine;
- CppTools::ProjectPart::Ptr projectPart;
- CppTools::ProjectFile projectFile{curentDocumentFilePath, CppTools::ProjectFile::CXXSource};
-};
-
-TEST_F(ClangQueryCurrentFileFindFilter, SupportedFindFlags)
-{
- auto findFlags = findFilter.supportedFindFlags();
-
- ASSERT_FALSE(findFlags);
-}
-
-TEST_F(ClangQueryCurrentFileFindFilter, IsNotUsableForUnusableServer)
-{
- auto isUsable = findFilter.isUsable();
-
- ASSERT_FALSE(isUsable);
-}
-
-TEST_F(ClangQueryCurrentFileFindFilter, IsUsableForUsableServer)
-{
- mockRefactoringServer.setUsable(true);
-
- auto isUsable = findFilter.isUsable();
-
- ASSERT_TRUE(isUsable);
-}
-
-TEST_F(ClangQueryCurrentFileFindFilter, ServerIsUsableForUsableFindFilter)
-{
- findFilter.setUsable(true);
-
- auto isUsable = mockRefactoringServer.isUsable();
-
- ASSERT_TRUE(isUsable);
-}
-
-TEST_F(ClangQueryCurrentFileFindFilter, SearchHandleSetIsSetAfterFindAll)
-{
- findFilter.findAll(findDeclQueryText);
-
- auto searchHandle = refactoringClient.searchHandle();
-
- ASSERT_THAT(searchHandle, NotNull());
-}
-
-
-TEST_F(ClangQueryCurrentFileFindFilter, FindAllIsCallingStartNewSearch)
-{
- EXPECT_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"),
- findDeclQueryText))
- .Times(1);
-
- findFilter.findAll(findDeclQueryText);
-}
-
-TEST_F(ClangQueryCurrentFileFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage)
-{
- ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(findDeclQueryText,
- {{{"/path/to", "file.cpp"},
- unsavedDocumentContent,
- commandLine.clone(),
- 1}});
-
- EXPECT_CALL(mockRefactoringServer, requestSourceRangesAndDiagnosticsForQueryMessage(message))
- .Times(1);
-
- findFilter.findAll(findDeclQueryText);
-}
-
-void ClangQueryCurrentFileFindFilter::SetUp()
-{
- projectPart = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart);
- projectPart->files.push_back(projectFile);
-
- commandLine = RefactoringCompilerOptionsBuilder::build(
- projectPart.data(),
- projectFile.kind,
- RefactoringCompilerOptionsBuilder::PchUsage::None);
- commandLine.push_back(curentDocumentFilePath);
-
- findFilter.setCurrentDocumentFilePath(curentDocumentFilePath);
- findFilter.setUnsavedDocumentContent(unsavedDocumentContent);
- findFilter.setProjectPart(projectPart);
-
- DefaultValue<std::unique_ptr<ClangRefactoring::SearchHandleInterface>>::SetFactory([] () {
- return std::unique_ptr<ClangRefactoring::SearchHandleInterface>(new MockSearchHandle); });
-
-}
-
-}
diff --git a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp
index f641aa4b1b..f389c75bd9 100644
--- a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp
+++ b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp
@@ -43,8 +43,10 @@ namespace {
using ::testing::_;
using ::testing::NiceMock;
using ::testing::NotNull;
+using ::testing::Return;
using ::testing::ReturnNew;
using ::testing::DefaultValue;
+using ::testing::ByMove;
using ClangRefactoring::RefactoringCompilerOptionsBuilder;
@@ -52,6 +54,7 @@ class ClangQueryProjectFindFilter : public ::testing::Test
{
protected:
void SetUp();
+ std::unique_ptr<ClangRefactoring::SearchHandle> createSearchHandle();
protected:
NiceMock<MockRefactoringServer> mockRefactoringServer;
@@ -61,10 +64,8 @@ protected:
QString findDeclQueryText{"functionDecl()"};
QString curentDocumentFilePath{"/path/to/file.cpp"};
QString unsavedDocumentContent{"void f();"};
- Utils::SmallStringVector commandLine;
- CppTools::ProjectPart::Ptr projectPart1;
- CppTools::ProjectPart::Ptr projectPart2;
- CppTools::ProjectFile projectFile{curentDocumentFilePath, CppTools::ProjectFile::CXXSource};
+ std::vector<Utils::SmallStringVector> commandLines;
+ std::vector<CppTools::ProjectPart::Ptr> projectsParts;
};
TEST_F(ClangQueryProjectFindFilter, SupportedFindFlags)
@@ -117,13 +118,25 @@ TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingStartNewSearch)
findFilter.findAll(findDeclQueryText);
}
+TEST_F(ClangQueryProjectFindFilter, FindAllIsSettingExprectedResultCountInTheRefactoringClient)
+{
+ findFilter.findAll(findDeclQueryText);
+
+ ASSERT_THAT(refactoringClient.expectedResultCount(), 3);
+}
+
TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage)
{
ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(findDeclQueryText,
- {{{"/path/to", "file.cpp"},
- unsavedDocumentContent,
- commandLine.clone(),
- 1}});
+ {{{"/path/to", "file1.h"},
+ "",
+ commandLines[0].clone()},
+ {{"/path/to", "file1.cpp"},
+ "",
+ commandLines[1].clone()},
+ {{"/path/to", "file2.cpp"},
+ "",
+ commandLines[2].clone()}});
EXPECT_CALL(mockRefactoringServer, requestSourceRangesAndDiagnosticsForQueryMessage(message))
.Times(1);
@@ -131,23 +144,64 @@ TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagno
findFilter.findAll(findDeclQueryText);
}
+TEST_F(ClangQueryProjectFindFilter, CancelSearch)
+{
+ EXPECT_CALL(mockRefactoringServer, cancel())
+ .Times(1);
+
+ findFilter.findAll(findDeclQueryText);
+
+ findFilter.searchHandleForTestOnly()->cancel();
+}
+
+std::vector<CppTools::ProjectPart::Ptr> createProjectParts()
+{
+ auto projectPart1 = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart);
+ projectPart1->files.append({"/path/to/file1.h", CppTools::ProjectFile::CXXSource});
+ projectPart1->files.append({"/path/to/file1.cpp", CppTools::ProjectFile::CXXHeader});
+
+ auto projectPart2 = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart);
+ projectPart1->files.append({"/path/to/file2.cpp", CppTools::ProjectFile::CXXHeader});
+
+ return {projectPart1, projectPart2};
+}
+
+std::vector<Utils::SmallStringVector>
+createCommandLines(const std::vector<CppTools::ProjectPart::Ptr> &projectParts)
+{
+ std::vector<Utils::SmallStringVector> commandLines;
+
+ for (const CppTools::ProjectPart::Ptr &projectPart : projectParts) {
+ for (const CppTools::ProjectFile &projectFile : projectPart->files) {
+ auto commandLine = RefactoringCompilerOptionsBuilder::build(projectPart.data(),
+ projectFile.kind,
+ CppTools::CompilerOptionsBuilder::PchUsage::None);
+ commandLine.emplace_back(projectFile.path);
+ commandLines.push_back(commandLine);
+ }
+ }
+
+ return commandLines;
+}
+
void ClangQueryProjectFindFilter::SetUp()
{
-// projectPart = CppTools::ProjectPart::Ptr(new CppTools::ProjectPart);
-// projectPart->files.push_back(projectFile);
+ projectsParts = createProjectParts();
+ commandLines = createCommandLines(projectsParts);
-// commandLine = RefactoringCompilerOptionsBuilder::build(projectPart.data(),
-// projectFile.kind);
- commandLine.push_back(curentDocumentFilePath);
+ findFilter.setProjectParts(projectsParts);
-// findFilter.setCurrentDocumentFilePath(curentDocumentFilePath);
-// findFilter.setCurrentDocumentRevision(documentRevision);
-// findFilter.setUnsavedDocumentContent(unsavedDocumentContent);
-// findFilter.setProjectPart(projectPart);
+ ON_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"), findDeclQueryText))
+ .WillByDefault(Return(ByMove(createSearchHandle())));
- DefaultValue<std::unique_ptr<ClangRefactoring::SearchHandleInterface>>::SetFactory([] () {
- return std::unique_ptr<ClangRefactoring::SearchHandleInterface>(new MockSearchHandle); });
+}
+
+std::unique_ptr<ClangRefactoring::SearchHandle> ClangQueryProjectFindFilter::createSearchHandle()
+{
+ std::unique_ptr<ClangRefactoring::SearchHandle> handle(new NiceMock<MockSearchHandle>);
+ handle->setRefactoringServer(&mockRefactoringServer);
+ return handle;
}
}
diff --git a/tests/unit/unittest/data/sourcerangeextractor_location.cpp b/tests/unit/unittest/data/sourcerangeextractor_location.cpp
new file mode 100644
index 0000000000..8e63dcf97e
--- /dev/null
+++ b/tests/unit/unittest/data/sourcerangeextractor_location.cpp
@@ -0,0 +1,2 @@
+int value;
+
diff --git a/tests/unit/unittest/googletest.h b/tests/unit/unittest/googletest.h
index da028e9f64..a3a74ded2f 100644
--- a/tests/unit/unittest/googletest.h
+++ b/tests/unit/unittest/googletest.h
@@ -28,4 +28,8 @@
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
+
#include "gtest-qt-printing.h"
+#ifdef CLANG_UNIT_TESTS
+# include "gtest-clang-printing.h"
+#endif
diff --git a/tests/unit/unittest/gtest-clang-printing.cpp b/tests/unit/unittest/gtest-clang-printing.cpp
new file mode 100644
index 0000000000..7b9167540e
--- /dev/null
+++ b/tests/unit/unittest/gtest-clang-printing.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#ifdef CLANG_UNIT_TESTS
+#include <clang/Basic/SourceLocation.h>
+#include <clang/Basic/SourceManager.h>
+#endif
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+#include <gtest/gtest-printers.h>
+
+namespace TestGlobal {
+
+const clang::SourceManager *globalSourceManager = nullptr;
+
+void setSourceManager(const clang::SourceManager *sourceManager)
+{
+ globalSourceManager = sourceManager;
+}
+
+}
+
+namespace llvm {
+std::ostream &operator<<(std::ostream &out, const StringRef stringReference)
+{
+ out.write(stringReference.data(), std::streamsize(stringReference.size()));
+
+ return out;
+}
+}
+
+namespace clang {
+
+void PrintTo(const FullSourceLoc &sourceLocation, ::std::ostream *os)
+{
+ auto &&sourceManager = sourceLocation.getManager();
+ auto fileName = sourceManager.getFileEntryForID(sourceLocation.getFileID())->getName();
+
+ *os << "(\""
+ << fileName << ", "
+ << sourceLocation.getSpellingLineNumber() << ", "
+ << sourceLocation.getSpellingColumnNumber() << ")";
+}
+
+void PrintTo(const SourceRange &sourceRange, ::std::ostream *os)
+{
+ if (TestGlobal::globalSourceManager) {
+ *os << "("
+ << sourceRange.getBegin().printToString(*TestGlobal::globalSourceManager) << ", "
+ << sourceRange.getEnd().printToString(*TestGlobal::globalSourceManager) << ")";
+ } else {
+ *os << "("
+ << sourceRange.getBegin().getRawEncoding() << ", "
+ << sourceRange.getEnd().getRawEncoding() << ")";
+ }
+}
+
+}
diff --git a/tests/unit/unittest/gtest-clang-printing.h b/tests/unit/unittest/gtest-clang-printing.h
new file mode 100644
index 0000000000..7ed5a8b960
--- /dev/null
+++ b/tests/unit/unittest/gtest-clang-printing.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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 <iosfwd>
+
+namespace llvm {
+
+class StringRef;
+
+std::ostream &operator<<(std::ostream &out, const StringRef stringReference);
+}
+
+namespace clang {
+class FullSourceLoc;
+class SourceRange;
+class SourceManager;
+
+void PrintTo(const FullSourceLoc &sourceLocation, ::std::ostream *os);
+void PrintTo(const SourceRange &sourceLocation, ::std::ostream *os);
+
+}
+
+namespace TestGlobal {
+void setSourceManager(const clang::SourceManager *sourceManager);
+}
+
diff --git a/tests/unit/unittest/mockrefactoringclient.h b/tests/unit/unittest/mockrefactoringclient.h
index d35f55ad31..80db17eb96 100644
--- a/tests/unit/unittest/mockrefactoringclient.h
+++ b/tests/unit/unittest/mockrefactoringclient.h
@@ -32,7 +32,7 @@
#include <gtest/gtest.h>
#include "gtest-qt-printing.h"
-class MockRefactoringClient final : public ClangBackEnd::RefactoringClientInterface
+class MockRefactoringClient : public ClangBackEnd::RefactoringClientInterface
{
public:
MOCK_METHOD0(alive,
diff --git a/tests/unit/unittest/mockrefactoringserver.h b/tests/unit/unittest/mockrefactoringserver.h
index cc828f3b57..c88ab1d36b 100644
--- a/tests/unit/unittest/mockrefactoringserver.h
+++ b/tests/unit/unittest/mockrefactoringserver.h
@@ -41,6 +41,9 @@ public:
MOCK_METHOD1(requestSourceRangesAndDiagnosticsForQueryMessage,
void (const ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage&));
+ MOCK_METHOD0(cancel,
+ void ());
+
void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override
{
requestSourceLocationsForRenamingMessage(message);
diff --git a/tests/unit/unittest/mocksearch.h b/tests/unit/unittest/mocksearch.h
index 668d57233d..539c07833d 100644
--- a/tests/unit/unittest/mocksearch.h
+++ b/tests/unit/unittest/mocksearch.h
@@ -33,6 +33,6 @@ class MockSearch : public ClangRefactoring::SearchInterface
{
public:
MOCK_METHOD2(startNewSearch,
- std::unique_ptr<ClangRefactoring::SearchHandleInterface>(const QString &searchLabel,
- const QString &searchTerm));
+ std::unique_ptr<ClangRefactoring::SearchHandle>(const QString &searchLabel,
+ const QString &searchTerm));
};
diff --git a/tests/unit/unittest/mocksearchhandle.h b/tests/unit/unittest/mocksearchhandle.h
index 61c68d4b21..f13b06b2a8 100644
--- a/tests/unit/unittest/mocksearchhandle.h
+++ b/tests/unit/unittest/mocksearchhandle.h
@@ -27,16 +27,19 @@
#include "googletest.h"
-#include <searchhandleinterface.h>
+#include <searchhandle.h>
-class MockSearchHandle : public ClangRefactoring::SearchHandleInterface
+class MockSearchHandle : public ClangRefactoring::SearchHandle
{
public:
- MOCK_METHOD5(addResult,
+ MockSearchHandle() = default;
+ using ClangRefactoring::SearchHandle::SearchHandle;
+
+ MOCK_METHOD3(addResult,
void(const QString &fileName,
- int lineNumber,
const QString &lineText,
- int searchTermStart,
- int searchTermLength));
+ Core::Search::TextRange textRange));
+ MOCK_METHOD1(setExpectedResultCount, void(uint count));
+ MOCK_METHOD1(setResultCounter, void(uint counter));
MOCK_METHOD0(finishSearch, void());
};
diff --git a/tests/unit/unittest/refactoringclient-test.cpp b/tests/unit/unittest/refactoringclient-test.cpp
index ce21df5b7f..5f779223c9 100644
--- a/tests/unit/unittest/refactoringclient-test.cpp
+++ b/tests/unit/unittest/refactoringclient-test.cpp
@@ -138,7 +138,7 @@ TEST_F(RefactoringClient, AfterStartLocalRenameHasValidCallback)
TEST_F(RefactoringClient, CallAddResultsForEmptyQueryMessage)
{
- EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_ , _, _))
+ EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_))
.Times(0);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(emptyQueryResultMessage));
@@ -146,7 +146,7 @@ TEST_F(RefactoringClient, CallAddResultsForEmptyQueryMessage)
TEST_F(RefactoringClient, CallAddResultsForQueryMessage)
{
- EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_ , _, _))
+ EXPECT_CALL(mockSearchHandle, addResult(_ ,_ ,_))
.Times(2);
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
@@ -168,6 +168,61 @@ TEST_F(RefactoringClient, CallFinishSearchQueryMessage)
client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
}
+TEST_F(RefactoringClient, CallFinishSearchForTwoQueryMessages)
+{
+ client.setExpectedResultCount(2);
+
+ EXPECT_CALL(mockSearchHandle, finishSearch())
+ .Times(1);
+
+ client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
+ client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
+}
+
+TEST_F(RefactoringClient, CallSetExpectedResultCountInSearchHandle)
+{
+ EXPECT_CALL(mockSearchHandle, setExpectedResultCount(3))
+ .Times(1);
+
+ client.setExpectedResultCount(3);
+}
+
+TEST_F(RefactoringClient, ResultCounterIsOneAfterQueryMessage)
+{
+ client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
+
+ ASSERT_THAT(client.resultCounter(), 1);
+}
+
+TEST_F(RefactoringClient, ResultCounterIsSetInSearchHandleToOne)
+{
+ EXPECT_CALL(mockSearchHandle, setResultCounter(1))
+ .Times(1);
+
+ client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
+}
+
+TEST_F(RefactoringClient, ResultCounterIsSetInSearchHandleToTwo)
+{
+ client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
+
+ EXPECT_CALL(mockSearchHandle, setResultCounter(2))
+ .Times(1);
+
+ client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
+}
+
+
+TEST_F(RefactoringClient, ResultCounterIsZeroAfterSettingExpectedResultCount)
+{
+ client.sourceRangesAndDiagnosticsForQueryMessage(std::move(queryResultMessage));
+
+ client.setExpectedResultCount(3);
+
+ ASSERT_THAT(client.resultCounter(), 0);
+}
+
+
TEST_F(RefactoringClient, ConvertFilePaths)
{
std::unordered_map<uint, ClangBackEnd::FilePath> filePaths{{42u, clangBackEndFilePath.clone()}};
@@ -189,6 +244,7 @@ void RefactoringClient::SetUp()
RefactoringCompilerOptionsBuilder::PchUsage::None);
client.setSearchHandle(&mockSearchHandle);
+ client.setExpectedResultCount(1);
}
}
diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
index 74cc523b2f..c966161f9b 100644
--- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
+++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
@@ -146,6 +146,16 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesAndDiagnosticsForQue
scheduleServerMessages();
}
+TEST_F(RefactoringClientServerInProcess, CancelMessage)
+{
+ EXPECT_CALL(mockRefactoringServer, cancel())
+ .Times(1);
+
+ serverProxy.cancel();
+ scheduleServerMessages();
+}
+
+
RefactoringClientServerInProcess::RefactoringClientServerInProcess()
: serverProxy(&mockRefactoringClient, &buffer),
clientProxy(&mockRefactoringServer, &buffer)
diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp
index 04f862feca..97c35645e1 100644
--- a/tests/unit/unittest/refactoringserver-test.cpp
+++ b/tests/unit/unittest/refactoringserver-test.cpp
@@ -39,6 +39,7 @@ namespace {
using testing::AllOf;
using testing::Contains;
+using testing::NiceMock;
using testing::Pair;
using testing::PrintToString;
using testing::Property;
@@ -70,7 +71,11 @@ class RefactoringServer : public ::testing::Test
protected:
ClangBackEnd::RefactoringServer refactoringServer;
- MockRefactoringClient mockRefactoringClient;
+ NiceMock<MockRefactoringClient> mockRefactoringClient;
+ Utils::SmallString fileContent{"void f()\n {}"};
+ FileContainer fileContainer{{TESTDATA_DIR, "query_simplefunction.cpp"},
+ fileContent.clone(),
+ {"cc", "query_simplefunction.cpp"}};
};
@@ -101,15 +106,13 @@ TEST_F(RefactoringServer, RequestSourceLocationsForRenamingMessage)
TEST_F(RefactoringServer, RequestSingleSourceRangesAndDiagnosticsForQueryMessage)
{
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()",
- {{{TESTDATA_DIR, "query_simplefunction.cpp"},
- "void f()\n \t{}",
- {"cc", "query_simplefunction.cpp"}}}};
+ {fileContainer.clone()}};
EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
- Contains(IsSourceRangeWithText(1, 1, 2, 4, "void f() {}"))))))
+ Contains(IsSourceRangeWithText(1, 1, 2, 4, fileContent))))))
.Times(1);
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage));
@@ -118,18 +121,13 @@ TEST_F(RefactoringServer, RequestSingleSourceRangesAndDiagnosticsForQueryMessage
TEST_F(RefactoringServer, RequestTwoSourceRangesAndDiagnosticsForQueryMessage)
{
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()",
- {{{TESTDATA_DIR, "query_simplefunction.cpp"},
- "void f()\n \t{}",
- {"cc", "query_simplefunction.cpp"}},
- {{TESTDATA_DIR, "query_simplefunction.cpp"},
- "void f()\n \t{}",
- {"cc", "query_simplefunction.cpp"}}}};
+ {fileContainer.clone(), fileContainer.clone()}};
EXPECT_CALL(mockRefactoringClient,
sourceRangesAndDiagnosticsForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
- Contains(IsSourceRangeWithText(1, 1, 2, 4, "void f() {}"))))))
+ Contains(IsSourceRangeWithText(1, 1, 2, 4, fileContent))))))
.Times(2);
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage));
@@ -140,9 +138,7 @@ TEST_F(RefactoringServer, RequestManySourceRangesAndDiagnosticsForQueryMessage)
std::vector<FileContainer> fileContainers;
std::fill_n(std::back_inserter(fileContainers),
std::thread::hardware_concurrency() + 3,
- FileContainer{{TESTDATA_DIR, "query_simplefunction.cpp"},
- "void f()\n \t{}",
- {"cc", "query_simplefunction.cpp"}});
+ fileContainer.clone());
RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()",
std::move(fileContainers)};
@@ -150,12 +146,34 @@ TEST_F(RefactoringServer, RequestManySourceRangesAndDiagnosticsForQueryMessage)
sourceRangesAndDiagnosticsForQueryMessage(
Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges,
Property(&SourceRangesContainer::sourceRangeWithTextContainers,
- Contains(IsSourceRangeWithText(1, 1, 2, 4, "void f() {}"))))))
+ Contains(IsSourceRangeWithText(1, 1, 2, 4, fileContent))))))
.Times(std::thread::hardware_concurrency() + 3);
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage));
}
+TEST_F(RefactoringServer, CancelJobs)
+{
+ refactoringServer.cancel();
+
+ ASSERT_TRUE(refactoringServer.isCancelingJobs());
+}
+
+TEST_F(RefactoringServer, PollEventLoopAsQueryIsRunning)
+{
+ std::vector<FileContainer> fileContainers;
+ std::fill_n(std::back_inserter(fileContainers),
+ std::thread::hardware_concurrency() + 3,
+ fileContainer.clone());
+ RequestSourceRangesAndDiagnosticsForQueryMessage requestSourceRangesAndDiagnosticsForQueryMessage{"functionDecl()", std::move(fileContainers)};
+ bool eventLoopIsPolled = false;
+ refactoringServer.supersedePollEventLoop([&] () { eventLoopIsPolled = true; });
+
+ refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(requestSourceRangesAndDiagnosticsForQueryMessage));
+
+ ASSERT_TRUE(eventLoopIsPolled);
+}
+
void RefactoringServer::SetUp()
{
refactoringServer.setClient(&mockRefactoringClient);
diff --git a/tests/unit/unittest/sourcerangecontainer-matcher.h b/tests/unit/unittest/sourcerangecontainer-matcher.h
index 1bd9776288..ddb9f1e823 100644
--- a/tests/unit/unittest/sourcerangecontainer-matcher.h
+++ b/tests/unit/unittest/sourcerangecontainer-matcher.h
@@ -52,8 +52,8 @@ MATCHER_P5(IsSourceRangeWithText, startLine, startColumn, endLine, endColumn, te
+ ", " + PrintToString(startColumn)
+ "), (" + PrintToString(endLine)
+ ", " + PrintToString(endColumn)
- + "), \"" + PrintToString(text)
- + "\")"
+ + "), " + PrintToString(text)
+ + ")"
)
{
return arg.start().line() == uint(startLine)
diff --git a/tests/unit/unittest/sourcerangeextractor-test.cpp b/tests/unit/unittest/sourcerangeextractor-test.cpp
new file mode 100644
index 0000000000..759ee2cd7f
--- /dev/null
+++ b/tests/unit/unittest/sourcerangeextractor-test.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+#include "testclangtool.h"
+
+#include <sourcerangeextractor.h>
+#include <sourcerangescontainer.h>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include <clang/Basic/SourceManager.h>
+#include <clang/Lex/Lexer.h>
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+using testing::Contains;
+using ::testing::Eq;
+using ::testing::StrEq;
+
+using ClangBackEnd::SourceRangeWithTextContainer;
+using ClangBackEnd::SourceRangeExtractor;
+
+namespace {
+
+class SourceRangeExtractor : public ::testing::Test
+{
+protected:
+ void SetUp() override;
+ void TearDown() override;
+
+protected:
+ TestClangTool clangTool{TESTDATA_DIR, "sourcerangeextractor_location.cpp", "", {"cc", "sourcerangeextractor_location.cpp"}};
+ ClangBackEnd::SourceRangesContainer sourceRangesContainer;
+ const clang::SourceManager &sourceManager{clangTool.sourceManager()};
+ ClangBackEnd::SourceRangeExtractor extractor{sourceManager, clangTool.languageOptions(), sourceRangesContainer};
+ clang::SourceLocation startLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID());
+ clang::SourceLocation endLocation = sourceManager.getLocForStartOfFile(sourceManager.getMainFileID()).getLocWithOffset(4);
+ clang::SourceRange sourceRange{startLocation, endLocation};
+ clang::SourceRange extendedSourceRange{startLocation, endLocation.getLocWithOffset(5)};
+};
+
+TEST_F(SourceRangeExtractor, ExtractSourceRangeContainer)
+{
+ SourceRangeWithTextContainer sourceRangeContainer{1, 1, 1, 0, 1, 10, 9, Utils::SmallString("int value;")};
+
+ extractor.addSourceRange(sourceRange);
+
+ ASSERT_THAT(extractor.sourceRangeWithTextContainers(), Contains(sourceRangeContainer));
+}
+
+TEST_F(SourceRangeExtractor, ExtendedSourceRange)
+{
+ auto range = extractor.extendSourceRangeToLastTokenEnd(sourceRange);
+
+ ASSERT_THAT(range, extendedSourceRange);
+}
+
+TEST_F(SourceRangeExtractor, FindStartOfLineInEmptyBuffer)
+{
+ clang::StringRef text = "";
+
+ auto found = ::SourceRangeExtractor::findStartOfLineInBuffer(text, 0);
+
+ ASSERT_THAT(found, StrEq(""));
+}
+
+TEST_F(SourceRangeExtractor, FindStartOfLineInBufferInFirstLine)
+{
+ clang::StringRef text = "first line";
+
+ auto found = ::SourceRangeExtractor::findStartOfLineInBuffer(text, 5);
+
+ ASSERT_THAT(found, StrEq("first line"));
+}
+
+TEST_F(SourceRangeExtractor, FindStartOfNewLineInBufferInSecondLine)
+{
+ clang::StringRef text = "first line\nsecond line";
+
+ auto found = ::SourceRangeExtractor::findStartOfLineInBuffer(text, 15);
+
+ ASSERT_THAT(found, StrEq("second line"));
+}
+
+TEST_F(SourceRangeExtractor, FindStartOfCarriageReturnInBufferInSecondLine)
+{
+ clang::StringRef text = "first line\rsecond line";
+
+ auto found = ::SourceRangeExtractor::findStartOfLineInBuffer(text, 15);
+
+ ASSERT_THAT(found, StrEq("second line"));
+}
+
+TEST_F(SourceRangeExtractor, FindStartOfNewLineCarriageReturnInBufferInSecondLine)
+{
+ clang::StringRef text = "first line\n\rsecond line";
+
+ auto found = ::SourceRangeExtractor::findStartOfLineInBuffer(text, 15);
+
+ ASSERT_THAT(found, StrEq("second line"));
+}
+
+TEST_F(SourceRangeExtractor, FindEndOfLineInEmptyBuffer)
+{
+ clang::StringRef text = "";
+
+ auto found = ::SourceRangeExtractor::findEndOfLineInBuffer(text, 0);
+
+ ASSERT_THAT(found, StrEq(""));
+}
+
+TEST_F(SourceRangeExtractor, FindEndOfLineInBuffer)
+{
+ clang::StringRef text = "first line";
+
+ auto found = ::SourceRangeExtractor::findEndOfLineInBuffer(text, 5);
+
+ ASSERT_THAT(found, StrEq(""));
+}
+
+TEST_F(SourceRangeExtractor, FindEndOfLineInBufferInFirstLineWithNewLine)
+{
+ clang::StringRef text = "first line\nsecond line\nthird line";
+
+ auto found = ::SourceRangeExtractor::findEndOfLineInBuffer(text, 15);
+
+ ASSERT_THAT(found, StrEq("\nthird line"));
+}
+
+TEST_F(SourceRangeExtractor, FindEndOfLineInBufferInFirstLineWithCarriageReturn)
+{
+ clang::StringRef text = "first line\rsecond line\rthird line";
+
+ auto found = ::SourceRangeExtractor::findEndOfLineInBuffer(text, 15);
+
+ ASSERT_THAT(found, StrEq("\rthird line"));
+}
+
+TEST_F(SourceRangeExtractor, EpandText)
+{
+ clang::StringRef text = "first line\nsecond line\nthird line\nforth line";
+
+ auto expandedText = ::SourceRangeExtractor::getExpandedText(text, 15, 25);
+
+ ASSERT_THAT(expandedText, StrEq("second line\nthird line"));
+}
+
+void SourceRangeExtractor::SetUp()
+{
+ TestGlobal::setSourceManager(&sourceManager);
+}
+
+void SourceRangeExtractor::TearDown()
+{
+ TestGlobal::setSourceManager(nullptr);
+}
+}
+
diff --git a/tests/unit/unittest/testclangtool.cpp b/tests/unit/unittest/testclangtool.cpp
new file mode 100644
index 0000000000..de41e42a81
--- /dev/null
+++ b/tests/unit/unittest/testclangtool.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "testclangtool.h"
+
+TestClangTool::TestClangTool(std::string &&directory,
+ std::string &&fileName,
+ std::string &&content,
+ std::vector<std::string> &&commandLine)
+{
+ addFile(std::move(directory), std::move(fileName), std::move(content), std::move(commandLine));
+
+ auto clangTool = createTool();
+
+ clangTool.buildASTs(asts);
+}
+
+const clang::ASTUnit *TestClangTool::ast() const
+{
+ return asts.front().get();
+}
+
+const clang::SourceManager &TestClangTool::sourceManager() const
+{
+ return ast()->getSourceManager();
+}
+
+const clang::LangOptions &TestClangTool::languageOptions() const
+{
+ return ast()->getLangOpts();
+}
diff --git a/tests/unit/unittest/testclangtool.h b/tests/unit/unittest/testclangtool.h
new file mode 100644
index 0000000000..f8ae0caf16
--- /dev/null
+++ b/tests/unit/unittest/testclangtool.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** 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 <clangtool.h>
+
+class TestClangTool : public ClangBackEnd::ClangTool
+{
+public:
+ TestClangTool(std::string &&directory,
+ std::string &&fileName,
+ std::string &&content,
+ std::vector<std::string> &&commandLine);
+
+ const clang::ASTUnit *ast() const;
+ const clang::SourceManager &sourceManager() const;
+ const clang::LangOptions &languageOptions() const;
+
+private:
+ std::vector<std::unique_ptr<clang::ASTUnit>> asts;
+};
+
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index 7bca7f4ee0..601efbbd91 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -34,7 +34,8 @@ SOURCES += \
smallstring-test.cpp \
spydummy.cpp \
unittests-main.cpp \
- utf8-test.cpp
+ utf8-test.cpp \
+ gtest-qt-printing.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \
@@ -72,7 +73,6 @@ SOURCES += \
diagnosticset-test.cpp \
diagnostic-test.cpp \
fixit-test.cpp \
- gtest-qt-printing.cpp \
highlightingmarksreporter-test.cpp \
highlightingmarks-test.cpp \
projectpart-test.cpp \
@@ -95,14 +95,16 @@ SOURCES += \
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \
clangquery-test.cpp \
- clangquerycurrentfilefindfilter-test.cpp \
clangqueryprojectfindfilter-test.cpp \
refactoringclientserverinprocess-test.cpp \
refactoringclient-test.cpp \
refactoringcompilationdatabase-test.cpp \
refactoringengine-test.cpp \
refactoringserver-test.cpp \
- symbolfinder-test.cpp
+ symbolfinder-test.cpp \
+ sourcerangeextractor-test.cpp \
+ gtest-clang-printing.cpp \
+ testclangtool.cpp
}
exists($$GOOGLEBENCHMARK_DIR) {
@@ -120,7 +122,7 @@ HEADERS += \
dynamicastmatcherdiagnosticcontainer-matcher.h \
mocksearchresult.h \
mocksearch.h \
- mocksearchhandle.h
+ mocksearchhandle.h \
!isEmpty(LIBCLANG_LIBS) {
HEADERS += \
@@ -137,7 +139,9 @@ HEADERS += \
HEADERS += \
mockrefactoringclientcallback.h \
mockrefactoringclient.h \
- mockrefactoringserver.h
+ mockrefactoringserver.h \
+ gtest-clang-printing.h \
+ testclangtool.h
}
OTHER_FILES += $$files(data/*)