Commit 4cdb5bab authored by Marco Bubke's avatar Marco Bubke

Clang: Add clang refactoring

Change-Id: I2e3f36f810276da3f8dc7dcc587b06f8edb586d3
GPush-Base: d02f51b48fc752fddcdef6dcb32b3f7f6c0195a3
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent 2b9edb35
......@@ -44,11 +44,20 @@ SOURCES += $$PWD/clangcodemodelserverinterface.cpp \
$$PWD/updatetranslationunitsforeditormessage.cpp \
$$PWD/updatevisibletranslationunitsmessage.cpp \
$$PWD/highlightingmarkcontainer.cpp \
$$PWD/refactoringclientinterface.cpp \
$$PWD/messageenvelop.cpp \
$$PWD/refactoringserverinterface.cpp \
$$PWD/refactoringserverproxy.cpp \
$$PWD/ipcclientinterface.cpp \
$$PWD/ipcserverinterface.cpp \
$$PWD/clangcodemodelconnectionclient.cpp \
$$PWD/documentannotationschangedmessage.cpp
$$PWD/documentannotationschangedmessage.cpp \
$$PWD/refactoringclientproxy.cpp \
$$PWD/sourcelocationscontainer.cpp \
$$PWD/sourcelocationcontainerv2.cpp \
$$PWD/sourcelocationsforrenamingmessage.cpp \
$$PWD/requestsourcelocationforrenamingmessage.cpp \
$$PWD/filepath.cpp
HEADERS += \
$$PWD/clangcodemodelserverinterface.h \
......@@ -92,6 +101,15 @@ HEADERS += \
$$PWD/ipcclientinterface.h \
$$PWD/ipcserverinterface.h \
$$PWD/clangcodemodelconnectionclient.h \
$$PWD/documentannotationschangedmessage.h
$$PWD/documentannotationschangedmessage.h \
$$PWD/refactoringclientinterface.h \
$$PWD/refactoringserverinterface.h \
$$PWD/refactoringserverproxy.h \
$$PWD/refactoringclientproxy.h \
$$PWD/sourcelocationscontainer.h \
$$PWD/sourcelocationcontainerv2.h \
$$PWD/sourcelocationsforrenamingmessage.h \
$$PWD/requestsourcelocationforrenamingmessage.h \
$$PWD/filepath.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
......@@ -106,7 +106,10 @@ enum class MessageType : quint8 {
CodeCompletedMessage,
TranslationUnitDoesNotExistMessage,
ProjectPartsDoNotExistMessage
ProjectPartsDoNotExistMessage,
SourceLocationsForRenamingMessage,
RequestSourceLocationsForRenamingMessage
};
template<MessageType messageEnumeration>
......
......@@ -25,14 +25,26 @@
#include "clangcodemodelconnectionclient.h"
#include <QCoreApplication>
#include <QTemporaryDir>
namespace ClangBackEnd {
namespace {
QString currentProcessId()
{
return QString::number(QCoreApplication::applicationPid());
}
}
ClangCodeModelConnectionClient::ClangCodeModelConnectionClient(
ClangCodeModelClientInterface *client)
: serverProxy_(client, ioDevice())
{
stdErrPrefixer().setPrefix("ClangCodeModelConnectionClient.error:");
stdOutPrefixer().setPrefix("ClangCodeModelConnectionClient.out:");
}
ClangCodeModelConnectionClient::~ClangCodeModelConnectionClient()
......@@ -55,4 +67,14 @@ void ClangCodeModelConnectionClient::resetCounter()
serverProxy_.resetCounter();
}
QString ClangCodeModelConnectionClient::connectionName() const
{
return temporaryDirectory().path() + QStringLiteral("/ClangBackEnd-") + currentProcessId();
}
QString ClangCodeModelConnectionClient::outputName() const
{
return QStringLiteral("ClangCodeModelConnectionClient");
}
} // namespace ClangBackEnd
......@@ -41,6 +41,8 @@ public:
protected:
void sendEndCommand() override;
void resetCounter() override;
QString connectionName() const override;
QString outputName() const override;
private:
ClangCodeModelServerProxy serverProxy_;
......
......@@ -38,25 +38,6 @@
namespace ClangBackEnd {
namespace {
const QTemporaryDir &temporaryDirectory()
{
static QTemporaryDir temporaryDirectory(QDir::tempPath() + QStringLiteral("/qtc-clang-XXXXXX"));
return temporaryDirectory;
}
QString currentProcessId()
{
return QString::number(QCoreApplication::applicationPid());
}
QString connectionName()
{
return temporaryDirectory().path() + QStringLiteral("/ClangBackEnd-") + currentProcessId();
}
}
ConnectionClient::ConnectionClient()
{
processAliveTimer.setInterval(10000);
......@@ -127,6 +108,23 @@ QProcessEnvironment ConnectionClient::processEnvironment() const
return processEnvironment;
}
const QTemporaryDir &ConnectionClient::temporaryDirectory() const
{
static QTemporaryDir temporaryDirectory(QDir::tempPath() + QStringLiteral("/qtc-clang-XXXXXX"));
return temporaryDirectory;
}
LinePrefixer &ConnectionClient::stdErrPrefixer()
{
return stdErrPrefixer_;
}
LinePrefixer &ConnectionClient::stdOutPrefixer()
{
return stdOutPrefixer_;
}
std::unique_ptr<QProcess> ConnectionClient::startProcess()
{
processIsStarting = true;
......@@ -207,17 +205,17 @@ void ConnectionClient::resetProcessIsStarting()
void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError socketError)
{
if (socketError != QLocalSocket::ServerNotFoundError)
qWarning() << "ClangCodeModel ConnectionClient LocalSocket Error:" << localSocket.errorString();
qWarning() << outputName() << "LocalSocket Error:" << localSocket.errorString();
}
void ConnectionClient::printStandardOutput()
{
qDebug("%s", stdOutPrefixer.prefix(process_->readAllStandardOutput()).constData());
qDebug("%s", stdOutPrefixer_.prefix(process_->readAllStandardOutput()).constData());
}
void ConnectionClient::printStandardError()
{
qDebug("%s", stdErrPrefixer.prefix(process_->readAllStandardError()).constData());
qDebug("%s", stdErrPrefixer_.prefix(process_->readAllStandardError()).constData());
}
void ConnectionClient::connectLocalSocketConnected()
......@@ -240,8 +238,6 @@ void ConnectionClient::finishProcess()
void ConnectionClient::finishProcess(std::unique_ptr<QProcess> &&process)
{
TIME_SCOPE_DURATION("ConnectionClient::finishProcess");
if (process) {
processAliveTimer.stop();
......@@ -274,7 +270,7 @@ bool ConnectionClient::waitForConnected()
}
}
qWarning() << "Cannot connect:" << localSocket.errorString();
qWarning() << outputName() << "cannot connect:" << localSocket.errorString();
return isConnected;
}
......
......@@ -35,6 +35,7 @@
QT_BEGIN_NAMESPACE
class QProcess;
class QTemporaryDir;
QT_END_NAMESPACE
class Utf8String;
......@@ -79,9 +80,14 @@ signals:
protected:
QIODevice *ioDevice();
const QTemporaryDir &temporaryDirectory() const;
LinePrefixer &stdErrPrefixer();
LinePrefixer &stdOutPrefixer();
virtual void sendEndCommand() = 0;
virtual void resetCounter() = 0;
virtual QString connectionName() const = 0;
virtual QString outputName() const = 0;
private:
std::unique_ptr<QProcess> startProcess();
......@@ -108,6 +114,9 @@ private:
QProcessEnvironment processEnvironment() const;
private:
LinePrefixer stdErrPrefixer_;
LinePrefixer stdOutPrefixer_;
mutable std::unique_ptr<QProcess> process_;
QLocalSocket localSocket;
QTimer processAliveTimer;
......@@ -115,8 +124,6 @@ private:
bool isAliveTimerResetted = false;
bool processIsStarting = false;
LinePrefixer stdErrPrefixer = QByteArrayLiteral("clangbackend.stderr: ");
LinePrefixer stdOutPrefixer = QByteArrayLiteral("clangbackend.stdout: ");
};
} // namespace ClangBackEnd
......@@ -83,7 +83,7 @@ public:
localServer.listen(ConnectionName::connectionName);
}
void setClangCodeModelServer(ServerInterface *ipcServer)
void setServer(ServerInterface *ipcServer)
{
this->ipcServer = ipcServer;
......
......@@ -25,7 +25,7 @@
#pragma once
#include <clangbackendipc_global.h>
#include "clangbackendipc_global.h"
#include <utf8string.h>
#include <utf8stringvector.h>
......
/****************************************************************************
**
** 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 "filepath.h"
namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const FilePath &filePath)
{
debug.nospace() << filePath.directory() << "/" << filePath.name();
return debug;
}
void PrintTo(const FilePath &filePath, ::std::ostream* os)
{
*os << filePath.directory() << "/" << filePath.name();
}
} // namespace ClangBackEnd
/****************************************************************************
**
** 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"
#include <utils/smallstring.h>
namespace ClangBackEnd {
struct FilePath
{
public:
FilePath() = default;
FilePath(Utils::SmallString &&directory, Utils::SmallString &&name)
: directory_(std::move(directory)),
name_(std::move(name))
{}
const Utils::SmallString &directory() const
{
return directory_;
}
const Utils::SmallString &name() const
{
return name_;
}
friend QDataStream &operator<<(QDataStream &out, const FilePath &filePath)
{
out << filePath.directory_;
out << filePath.name_;
return out;
}
friend QDataStream &operator>>(QDataStream &in, FilePath &filePath)
{
in >> filePath.directory_;
in >> filePath.name_;
return in;
}
friend bool operator==(const FilePath &first, const FilePath &second)
{
return first.directory_ == second.directory_
&& first.name_ == second.name_;
}
FilePath clone() const
{
return FilePath(directory_.clone(), name_.clone());
}
private:
Utils::SmallString directory_;
Utils::SmallString name_;
};
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const FilePath &filePath);
void PrintTo(const FilePath &filePath, ::std::ostream* os);
} // namespace ClangBackEnd
......@@ -28,10 +28,15 @@
namespace ClangBackEnd {
LinePrefixer::LinePrefixer(const QByteArray &prefix)
: m_prefix(prefix)
, m_previousIsEndingWithNewLine(true)
: m_prefix(prefix),
m_previousIsEndingWithNewLine(true)
{}
void LinePrefixer::setPrefix(const QByteArray &prefix)
{
m_prefix = prefix;
}
QByteArray LinePrefixer::prefix(const QByteArray &text)
{
QByteArray output = text;
......
......@@ -25,17 +25,20 @@
#pragma once
#include "clangbackendipc_global.h"
#include <QString>
#include <QTextStream>
#include <utf8string.h>
namespace ClangBackEnd {
class LinePrefixer
class CMBIPC_EXPORT LinePrefixer
{
public:
LinePrefixer() = delete;
LinePrefixer(const QByteArray &m_prefix);
LinePrefixer() = default;
LinePrefixer(const QByteArray &prefix);
void setPrefix(const QByteArray &prefix);
QByteArray prefix(const QByteArray &text);
private:
......
......@@ -25,7 +25,7 @@
#pragma once
#include <clangbackendipc_global.h>
#include "clangbackendipc_global.h"
#include <utf8stringvector.h>
......
/****************************************************************************
**
** 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 "refactoringclientinterface.h"
#include "messageenvelop.h"
#include "sourcelocationsforrenamingmessage.h"
#include <QDebug>
namespace ClangBackEnd {
void RefactoringClientInterface::dispatch(const MessageEnvelop &messageEnvelop)
{
switch (messageEnvelop.messageType()) {
case MessageType::AliveMessage:
alive();
break;
case MessageType::SourceLocationsForRenamingMessage:
sourceLocationsForRenamingMessage(messageEnvelop.message<SourceLocationsForRenamingMessage>());
break;
default:
qWarning() << "Unknown IpcClientMessage";
}
}
} // namespace ClangBackEnd
/****************************************************************************
**
** 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 "ipcclientinterface.h"
#include <functional>
namespace ClangBackEnd {
class SourceLocationsForRenamingMessage;
class SourceLocationsContainer;
class CMBIPC_EXPORT RefactoringClientInterface : public IpcClientInterface
{
public:
using RenameCallback = std::function<void(const QString &,
const SourceLocationsContainer &,
int)>;
void dispatch(const MessageEnvelop &messageEnvelop) override;
virtual void alive() = 0;
virtual void sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message) = 0;
virtual void setLocalRenamingCallback(RenameCallback &&localRenamingCallback) = 0;
};
} // namespace ClangBackEnd
/****************************************************************************
**
** 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 "refactoringclientproxy.h"
#include "cmbalivemessage.h"
#include "messageenvelop.h"
#include "refactoringserverinterface.h"
#include "sourcelocationsforrenamingmessage.h"
#include <QDebug>
#include <QIODevice>
namespace ClangBackEnd {
RefactoringClientProxy::RefactoringClientProxy(RefactoringServerInterface *server, QIODevice *ioDevice)
: writeMessageBlock(ioDevice),
readMessageBlock(ioDevice),
server(server),
ioDevice(ioDevice)
{
QObject::connect(ioDevice, &QIODevice::readyRead, [this] () {RefactoringClientProxy::readMessages();});
}
RefactoringClientProxy::RefactoringClientProxy(RefactoringClientProxy &&other)
: writeMessageBlock(std::move(other.writeMessageBlock)),
readMessageBlock(std::move(other.readMessageBlock)),
server(std::move(other.server)),
ioDevice(std::move(other.ioDevice))
{
}
RefactoringClientProxy &RefactoringClientProxy::operator=(RefactoringClientProxy &&other)
{
writeMessageBlock = std::move(other.writeMessageBlock);
readMessageBlock = std::move(other.readMessageBlock);
server = std::move(other.server);
ioDevice = std::move(other.ioDevice);
return *this;
}
void RefactoringClientProxy::readMessages()
{
for (const MessageEnvelop &message : readMessageBlock.readAll())
server->dispatch(message);
}
void RefactoringClientProxy::alive()
{
writeMessageBlock.write(AliveMessage());
}
void RefactoringClientProxy::sourceLocationsForRenamingMessage(SourceLocationsForRenamingMessage &&message)
{
writeMessageBlock.write(message);
}
} // namespace ClangBackEnd
/****************************************************************************
**
** 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.
**