forked from qt-creator/qt-creator
Clang: Extend clang query
It's a first step to introduce clang query. Change-Id: I4d001a8883f56066765ce6bc561fa3f49611c0a4 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
44
src/libs/clangbackendipc/cancelmessage.cpp
Normal file
44
src/libs/clangbackendipc/cancelmessage.cpp
Normal file
@@ -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
|
||||
55
src/libs/clangbackendipc/cancelmessage.h
Normal file
55
src/libs/clangbackendipc/cancelmessage.h
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -122,7 +122,9 @@ enum class MessageType : quint8 {
|
||||
RequestSourceLocationsForRenamingMessage,
|
||||
|
||||
RequestSourceRangesAndDiagnosticsForQueryMessage,
|
||||
SourceRangesAndDiagnosticsForQueryMessage
|
||||
SourceRangesAndDiagnosticsForQueryMessage,
|
||||
|
||||
CancelMessage
|
||||
};
|
||||
|
||||
template<MessageType messageEnumeration>
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -25,13 +25,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clangbackendipc_global.h"
|
||||
|
||||
#include "filecontainerv2.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class CMBIPC_EXPORT RequestSourceRangesAndDiagnosticsForQueryMessage
|
||||
class RequestSourceRangesAndDiagnosticsForQueryMessage
|
||||
{
|
||||
public:
|
||||
RequestSourceRangesAndDiagnosticsForQueryMessage() = default;
|
||||
|
||||
32
src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp
Normal file
32
src/libs/clangbackendipc/sourcefilepathcontainerbase.cpp
Normal file
@@ -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
|
||||
@@ -44,10 +44,12 @@ public:
|
||||
|
||||
void insertFilePath(uint fileId, Utils::SmallString &&fileDirectory, Utils::SmallString &&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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
std::unique_ptr<SearchHandleInterface> searchHandle;
|
||||
ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage createMessage(
|
||||
const QString &queryText) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<SearchHandle> searchHandle;
|
||||
std::vector<CppTools::ProjectPart::Ptr> projectParts;
|
||||
ClangBackEnd::RefactoringServerInterface &server;
|
||||
SearchInterface &searchInterface;
|
||||
RefactoringClient &refactoringClient;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
return CppTools::CppModelManager::instance();
|
||||
}
|
||||
|
||||
bool isCppEditor(Core::IEditor *currentEditor)
|
||||
{
|
||||
return cppToolManager()->isCppEditor(currentEditor);
|
||||
}
|
||||
|
||||
CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath)
|
||||
{
|
||||
if (const auto parser = CppTools::BaseEditorDocumentParser::get(filePath))
|
||||
return parser->projectPart();
|
||||
return CppTools::ProjectPart::Ptr();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QtCreatorClangQueryFindFilter::findAll(const QString &queryText, Core::FindFlags findFlags)
|
||||
{
|
||||
prepareFind();
|
||||
|
||||
ClangQueryCurrentFileFindFilter::findAll(queryText, findFlags);
|
||||
ClangQueryProjectsFindFilter::findAll(queryText, findFlags);
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::vector<CppTools::ProjectPart::Ptr>
|
||||
convertProjectParts(const QList<CppTools::ProjectPart::Ptr> &projectPartList)
|
||||
{
|
||||
std::vector<CppTools::ProjectPart::Ptr> projectPartVector;
|
||||
projectPartVector.reserve(projectPartList.size());
|
||||
|
||||
std::copy(projectPartList.begin(), projectPartList.end(), std::back_inserter(projectPartVector));
|
||||
|
||||
return projectPartVector;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QtCreatorClangQueryFindFilter::prepareFind()
|
||||
{
|
||||
Core::IEditor *currentEditor = Core::EditorManager::currentEditor();
|
||||
ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::startupProject();
|
||||
|
||||
if (isCppEditor(currentEditor)) {
|
||||
Core::IDocument *currentDocument = currentEditor->document();
|
||||
auto currentTextDocument = static_cast<TextEditor::TextDocument*>(currentDocument);
|
||||
const QString filePath = currentDocument->filePath().toString();
|
||||
const CppTools::ProjectInfo projectInfo = CppTools::CppModelManager::instance()->projectInfo(currentProject);
|
||||
|
||||
setCurrentDocumentFilePath(filePath);
|
||||
setCurrentDocumentRevision(currentTextDocument->document()->revision());
|
||||
setProjectPart(projectPartForFile(filePath));
|
||||
|
||||
if (currentTextDocument->isModified())
|
||||
setUnsavedDocumentContent(currentTextDocument->document()->toPlainText());
|
||||
}
|
||||
setProjectParts(convertProjectParts(projectInfo.projectParts()));
|
||||
}
|
||||
|
||||
} // namespace ClangRefactoring
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
#include <coreplugin/find/searchresultwindow.h>
|
||||
|
||||
namespace Core {
|
||||
class SearchResultItem;
|
||||
}
|
||||
|
||||
namespace ClangRefactoring {
|
||||
|
||||
class QtCreatorSearch final : public SearchInterface
|
||||
@@ -36,9 +40,12 @@ 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;
|
||||
};
|
||||
|
||||
@@ -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, int lineNumber, const QString &lineText, int searchTermStart, int searchTermLength)
|
||||
void QtCreatorSearchHandle::addResult(const QString &fileName,
|
||||
const QString &lineText,
|
||||
Core::TextRange textRange)
|
||||
{
|
||||
searchResult->addResult(fileName, lineNumber, lineText, searchTermStart, searchTermLength);
|
||||
searchResult->addResult(fileName, lineText, textRange);
|
||||
}
|
||||
|
||||
void QtCreatorSearchHandle::setExpectedResultCount(uint count)
|
||||
{
|
||||
promise.setExpectedResultCount(count);
|
||||
}
|
||||
|
||||
void QtCreatorSearchHandle::setResultCounter(uint counter)
|
||||
{
|
||||
promise.setProgressValue(counter);
|
||||
}
|
||||
|
||||
void QtCreatorSearchHandle::finishSearch()
|
||||
{
|
||||
searchResult->finishSearch(false);
|
||||
promise.reportFinished();
|
||||
}
|
||||
|
||||
} // namespace ClangRefactoring
|
||||
|
||||
@@ -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 finishSearch();
|
||||
void setExpectedResultCount(uint count) override;
|
||||
void setResultCounter(uint counter) override;
|
||||
|
||||
void finishSearch() override;
|
||||
|
||||
private:
|
||||
Core::SearchResult *searchResult;
|
||||
QFutureInterface<void> promise;
|
||||
};
|
||||
|
||||
} // namespace ClangRefactoring
|
||||
|
||||
@@ -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()),
|
||||
searchHandle_->addResult(filePaths[sourceRangeWithText.fileHash()],
|
||||
sourceRangeWithText.text(),
|
||||
int(sourceRangeWithText.start().column()),
|
||||
int(sourceRangeWithText.end().column()));
|
||||
{{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
|
||||
|
||||
@@ -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
|
||||
|
||||
44
src/plugins/clangrefactoring/searchhandle.cpp
Normal file
44
src/plugins/clangrefactoring/searchhandle.cpp
Normal file
@@ -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
|
||||
56
src/plugins/clangrefactoring/searchhandle.h
Normal file
56
src/plugins/clangrefactoring/searchhandle.h
Normal file
@@ -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
|
||||
@@ -27,13 +27,18 @@
|
||||
|
||||
namespace ClangRefactoring {
|
||||
|
||||
SearchHandleInterface::SearchHandleInterface()
|
||||
SearchHandle::~SearchHandle()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SearchHandleInterface::~SearchHandleInterface()
|
||||
void SearchHandle::cancel()
|
||||
{
|
||||
server->cancel();
|
||||
}
|
||||
|
||||
void SearchHandle::setRefactoringServer(ClangBackEnd::RefactoringServerInterface *server)
|
||||
{
|
||||
this->server = server;
|
||||
}
|
||||
|
||||
} // namespace ClangRefactoring
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,5 +27,9 @@
|
||||
|
||||
namespace ClangRefactoring {
|
||||
|
||||
SearchInterface::~SearchInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace ClangRefactoring
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Submodule src/shared/qbs updated: ab14d325ea...0971e0b745
@@ -26,6 +26,7 @@
|
||||
#include "clangquery.h"
|
||||
|
||||
#include "sourcelocationsutils.h"
|
||||
#include "sourcerangeextractor.h"
|
||||
|
||||
#include <sourcerangescontainer.h>
|
||||
|
||||
@@ -76,17 +77,8 @@ 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);
|
||||
|
||||
std::for_each (std::make_move_iterator(asts.begin()),
|
||||
std::make_move_iterator(asts.end()),
|
||||
[&] (std::unique_ptr<clang::ASTUnit> &&ast) {
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
49
src/tools/clangrefactoringbackend/source/includecollector.h
Normal file
49
src/tools/clangrefactoringbackend/source/includecollector.h
Normal file
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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));
|
||||
|
||||
if (!cancelWork) {
|
||||
clangQuery.addFile(fileContainer.filePath().directory(),
|
||||
fileContainer.filePath().name(),
|
||||
fileContainer.takeUnsavedFileContent(),
|
||||
fileContainer.takeCommandLineArguments());
|
||||
|
||||
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());
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "symbolfinder.h"
|
||||
|
||||
#include "sourcefilecallbacks.h"
|
||||
#include "locationsourcefilecallbacks.h"
|
||||
#include "symbollocationfinderaction.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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); });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
DefaultValue<std::unique_ptr<ClangRefactoring::SearchHandleInterface>>::SetFactory([] () {
|
||||
return std::unique_ptr<ClangRefactoring::SearchHandleInterface>(new MockSearchHandle); });
|
||||
ON_CALL(mockSearch, startNewSearch(QStringLiteral("Clang Query"), findDeclQueryText))
|
||||
.WillByDefault(Return(ByMove(createSearchHandle())));
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<ClangRefactoring::SearchHandle> ClangQueryProjectFindFilter::createSearchHandle()
|
||||
{
|
||||
std::unique_ptr<ClangRefactoring::SearchHandle> handle(new NiceMock<MockSearchHandle>);
|
||||
handle->setRefactoringServer(&mockRefactoringServer);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
int value;
|
||||
|
||||
@@ -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
|
||||
|
||||
88
tests/unit/unittest/gtest-clang-printing.cpp
Normal file
88
tests/unit/unittest/gtest-clang-printing.cpp
Normal file
@@ -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() << ")";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
50
tests/unit/unittest/gtest-clang-printing.h
Normal file
50
tests/unit/unittest/gtest-clang-printing.h
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -41,6 +41,9 @@ public:
|
||||
MOCK_METHOD1(requestSourceRangesAndDiagnosticsForQueryMessage,
|
||||
void (const ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage&));
|
||||
|
||||
MOCK_METHOD0(cancel,
|
||||
void ());
|
||||
|
||||
void requestSourceLocationsForRenamingMessage(ClangBackEnd::RequestSourceLocationsForRenamingMessage &&message) override
|
||||
{
|
||||
requestSourceLocationsForRenamingMessage(message);
|
||||
|
||||
@@ -33,6 +33,6 @@ class MockSearch : public ClangRefactoring::SearchInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD2(startNewSearch,
|
||||
std::unique_ptr<ClangRefactoring::SearchHandleInterface>(const QString &searchLabel,
|
||||
std::unique_ptr<ClangRefactoring::SearchHandle>(const QString &searchLabel,
|
||||
const QString &searchTerm));
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
186
tests/unit/unittest/sourcerangeextractor-test.cpp
Normal file
186
tests/unit/unittest/sourcerangeextractor-test.cpp
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
53
tests/unit/unittest/testclangtool.cpp
Normal file
53
tests/unit/unittest/testclangtool.cpp
Normal file
@@ -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();
|
||||
}
|
||||
45
tests/unit/unittest/testclangtool.h
Normal file
45
tests/unit/unittest/testclangtool.h
Normal file
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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/*)
|
||||
|
||||
Reference in New Issue
Block a user