Merge remote-tracking branch 'origin/3.6'

Conflicts:
	src/libs/qmldebug/qmldebugclient.cpp
	src/libs/qmldebug/qmldebugclient.h
	src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp

Change-Id: I9594b4e9befc78f8138deb121f0bfc4212f7edbf
This commit is contained in:
Eike Ziller
2015-11-26 13:01:20 +01:00
49 changed files with 1071 additions and 110 deletions

17
dist/changes-3.6.0.md vendored
View File

@@ -21,6 +21,10 @@ Editing
* Fixed that Qt Creator tried to write auto-save files in read-only
directories
* Fixed possible crash with code completion (QTCREATORBUG-14875)
* Fixed that closing session was leaving invalid editor windows open
(QTCREATORBUG-15193)
* Fixed that editors were closing even when closing Qt Creator was cancelled
(QTCREATORBUG-14401)
Project Management
@@ -29,6 +33,10 @@ Project Management
(QTCREATORBUG-14606)
* Added option to synchronize kits between all projects in a session
(QTCREATORBUG-5823)
* Fixed that `%{CurrentBuild:Type}` was not expanded correctly
(QTCREATORBUG-15178)
* Fixed that `Stop applications before building` also stopped applications
when deploying (QTCREATORBUG-15281)
QMake Projects
@@ -39,6 +47,8 @@ QMake Projects
* Fixed that `QMAKE_EXT_H` was ignored for UI code model (QTCREATORBUG-14910)
* Fixed that `make` build step was not updated on environment changes
(QTCREATORBUG-14831)
* Fixed adding files to `.qrc` files through the project tree
(QTCREATORBUG-15277)
CMake Projects
@@ -50,9 +60,13 @@ CMake Projects
C++ Support
* Added support for `noexcept`
* Fixed crash with function arguments hint (QTCREATORBUG-15275)
* Fixed that object instantiation was sometimes highlighted as function call
(QTCREATORBUG-15212)
* Clang code model
* Added more diagnostic messages to editors
* Added Clang's Fix-its to refactoring actions (QTCREATORBUG-14868)
* Added option for additional command line arguments
Debugging
@@ -73,6 +87,7 @@ Analyzer
QML Profiler
* Improved performance of timeline view (QTCREATORBUG-14983)
* Fixed offset when dragging timeline categories (QTCREATORBUG-15333)
Qt Quick Designer
@@ -114,6 +129,7 @@ Android
(QTCREATORBUG-14832)
* Fixed deployment on devices without `readlink` (QTCREATORBUG-15006)
* Fixed debugging of signed applications (requires Qt 5.6) (QTCREATORBUG-13035)
* Fixed that building failed if Java is not in `PATH` (QTCREATORBUG-15382)
iOS
@@ -124,6 +140,7 @@ Remote Linux
* Added support for ECDSA public keys with 384 and 521 bits,
ECDSA user keys, and ECDSA key creation
* Fixed environment and working directory for Valgrind analyzer
* Fixed attaching to remote debugging server (QTCREATORBUG-15210)
Credits for these changes go to:
Aleix Pol

View File

@@ -0,0 +1,135 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 http://www.qt.io/terms-conditions. For further information
** use the contact form at http://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.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
****************************************************************************/
import QtQuick 2.1
import HelperWidgets 2.0
import QtQuick.Layouts 1.0
Column {
anchors.left: parent.left
anchors.right: parent.right
Section {
anchors.left: parent.left
anchors.right: parent.right
caption: qsTr("GridLayout")
SectionLayout {
Label {
text: qsTr("Columns")
}
SecondColumnLayout {
SpinBox {
backendValue: backendValues.columns
minimumValue: 0
maximumValue: 2000
decimals: 0
}
ExpandingSpacer {
}
}
Label {
text: qsTr("Rows")
}
SecondColumnLayout {
SpinBox {
backendValue: backendValues.rows
minimumValue: 0
maximumValue: 2000
decimals: 0
}
ExpandingSpacer {
}
}
Label {
text: qsTr("Flow")
}
SecondColumnLayout {
ComboBox {
model: ["LeftToRight", "TopToBottom"]
backendValue: backendValues.flow
Layout.fillWidth: true
scope: "GridLayout"
}
}
Label {
text: qsTr("Layout Direction")
}
SecondColumnLayout {
ComboBox {
model: ["LeftToRight", "RightToLeft"]
backendValue: backendValues.layoutDirection
Layout.fillWidth: true
scope: "Qt"
}
}
Label {
text: qsTr("Row Spacing")
}
SecondColumnLayout {
SpinBox {
backendValue: backendValues.rowSpacing
minimumValue: -4000
maximumValue: 4000
decimals: 0
}
ExpandingSpacer {
}
}
Label {
text: qsTr("Column Spacing")
}
SecondColumnLayout {
SpinBox {
backendValue: backendValues.columnSpacing
minimumValue: -4000
maximumValue: 4000
decimals: 0
}
ExpandingSpacer {
}
}
}
}
}

View File

@@ -46,7 +46,8 @@ SOURCES += $$PWD/ipcserverinterface.cpp \
$$PWD/requestdiagnosticsmessage.cpp \
$$PWD/registerunsavedfilesforeditormessage.cpp \
$$PWD/unregisterunsavedfilesforeditormessage.cpp \
$$PWD/updatetranslationunitsforeditormessage.cpp
$$PWD/updatetranslationunitsforeditormessage.cpp \
$$PWD/updatevisibletranslationunitsmessage.cpp
HEADERS += \
$$PWD/ipcserverinterface.h \
@@ -87,6 +88,7 @@ HEADERS += \
$$PWD/requestdiagnosticsmessage.h \
$$PWD/registerunsavedfilesforeditormessage.h \
$$PWD/unregisterunsavedfilesforeditormessage.h \
$$PWD/updatetranslationunitsforeditormessage.h
$$PWD/updatetranslationunitsforeditormessage.h \
$$PWD/updatevisibletranslationunitsmessage.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols

View File

@@ -49,6 +49,7 @@
#include "translationunitdoesnotexistmessage.h"
#include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include "updatevisibletranslationunitsmessage.h"
#include <QDataStream>
@@ -82,6 +83,8 @@ void Messages::registerMessages()
registerMetaType<RequestDiagnosticsMessage>();
registerMetaType<DiagnosticsChangedMessage>();
registerMetaType<UpdateVisibleTranslationUnitsMessage>();
registerMetaType<CompleteCodeMessage>();
registerMetaType<CodeCompletedMessage>();
registerMetaType<CodeCompletion>();

View File

@@ -50,6 +50,7 @@ class DiagnosticsChangedMessage;
class RequestDiagnosticsMessage;
class RegisterUnsavedFilesForEditorMessage;
class UnregisterUnsavedFilesForEditorMessage;
class UpdateVisibleTranslationUnitsMessage;
class CMBIPC_EXPORT IpcClientInterface : public IpcInterface
{

View File

@@ -39,6 +39,7 @@
#include "requestdiagnosticsmessage.h"
#include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include "updatevisibletranslationunitsmessage.h"
#include <QDebug>
#include <QVariant>
@@ -57,6 +58,8 @@ void IpcServerInterface::dispatch(const QVariant &message)
static const int unregisterUnsavedFilesForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterUnsavedFilesForEditorMessage");
static const int completeCodeMessageType = QMetaType::type("ClangBackEnd::CompleteCodeMessage");
static const int requestDiagnosticsMessageType = QMetaType::type("ClangBackEnd::RequestDiagnosticsMessage");
static const int updateVisibleTranslationUnitsMessageType = QMetaType::type("ClangBackEnd::UpdateVisibleTranslationUnitsMessage");
int type = message.userType();
@@ -80,6 +83,8 @@ void IpcServerInterface::dispatch(const QVariant &message)
completeCode(message.value<CompleteCodeMessage>());
else if (type == requestDiagnosticsMessageType)
requestDiagnostics(message.value<RequestDiagnosticsMessage>());
else if (type == updateVisibleTranslationUnitsMessageType)
updateVisibleTranslationUnits(message.value<UpdateVisibleTranslationUnitsMessage>());
else
qWarning() << "Unknown IpcServerMessage";
}

View File

@@ -54,6 +54,7 @@ public:
virtual void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) = 0;
virtual void completeCode(const CompleteCodeMessage &message) = 0;
virtual void requestDiagnostics(const RequestDiagnosticsMessage &message) = 0;
virtual void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) = 0;
void addClient(IpcClientInterface *client);
void removeClient(IpcClientInterface *client);

View File

@@ -42,6 +42,7 @@
#include <requestdiagnosticsmessage.h>
#include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <updatevisibletranslationunitsmessage.h>
#include <QLocalServer>
#include <QLocalSocket>
@@ -119,5 +120,10 @@ void IpcServerProxy::requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMe
writeMessageBlock.write(QVariant::fromValue(message));
}
void IpcServerProxy::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
writeMessageBlock.write(QVariant::fromValue(message));
}
} // namespace ClangBackEnd

View File

@@ -65,7 +65,7 @@ public:
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
void completeCode(const CompleteCodeMessage &message) override;
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
void readMessages();
void resetCounter();

View File

@@ -0,0 +1,116 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "updatevisibletranslationunitsmessage.h"
#include "container_common.h"
#include <QDataStream>
#include <QDebug>
#include <algorithm>
#include <iterator>
#include <ostream>
namespace ClangBackEnd {
UpdateVisibleTranslationUnitsMessage::UpdateVisibleTranslationUnitsMessage(
const Utf8String &currentEditorFilePath,
const Utf8StringVector &visibleEditorFilePaths)
: currentEditorFilePath_(currentEditorFilePath),
visibleEditorFilePaths_(visibleEditorFilePaths)
{
}
const Utf8String &UpdateVisibleTranslationUnitsMessage::currentEditorFilePath() const
{
return currentEditorFilePath_;
}
const Utf8StringVector &UpdateVisibleTranslationUnitsMessage::visibleEditorFilePaths() const
{
return visibleEditorFilePaths_;
}
QDataStream &operator<<(QDataStream &out, const UpdateVisibleTranslationUnitsMessage &message)
{
out << message.currentEditorFilePath_;
out << message.visibleEditorFilePaths_;
return out;
}
QDataStream &operator>>(QDataStream &in, UpdateVisibleTranslationUnitsMessage &message)
{
in >> message.currentEditorFilePath_;
in >> message.visibleEditorFilePaths_;
return in;
}
bool operator==(const UpdateVisibleTranslationUnitsMessage &first, const UpdateVisibleTranslationUnitsMessage &second)
{
return first.currentEditorFilePath_ == second.currentEditorFilePath_
&& first.visibleEditorFilePaths_ == second.visibleEditorFilePaths_;
}
bool operator<(const UpdateVisibleTranslationUnitsMessage &first, const UpdateVisibleTranslationUnitsMessage &second)
{
return first.currentEditorFilePath_ < second.currentEditorFilePath_
&& compareContainer(first.visibleEditorFilePaths_, second.visibleEditorFilePaths_);
}
QDebug operator<<(QDebug debug, const UpdateVisibleTranslationUnitsMessage &message)
{
debug.nospace() << "UpdateVisibleTranslationUnitsMessage(";
debug.nospace() << message.currentEditorFilePath() << ", ";
for (const Utf8String &visibleEditorFilePath : message.visibleEditorFilePaths())
debug.nospace() << visibleEditorFilePath << ", ";
debug.nospace() << ")";
return debug;
}
void PrintTo(const UpdateVisibleTranslationUnitsMessage &message, ::std::ostream* os)
{
*os << "UpdateVisibleTranslationUnitsMessage(";
*os << message.currentEditorFilePath().constData() << ", ";
auto visiblePaths = message.visibleEditorFilePaths();
std::copy(visiblePaths.cbegin(), visiblePaths.cend(), std::ostream_iterator<Utf8String>(*os, ", "));
*os << ")";
}
} // namespace ClangBackEnd

View File

@@ -0,0 +1,72 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CLANGBACKEND_UPDATEVISIBLETRANSLATIONUNITSMESSAGE_H
#define CLANGBACKEND_UPDATEVISIBLETRANSLATIONUNITSMESSAGE_H
#include <clangbackendipc_global.h>
#include <utf8stringvector.h>
#include <QMetaType>
namespace ClangBackEnd {
class CMBIPC_EXPORT UpdateVisibleTranslationUnitsMessage
{
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const UpdateVisibleTranslationUnitsMessage &message);
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, UpdateVisibleTranslationUnitsMessage &message);
friend CMBIPC_EXPORT bool operator==(const UpdateVisibleTranslationUnitsMessage &first, const UpdateVisibleTranslationUnitsMessage &second);
friend CMBIPC_EXPORT bool operator<(const UpdateVisibleTranslationUnitsMessage &first, const UpdateVisibleTranslationUnitsMessage &second);
public:
UpdateVisibleTranslationUnitsMessage() = default;
UpdateVisibleTranslationUnitsMessage(const Utf8String &currentEditorFilePath,
const Utf8StringVector &visibleEditorFilePaths);
const Utf8String &currentEditorFilePath() const;
const Utf8StringVector &visibleEditorFilePaths() const;
private:
Utf8String currentEditorFilePath_;
Utf8StringVector visibleEditorFilePaths_;
};
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const UpdateVisibleTranslationUnitsMessage &message);
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, UpdateVisibleTranslationUnitsMessage &message);
CMBIPC_EXPORT bool operator==(const UpdateVisibleTranslationUnitsMessage &first, const UpdateVisibleTranslationUnitsMessage &second);
CMBIPC_EXPORT bool operator<(const UpdateVisibleTranslationUnitsMessage &first, const UpdateVisibleTranslationUnitsMessage &second);
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const UpdateVisibleTranslationUnitsMessage &message);
void PrintTo(const UpdateVisibleTranslationUnitsMessage &message, ::std::ostream* os);
} // namespace ClangBackEnd
Q_DECLARE_METATYPE(ClangBackEnd::UpdateVisibleTranslationUnitsMessage)
#endif // CLANGBACKEND_UPDATEVISIBLETRANSLATIONUNITSMESSAGE_H

View File

@@ -426,6 +426,18 @@ void QmlDebugConnection::setMaximumDataStreamVersion(int maximumVersion)
d->maximumDataStreamVersion = maximumVersion;
}
QAbstractSocket::SocketState QmlDebugConnection::socketState() const
{
Q_D(const QmlDebugConnection);
// TODO: when merging into master, add clause for local socket
if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(d->device))
return socket->state();
else
return QAbstractSocket::UnconnectedState;
}
//
QmlDebugClientPrivate::QmlDebugClientPrivate()
: connection(0)
{

View File

@@ -51,6 +51,7 @@ public:
void connectToHost(const QString &hostName, quint16 port);
void startLocalServer(const QString &fileName);
QAbstractSocket::SocketState socketState() const;
int currentDataStreamVersion() const;
void setMaximumDataStreamVersion(int maximumVersion);

View File

@@ -269,6 +269,14 @@ void PrintTo(const Utf8String &text, ::std::ostream* os)
*os << "\"" << text.toByteArray().data() << "\"";
}
std::ostream& operator<<(std::ostream &os, const Utf8String &utf8String)
{
using std::ostream;
os << utf8String.constData();
return os;
}
uint qHash(const Utf8String &utf8String)
{
return qHash(utf8String.byteArray);

View File

@@ -36,6 +36,8 @@
#include <QByteArray>
#include <QMetaType>
#include <iosfwd>
class Utf8StringVector;
class Utf8String;
@@ -120,6 +122,7 @@ SQLITE_EXPORT QDataStream &operator<<(QDataStream &datastream, const Utf8String
SQLITE_EXPORT QDataStream &operator>>(QDataStream &datastream, Utf8String &text);
SQLITE_EXPORT QDebug operator<<(QDebug debug, const Utf8String &text);
SQLITE_EXPORT void PrintTo(const Utf8String &text, ::std::ostream* os);
SQLITE_EXPORT std::ostream& operator<<(std::ostream &os, const Utf8String &utf8String);
SQLITE_EXPORT uint qHash(const Utf8String &utf8String);

View File

@@ -8,6 +8,10 @@ QT += gui network qml
CONFIG += exceptions # used by portlist.cpp, textfileformat.cpp, and ssh/*
win32: LIBS += -luser32 -lshell32
# PortsGatherer
win32: LIBS += -liphlpapi -lws2_32
SOURCES += $$PWD/environment.cpp \
$$PWD/environmentmodel.cpp \
$$PWD/qtcprocess.cpp \

View File

@@ -1,8 +1,4 @@
include(../../qtcreatorlibrary.pri)
include(utils-lib.pri)
win32: LIBS += -luser32 -lshell32
# PortsGatherer
win32: LIBS += -liphlpapi -lws2_32
DEFINES += QTC_REL_TOOLS_PATH=$$shell_quote(\"$$relative_path($$IDE_LIBEXEC_PATH, $$IDE_BIN_PATH)\")

View File

@@ -308,7 +308,7 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
toolchainsForAbi.insert(ati.abi);
QSet<ProjectExplorer::Abi> qtVersionsForAbi;
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::versions()) {
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::unsortedVersions()) {
if (qtVersion->type() != QLatin1String(Constants::ANDROIDQT) || qtVersion->qtAbis().isEmpty())
continue;
qtVersionsForAbi.insert(qtVersion->qtAbis().first());

View File

@@ -106,7 +106,6 @@ bool AndroidToolChain::isValid() const
void AndroidToolChain::addToEnvironment(Environment &env) const
{
// TODO this vars should be configurable in projects -> build tab
// TODO invalidate all .pro files !!!
@@ -114,9 +113,15 @@ void AndroidToolChain::addToEnvironment(Environment &env) const
env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_PREFIX"), AndroidConfig::toolchainPrefix(targetAbi()));
env.set(QLatin1String("ANDROID_NDK_TOOLS_PREFIX"), AndroidConfig::toolsPrefix(targetAbi()));
env.set(QLatin1String("ANDROID_NDK_TOOLCHAIN_VERSION"), m_ndkToolChainVersion);
QString javaHome = AndroidConfigurations::currentConfig().openJDKLocation().toString();
if (!javaHome.isEmpty() && QFileInfo::exists(javaHome))
env.set(QLatin1String("JAVA_HOME"), javaHome);
const Utils::FileName javaHome = AndroidConfigurations::currentConfig().openJDKLocation();
if (!javaHome.isEmpty() && javaHome.toFileInfo().exists()) {
env.set(QLatin1String("JAVA_HOME"), javaHome.toString());
Utils::FileName javaBin = javaHome;
javaBin.appendPath(QLatin1String("bin"));
const QString jb = javaBin.toUserOutput();
if (!Utils::contains(env.path(), [&jb](const QString &p) { return p == jb; }))
env.prependOrSetPath(jb);
}
env.set(QLatin1String("ANDROID_HOME"), AndroidConfigurations::currentConfig().sdkLocation().toString());
env.set(QLatin1String("ANDROID_SDK_ROOT"), AndroidConfigurations::currentConfig().sdkLocation().toString());
}

View File

@@ -189,6 +189,11 @@ QList<QTextEdit::ExtraSelection> ClangDiagnosticManager::takeExtraSelections()
return extraSelections;
}
void ClangDiagnosticManager::clearDiagnosticsWithFixIts()
{
m_fixItdiagnostics.clear();
}
void ClangDiagnosticManager::generateEditorSelections()
{
m_extraSelections.clear();

View File

@@ -56,6 +56,8 @@ public:
const QVector<ClangBackEnd::DiagnosticContainer> &diagnosticsWithFixIts() const;
QList<QTextEdit::ExtraSelection> takeExtraSelections();
void clearDiagnosticsWithFixIts();
private:
QString filePath() const;
void filterDiagnostics(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);

View File

@@ -224,6 +224,11 @@ ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainer() const
return fileContainer(m_projectPart.data());
}
void ClangEditorDocumentProcessor::clearDiagnosticsWithFixIts()
{
m_diagnosticManager.clearDiagnosticsWithFixIts();
}
ClangEditorDocumentProcessor *ClangEditorDocumentProcessor::get(const QString &filePath)
{
return qobject_cast<ClangEditorDocumentProcessor *>(BaseEditorDocumentProcessor::get(filePath));

View File

@@ -81,6 +81,8 @@ public:
ClangBackEnd::FileContainer fileContainer() const;
void clearDiagnosticsWithFixIts();
public:
static ClangEditorDocumentProcessor *get(const QString &filePath);

View File

@@ -197,6 +197,15 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool
}
}
namespace {
void clearDiagnosticFixIts(const QString &filePath)
{
auto processor = ClangEditorDocumentProcessor::get(filePath);
if (processor)
processor->clearDiagnosticsWithFixIts();
}
}
void ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit(int position,
int /*charsRemoved*/,
int /*charsAdded*/)
@@ -206,6 +215,8 @@ void ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit(int
m_ipcCommunicator.updateChangeContentStartPosition(document->filePath().toString(),
position);
m_ipcCommunicator.updateTranslationUnitIfNotCurrentDocument(document);
clearDiagnosticFixIts(document->filePath().toString());
}
void ModelManagerSupportClang::onCppDocumentAboutToReloadOnUnsavedFile()

View File

@@ -59,6 +59,16 @@ ProjectPart::ProjectPart()
{
}
static ProjectPart::HeaderPath toProjectPartHeaderPath(const ProjectExplorer::HeaderPath &headerPath)
{
const ProjectPart::HeaderPath::Type headerPathType =
headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath
? ProjectPart::HeaderPath::FrameworkPath
: ProjectPart::HeaderPath::IncludePath;
return ProjectPart::HeaderPath(headerPath.path(), headerPathType);
}
/*!
\brief Retrieves info from concrete compiler using it's flags.
@@ -106,10 +116,9 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc,
const QList<ProjectExplorer::HeaderPath> headers = tc->systemHeaderPaths(commandLineFlags, sysRoot);
foreach (const ProjectExplorer::HeaderPath &header, headers) {
headerPaths << ProjectPart::HeaderPath(header.path(),
header.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath
? ProjectPart::HeaderPath::FrameworkPath
: ProjectPart::HeaderPath::IncludePath);
const HeaderPath headerPath = toProjectPartHeaderPath(header);
if (!headerPaths.contains(headerPath))
headerPaths << headerPath;
}
toolchainDefines = tc->predefinedMacros(commandLineFlags);

View File

@@ -144,7 +144,7 @@ static QHash<Platform, ClangToolChain *> findToolChains(const QList<Platform> &p
static QHash<Abi::Architecture, QSet<BaseQtVersion *>> iosQtVersions()
{
QHash<Abi::Architecture, QSet<BaseQtVersion *>> versions;
foreach (BaseQtVersion *qtVersion, QtVersionManager::versions()) {
foreach (BaseQtVersion *qtVersion, QtVersionManager::unsortedVersions()) {
if (!qtVersion->isValid() || qtVersion->type() != QLatin1String(Constants::IOSQT))
continue;
foreach (const Abi &abi, qtVersion->qtAbis())

View File

@@ -108,7 +108,7 @@ QList<BuildInfo *> QmakeProjectImporter::import(const FileName &importPath, bool
qCDebug(logs) << " QMake:" << canonicalQmakeBinary;
BaseQtVersion *version
= Utils::findOrDefault(QtVersionManager::versions(),
= Utils::findOrDefault(QtVersionManager::unsortedVersions(),
[&canonicalQmakeBinary](BaseQtVersion *v) -> bool {
QFileInfo vfi = v->qmakeCommand().toFileInfo();
FileName current = FileName::fromString(vfi.canonicalFilePath());

View File

@@ -270,9 +270,22 @@ void QmlProfilerClientManager::tryToConnect()
if (d->connection && d->connection->isConnected()) {
d->connectionTimer.stop();
d->connectionAttempts = 0;
} else if (d->connection &&
d->connection->socketState() != QAbstractSocket::ConnectedState) {
// Replace the connection after trying for some time. On some operating systems (OSX) the
// very first connection to a TCP server takes a very long time to get established.
// delete directly here, so that any pending events aren't delivered. We don't want the
// connection first to be established and then torn down again.
delete d->connection;
d->connection = 0;
connectClient(d->tcpPort);
connectToClient();
} else if (d->connectionAttempts == 50) {
d->connectionTimer.stop();
d->connectionAttempts = 0;
delete d->connection; // delete directly.
d->connection = 0;
QMessageBox *infoBox = QmlProfilerTool::requestMessageBox();
infoBox->setIcon(QMessageBox::Critical);
@@ -333,14 +346,11 @@ void QmlProfilerClientManager::logState(const QString &msg)
void QmlProfilerClientManager::retryMessageBoxFinished(int result)
{
if (d->connection) {
QTC_ASSERT(!d->connection->isConnected(), return);
if (d->connection->isConnecting())
d->connection->disconnect();
}
QTC_ASSERT(!d->connection, disconnectClient());
switch (result) {
case QMessageBox::Retry: {
connectClient(d->tcpPort);
d->connectionAttempts = 0;
d->connectionTimer.start();
break;

View File

@@ -502,7 +502,7 @@ static void updateDocumentation()
void QtVersionManager::updateDumpFor(const FileName &qmakeCommand)
{
foreach (BaseQtVersion *v, versions()) {
foreach (BaseQtVersion *v, unsortedVersions()) {
if (v->qmakeCommand() == qmakeCommand)
v->recheckDumper();
}
@@ -630,7 +630,7 @@ void QtVersionManager::setNewQtVersions(QList<BaseQtVersion *> newVersions)
BaseQtVersion *QtVersionManager::qtVersionForQMakeBinary(const FileName &qmakePath)
{
return Utils::findOrDefault(versions(), Utils::equal(&BaseQtVersion::qmakeCommand, qmakePath));
return Utils::findOrDefault(unsortedVersions(), Utils::equal(&BaseQtVersion::qmakeCommand, qmakePath));
}
} // namespace QtVersion

View File

@@ -54,6 +54,7 @@
#include <translationunitdoesnotexistmessage.h>
#include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <updatevisibletranslationunitsmessage.h>
#include <QCoreApplication>
#include <QDebug>
@@ -243,6 +244,18 @@ void ClangIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message
}
}
void ClangIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
TIME_SCOPE_DURATION("ClangIpcServer::updateVisibleTranslationUnits");
try {
translationUnits.setCurrentEditor(message.currentEditorFilePath());
translationUnits.setVisibleEditors(message.visibleEditorFilePaths());
} catch (const std::exception &exception) {
qWarning() << "Error in ClangIpcServer::updateVisibleTranslationUnits:" << exception.what();
}
}
const TranslationUnits &ClangIpcServer::translationUnitsForTestOnly() const
{
return translationUnits;

View File

@@ -61,6 +61,7 @@ public:
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
void completeCode(const CompleteCodeMessage &message) override;
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
const TranslationUnits &translationUnitsForTestOnly() const;

View File

@@ -30,6 +30,8 @@
#include "commandlinearguments.h"
#include <utf8string.h>
#include <iostream>
namespace ClangBackEnd {
@@ -67,13 +69,23 @@ const char *CommandLineArguments::at(int position) const
return m_arguments.at(uint(position));
}
static Utf8String maybeQuoted(const char *argumentAsCString)
{
const auto quotationMark = Utf8StringLiteral("\"");
const auto argument = Utf8String::fromUtf8(argumentAsCString);
if (argument.contains(quotationMark))
return argument;
return quotationMark + argument + quotationMark;
}
void CommandLineArguments::print() const
{
using namespace std;
cerr << "Arguments to libclang:";
for (const auto &argument : m_arguments)
cerr << ' ' << argument;
cerr << ' ' << maybeQuoted(argument).constData();
cerr << endl;
}

View File

@@ -241,11 +241,23 @@ HighlightingType literalKind(const Cursor &cursor)
Q_UNREACHABLE();
}
bool hasOperatorName(const char *operatorString)
{
return std::strncmp(operatorString, "operator", 8) == 0;
}
HighlightingType operatorKind(const Cursor &cursor)
{
if (hasOperatorName(cursor.spelling().cString()))
return HighlightingType::Operator;
else
return HighlightingType::Invalid;
}
HighlightingType punctationKind(const Cursor &cursor)
{
switch (cursor.kind()) {
case CXCursor_DeclRefExpr: return HighlightingType::Operator;
case CXCursor_DeclRefExpr: return operatorKind(cursor);
default: return HighlightingType::Invalid;
}
}

View File

@@ -83,8 +83,10 @@ public:
CXTranslationUnit translationUnit = nullptr;
CXIndex index = nullptr;
uint documentRevision = 0;
bool needsToBeReparsed = false;
bool hasNewDiagnostics = false;
bool needsToBeReparsed = false;
bool hasNewDiagnostics = true;
bool isUsedByCurrentEditor = false;
bool isVisibleInEditor = false;
};
TranslationUnitData::TranslationUnitData(const Utf8String &filePath,
@@ -125,6 +127,26 @@ bool TranslationUnit::isNull() const
return !d;
}
void TranslationUnit::setIsUsedByCurrentEditor(bool isUsedByCurrentEditor)
{
d->isUsedByCurrentEditor = isUsedByCurrentEditor;
}
bool TranslationUnit::isUsedByCurrentEditor() const
{
return d->isUsedByCurrentEditor;
}
void TranslationUnit::setIsVisibleInEditor(bool isVisibleInEditor)
{
d->isVisibleInEditor = isVisibleInEditor;
}
bool TranslationUnit::isVisibleInEditor() const
{
return d->isVisibleInEditor;
}
void TranslationUnit::reset()
{
d.reset();

View File

@@ -86,6 +86,12 @@ public:
bool isNull() const;
void setIsUsedByCurrentEditor(bool isUsedByCurrentEditor);
bool isUsedByCurrentEditor() const;
void setIsVisibleInEditor(bool isVisibleInEditor);
bool isVisibleInEditor() const;
void reset();
void reparse() const;

View File

@@ -39,6 +39,8 @@
#include <QDebug>
#include <algorithm>
namespace ClangBackEnd {
bool operator==(const FileContainer &fileContainer, const TranslationUnit &translationUnit)
@@ -62,10 +64,8 @@ void TranslationUnits::create(const QVector<FileContainer> &fileContainers)
{
checkIfTranslationUnitsDoesNotExists(fileContainers);
for (const FileContainer &fileContainer : fileContainers) {
for (const FileContainer &fileContainer : fileContainers)
createTranslationUnit(fileContainer);
updateTranslationUnitsWithChangedDependency(fileContainer.filePath());
}
}
void TranslationUnits::update(const QVector<FileContainer> &fileContainers)
@@ -97,6 +97,18 @@ void TranslationUnits::remove(const QVector<FileContainer> &fileContainers)
updateTranslationUnitsWithChangedDependencies(fileContainers);
}
void TranslationUnits::setCurrentEditor(const Utf8String &filePath)
{
for (TranslationUnit &translationUnit : translationUnits_)
translationUnit.setIsUsedByCurrentEditor(translationUnit.filePath() == filePath);
}
void TranslationUnits::setVisibleEditors(const Utf8StringVector &filePaths)
{
for (TranslationUnit &translationUnit : translationUnits_)
translationUnit.setIsVisibleInEditor(filePaths.contains(translationUnit.filePath()));
}
const TranslationUnit &TranslationUnits::translationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const
{
checkIfProjectPartExists(projectPartId);
@@ -153,14 +165,55 @@ void TranslationUnits::updateTranslationUnitsWithChangedDependencies(const QVect
DiagnosticSendState TranslationUnits::sendChangedDiagnostics()
{
for (const auto &translationUnit : translationUnits_) {
if (translationUnit.hasNewDiagnostics()) {
sendDiagnosticChangedMessage(translationUnit);
return DiagnosticSendState::MaybeThereAreMoreDiagnostics;
}
auto diagnosticSendState = sendChangedDiagnosticsForCurrentEditor();
if (diagnosticSendState == DiagnosticSendState::NoDiagnosticSend)
diagnosticSendState = sendChangedDiagnosticsForVisibleEditors();
if (diagnosticSendState == DiagnosticSendState::NoDiagnosticSend)
diagnosticSendState = sendChangedDiagnosticsForAll();
return diagnosticSendState;
}
template<class Predicate>
DiagnosticSendState TranslationUnits::sendChangedDiagnostics(Predicate predicate)
{
auto foundTranslationUnit = std::find_if(translationUnits_.begin(),
translationUnits_.end(),
predicate);
if (foundTranslationUnit != translationUnits().end()) {
sendDiagnosticChangedMessage(*foundTranslationUnit);
return DiagnosticSendState::MaybeThereAreMoreDiagnostics;
}
return DiagnosticSendState::AllDiagnosticSend;
return DiagnosticSendState::NoDiagnosticSend;
}
DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForCurrentEditor()
{
auto hasDiagnosticsForCurrentEditor = [] (const TranslationUnit &translationUnit) {
return translationUnit.isUsedByCurrentEditor() && translationUnit.hasNewDiagnostics();
};
return sendChangedDiagnostics(hasDiagnosticsForCurrentEditor);
}
DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForVisibleEditors()
{
auto hasDiagnosticsForVisibleEditor = [] (const TranslationUnit &translationUnit) {
return translationUnit.isVisibleInEditor() && translationUnit.hasNewDiagnostics();
};
return sendChangedDiagnostics(hasDiagnosticsForVisibleEditor);
}
DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForAll()
{
auto hasDiagnostics = [] (const TranslationUnit &translationUnit) {
return translationUnit.hasNewDiagnostics();
};
return sendChangedDiagnostics(hasDiagnostics);
}
void TranslationUnits::setSendChangeDiagnosticsCallback(std::function<void(const DiagnosticsChangedMessage &)> &&callback)

View File

@@ -49,8 +49,8 @@ class DiagnosticsChangedMessage;
enum class DiagnosticSendState
{
AllDiagnosticSend,
MaybeThereAreMoreDiagnostics
NoDiagnosticSend,
MaybeThereAreMoreDiagnostics,
};
class TranslationUnits
@@ -62,6 +62,9 @@ public:
void update(const QVector<FileContainer> &fileContainers);
void remove(const QVector<FileContainer> &fileContainers);
void setCurrentEditor(const Utf8String &filePath);
void setVisibleEditors(const Utf8StringVector &filePaths);
const TranslationUnit &translationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const;
const TranslationUnit &translationUnit(const FileContainer &fileContainer) const;
bool hasTranslationUnit(const Utf8String &filePath) const;
@@ -76,6 +79,9 @@ public:
void updateTranslationUnitsWithChangedDependencies(const QVector<FileContainer> &fileContainers);
DiagnosticSendState sendChangedDiagnostics();
DiagnosticSendState sendChangedDiagnosticsForCurrentEditor();
DiagnosticSendState sendChangedDiagnosticsForVisibleEditors();
DiagnosticSendState sendChangedDiagnosticsForAll();
void setSendChangeDiagnosticsCallback(std::function<void(const DiagnosticsChangedMessage&)> &&callback);
@@ -99,6 +105,9 @@ private:
void sendDiagnosticChangedMessage(const TranslationUnit &translationUnit);
void removeTranslationUnits(const QVector<FileContainer> &fileContainers);
template<class Predicate>
DiagnosticSendState sendChangedDiagnostics(Predicate predicate);
private:
ClangFileSystemWatcher fileSystemWatcher;
std::function<void(const DiagnosticsChangedMessage&)> sendDiagnosticsChangedCallback;

View File

@@ -114,6 +114,7 @@ public:
IosTool *iosTool();
public slots:
void handleNewRelayConnection();
void removeRelayConnection(Relayer *relayer);
protected:
virtual void newRelayConnection() = 0;
@@ -231,9 +232,12 @@ void Relayer::setClientSocket(QTcpSocket *clientSocket)
{
QTC_CHECK(!m_clientSocket);
m_clientSocket = clientSocket;
if (m_clientSocket)
if (m_clientSocket) {
connect(m_clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(handleClientHasError(QAbstractSocket::SocketError)));
connect(m_clientSocket, &QAbstractSocket::disconnected,
this, [this](){server()->removeRelayConnection(this);});
}
}
bool Relayer::startRelay(int serverFileDescriptor)
@@ -354,7 +358,7 @@ void Relayer::handleClientHasData()
void Relayer::handleClientHasError(QAbstractSocket::SocketError error)
{
iosTool()->errorMsg(tr("iOS Debugging connection to creator failed with error %1").arg(error));
iosTool()->stopRelayServers();
server()->removeRelayConnection(this);
}
IosTool *Relayer::iosTool()
@@ -446,6 +450,12 @@ void RelayServer::handleNewRelayConnection()
newRelayConnection();
}
void RelayServer::removeRelayConnection(Relayer *relayer)
{
m_connections.removeAll(relayer);
relayer->deleteLater();
}
SingleRelayServer::SingleRelayServer(IosTool *parent,
int serverFileDescriptor) :
RelayServer(parent)
@@ -458,9 +468,7 @@ SingleRelayServer::SingleRelayServer(IosTool *parent,
void SingleRelayServer::newRelayConnection()
{
if (m_connections.size() > 0) {
m_server.close();
QTcpSocket *s = m_server.nextPendingConnection();
delete s;
delete m_server.nextPendingConnection();
return;
}
QTcpSocket *clientSocket = m_server.nextPendingConnection();
@@ -469,7 +477,6 @@ void SingleRelayServer::newRelayConnection()
m_connections.append(newConnection);
newConnection->startRelay(m_serverFileDescriptor);
}
m_server.close();
}
GenericRelayServer::GenericRelayServer(IosTool *parent, int remotePort,

View File

@@ -43,6 +43,7 @@
#include "requestdiagnosticsmessage.h"
#include "unregisterunsavedfilesforeditormessage.h"
#include "updatetranslationunitsforeditormessage.h"
#include "updatevisibletranslationunitsmessage.h"
#include <QCoreApplication>
#include <QDebug>
@@ -106,6 +107,11 @@ void EchoIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message)
echoMessage(QVariant::fromValue(message));
}
void EchoIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message)
{
echoMessage(QVariant::fromValue(message));
}
void EchoIpcServer::echoMessage(const QVariant &message)
{
client()->echo(EchoMessage(message));

View File

@@ -49,6 +49,7 @@ public:
void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override;
void completeCode(const CompleteCodeMessage &message) override;
void requestDiagnostics(const RequestDiagnosticsMessage &message) override;
void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override;
private:
void echoMessage(const QVariant &message);

View File

@@ -47,6 +47,7 @@
#include <projectpartsdonotexistmessage.h>
#include <translationunitdoesnotexistmessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <updatevisibletranslationunitsmessage.h>
#include <QBuffer>
#include <QFile>
@@ -76,12 +77,20 @@ using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::TranslationUnitDoesNotExistMessage;
using ClangBackEnd::ProjectPartsDoNotExistMessage;
using ClangBackEnd::UpdateTranslationUnitsForEditorMessage;
using ClangBackEnd::UpdateVisibleTranslationUnitsMessage;
MATCHER_P3(HasDirtyTranslationUnit, filePath, projectPartId, documentRevision,
MATCHER_P5(HasDirtyTranslationUnit,
filePath,
projectPartId,
documentRevision,
isNeedingReparse,
hasNewDiagnostics,
std::string(negation ? "isn't" : "is")
+ " translation unit with file path "+ PrintToString(filePath)
+ " and project " + PrintToString(projectPartId)
+ " and document revision " + PrintToString(documentRevision)
+ " and isNeedingReparse = " + PrintToString(isNeedingReparse)
+ " and hasNewDiagnostics = " + PrintToString(hasNewDiagnostics)
)
{
auto &&translationUnits = arg.translationUnitsForTestOnly();
@@ -89,16 +98,24 @@ MATCHER_P3(HasDirtyTranslationUnit, filePath, projectPartId, documentRevision,
auto translationUnit = translationUnits.translationUnit(filePath, projectPartId);
if (translationUnit.documentRevision() == documentRevision) {
if (translationUnit.hasNewDiagnostics()) {
if (translationUnit.isNeedingReparse())
return true;
if (translationUnit.hasNewDiagnostics() && !hasNewDiagnostics) {
*result_listener << "hasNewDiagnostics is true";
return false;
} else if (!translationUnit.hasNewDiagnostics() && hasNewDiagnostics) {
*result_listener << "hasNewDiagnostics is false";
return false;
}
if (translationUnit.isNeedingReparse() && !isNeedingReparse) {
*result_listener << "isNeedingReparse is true";
return false;
} else if (!translationUnit.isNeedingReparse() && isNeedingReparse) {
*result_listener << "isNeedingReparse is false";
return false;
}
*result_listener << "hasNewDiagnostics is false";
return false;
return true;
}
*result_listener << "revision number is " << PrintToString(translationUnit.documentRevision());
@@ -120,11 +137,13 @@ protected:
void registerProjectPart();
void changeProjectPartArguments();
void changeProjectPartArgumentsToWrongValues();
void updateVisibilty(const Utf8String &currentEditor, const Utf8String &additionalVisibleEditor);
static const Utf8String unsavedContent(const QString &unsavedFilePath);
protected:
MockIpcClient mockIpcClient;
ClangBackEnd::ClangIpcServer clangServer;
const ClangBackEnd::TranslationUnits &translationUnits = clangServer.translationUnitsForTestOnly();
const Utf8String projectPartId = Utf8StringLiteral("pathToProjectPart.pro");
const Utf8String functionTestFilePath = Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp");
const Utf8String variableTestFilePath = Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp");
@@ -133,53 +152,6 @@ protected:
const Utf8String parseErrorTestFilePath = Utf8StringLiteral(TESTDATA_DIR"/complete_translationunit_parse_error.cpp");
};
void ClangIpcServer::SetUp()
{
clangServer.addClient(&mockIpcClient);
registerProjectPart();
registerFiles();
}
void ClangIpcServer::registerFiles()
{
RegisterTranslationUnitForEditorMessage message({FileContainer(functionTestFilePath, projectPartId, unsavedContent(unsavedTestFilePath), true),
FileContainer(variableTestFilePath, projectPartId)});
clangServer.registerTranslationUnitsForEditor(message);
}
void ClangIpcServer::registerProjectPart()
{
RegisterProjectPartsForEditorMessage message({ProjectPartContainer(projectPartId)});
clangServer.registerProjectPartsForEditor(message);
}
void ClangIpcServer::changeProjectPartArguments()
{
RegisterProjectPartsForEditorMessage message({ProjectPartContainer(projectPartId, {Utf8StringLiteral("-DArgumentDefinition")})});
clangServer.registerProjectPartsForEditor(message);
}
void ClangIpcServer::changeProjectPartArgumentsToWrongValues()
{
RegisterProjectPartsForEditorMessage message({ProjectPartContainer(projectPartId, {Utf8StringLiteral("-blah")})});
clangServer.registerProjectPartsForEditor(message);
}
const Utf8String ClangIpcServer::unsavedContent(const QString &unsavedFilePath)
{
QFile unsavedFileContentFile(unsavedFilePath);
bool isOpen = unsavedFileContentFile.open(QIODevice::ReadOnly | QIODevice::Text);
if (!isOpen)
ADD_FAILURE() << "File with the unsaved content cannot be opened!";
return Utf8String::fromByteArray(unsavedFileContentFile.readAll());
}
TEST_F(ClangIpcServer, GetCodeCompletion)
{
CompleteCodeMessage completeCodeMessage(functionTestFilePath,
@@ -406,8 +378,98 @@ TEST_F(ClangIpcServer, TicketNumberIsForwarded)
clangServer.completeCode(completeCodeMessage);
}
TEST_F(ClangIpcServer, TranslationUnitIsDirtyAfterCreation)
TEST_F(ClangIpcServer, TranslationUnitAfterCreationNeedsNoReparseAndHasNewDiagnostics)
{
ASSERT_THAT(clangServer, HasDirtyTranslationUnit(functionTestFilePath, projectPartId, 0));
ASSERT_THAT(clangServer, HasDirtyTranslationUnit(functionTestFilePath, projectPartId, 0U, false, true));
}
TEST_F(ClangIpcServer, SetCurrentAndVisibleEditor)
{
auto functionTranslationUnit = translationUnits.translationUnit(functionTestFilePath, projectPartId);
auto variableTranslationUnit = translationUnits.translationUnit(variableTestFilePath, projectPartId);
updateVisibilty(functionTestFilePath, variableTestFilePath);
ASSERT_TRUE(functionTranslationUnit.isUsedByCurrentEditor());
ASSERT_TRUE(functionTranslationUnit.isVisibleInEditor());
ASSERT_TRUE(variableTranslationUnit.isVisibleInEditor());
}
TEST_F(ClangIpcServer, IsNotCurrentCurrentAndVisibleEditorAnymore)
{
auto functionTranslationUnit = translationUnits.translationUnit(functionTestFilePath, projectPartId);
auto variableTranslationUnit = translationUnits.translationUnit(variableTestFilePath, projectPartId);
updateVisibilty(functionTestFilePath, variableTestFilePath);
updateVisibilty(variableTestFilePath, Utf8String());
ASSERT_FALSE(functionTranslationUnit.isUsedByCurrentEditor());
ASSERT_FALSE(functionTranslationUnit.isVisibleInEditor());
ASSERT_TRUE(variableTranslationUnit.isUsedByCurrentEditor());
ASSERT_TRUE(variableTranslationUnit.isVisibleInEditor());
}
void ClangIpcServer::SetUp()
{
clangServer.addClient(&mockIpcClient);
registerProjectPart();
registerFiles();
}
void ClangIpcServer::registerFiles()
{
RegisterTranslationUnitForEditorMessage message({FileContainer(functionTestFilePath, projectPartId, unsavedContent(unsavedTestFilePath), true),
FileContainer(variableTestFilePath, projectPartId)});
clangServer.registerTranslationUnitsForEditor(message);
}
void ClangIpcServer::registerProjectPart()
{
RegisterProjectPartsForEditorMessage message({ProjectPartContainer(projectPartId)});
clangServer.registerProjectPartsForEditor(message);
}
void ClangIpcServer::changeProjectPartArguments()
{
RegisterProjectPartsForEditorMessage message({ProjectPartContainer(projectPartId, {Utf8StringLiteral("-DArgumentDefinition")})});
clangServer.registerProjectPartsForEditor(message);
}
void ClangIpcServer::changeProjectPartArgumentsToWrongValues()
{
RegisterProjectPartsForEditorMessage message({ProjectPartContainer(projectPartId, {Utf8StringLiteral("-blah")})});
clangServer.registerProjectPartsForEditor(message);
}
void ClangIpcServer::updateVisibilty(const Utf8String &currentEditor, const Utf8String &additionalVisibleEditor)
{
UpdateVisibleTranslationUnitsMessage message(currentEditor,
{currentEditor, additionalVisibleEditor});
clangServer.updateVisibleTranslationUnits(message);
}
const Utf8String ClangIpcServer::unsavedContent(const QString &unsavedFilePath)
{
QFile unsavedFileContentFile(unsavedFilePath);
bool isOpen = unsavedFileContentFile.open(QIODevice::ReadOnly | QIODevice::Text);
if (!isOpen)
ADD_FAILURE() << "File with the unsaved content cannot be opened!";
return Utf8String::fromByteArray(unsavedFileContentFile.readAll());
}
TEST_F(ClangIpcServer, TranslationUnitAfterUpdateNeedsReparseAndHasNewDiagnostics)
{
const auto fileContainer = FileContainer(functionTestFilePath, projectPartId,unsavedContent(unsavedTestFilePath), true, 1);
clangServer.updateTranslationUnitsForEditor({{fileContainer}});
ASSERT_THAT(clangServer, HasDirtyTranslationUnit(functionTestFilePath, projectPartId, 1U, true, true));
}
}

View File

@@ -53,6 +53,7 @@
#include <translationunitdoesnotexistmessage.h>
#include <unregisterunsavedfilesforeditormessage.h>
#include <updatetranslationunitsforeditormessage.h>
#include <updatevisibletranslationunitsmessage.h>
#include <writemessageblock.h>
#include <QBuffer>
@@ -232,6 +233,19 @@ TEST_F(ClientServerInProcess, SendUnregisterProjectPartsForEditorMessage)
scheduleServerMessages();
}
TEST_F(ClientServerInProcess, UpdateVisibleTranslationUnitsMessage)
{
ClangBackEnd::UpdateVisibleTranslationUnitsMessage message(Utf8StringLiteral(TESTDATA_DIR"/fileone.cpp"),
{Utf8StringLiteral(TESTDATA_DIR"/fileone.cpp"),
Utf8StringLiteral(TESTDATA_DIR"/filetwo.cpp")});
EXPECT_CALL(mockIpcServer, updateVisibleTranslationUnits(message))
.Times(1);
serverProxy.updateVisibleTranslationUnits(message);
scheduleServerMessages();
}
TEST_F(ClientServerInProcess, SendTranslationUnitDoesNotExistMessage)
{
ClangBackEnd::TranslationUnitDoesNotExistMessage message(fileContainer);

View File

@@ -383,3 +383,19 @@ void f17()
{
TemplatedType<int> TemplatedTypeDeclaration;
}
void f18()
{
auto value = 1 + 2;
}
class ScopeClass
{
public:
static void ScopeOperator();
};
void f19()
{
ScopeClass::ScopeOperator();
}

View File

@@ -881,6 +881,20 @@ TEST_F(HighlightingInformations, TemplatedTypeDeclaration)
ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
}
TEST_F(HighlightingInformations, NoOperator)
{
const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(389, 24));
ASSERT_THAT(infos[2], HasType(HighlightingType::Invalid));
}
TEST_F(HighlightingInformations, ScopeOperator)
{
const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(400, 33));
ASSERT_THAT(infos[1], HasType(HighlightingType::Invalid));
}
Data *HighlightingInformations::d;
void HighlightingInformations::SetUpTestCase()

View File

@@ -60,6 +60,8 @@ public:
void(const ClangBackEnd::CompleteCodeMessage &message));
MOCK_METHOD1(requestDiagnostics,
void(const ClangBackEnd::RequestDiagnosticsMessage &message));
MOCK_METHOD1(updateVisibleTranslationUnits,
void(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message));
};
#endif // MOCKIPCSERVER_H

View File

@@ -0,0 +1,53 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://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 http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef MOCKSENDDIAGNOSTICSCALLBACK_H
#define MOCKSENDDIAGNOSTICSCALLBACK_H
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include "gtest-qt-printing.h"
class SendDiagnosticCallback
{
public:
virtual ~SendDiagnosticCallback() = default;
virtual void sendDiagnostic() = 0;
};
class MockSendDiagnosticCallback : public SendDiagnosticCallback
{
public:
MOCK_METHOD0(sendDiagnostic,
void());
};
#endif // MOCKSENDDIAGNOSTICSCALLBACK_H

View File

@@ -43,9 +43,10 @@
#include <unsavedfiles.h>
#include <utf8string.h>
#include <clang-c/Index.h>
#include "mocksenddiagnosticscallback.h"
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
@@ -54,6 +55,8 @@
using ClangBackEnd::TranslationUnit;
using ClangBackEnd::UnsavedFiles;
using ClangBackEnd::ProjectPart;
using ClangBackEnd::DiagnosticsChangedMessage;
using ClangBackEnd::DiagnosticSendState;
using testing::IsNull;
using testing::NotNull;
@@ -81,23 +84,24 @@ class TranslationUnits : public ::testing::Test
{
protected:
void SetUp() override;
void sendAllDiagnostics();
void sendAllCurrentEditorDiagnostics();
void sendAllVisibleEditorsDiagnostics();
protected:
ClangBackEnd::ProjectParts projects;
ClangBackEnd::UnsavedFiles unsavedFiles;
ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles};
MockSendDiagnosticCallback mockSendDiagnosticCallback;
const Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp");
const Utf8String headerPath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.h");
const Utf8String nonExistingFilePath = Utf8StringLiteral("foo.cpp");
const Utf8String projectPartId = Utf8StringLiteral("projectPartId");
const Utf8String nonExistingProjectPartId = Utf8StringLiteral("nonExistingProjectPartId");
const ClangBackEnd::FileContainer fileContainer{filePath, projectPartId};
const ClangBackEnd::FileContainer headerContainer{headerPath, projectPartId};
};
void TranslationUnits::SetUp()
{
projects.createOrUpdate({ClangBackEnd::ProjectPartContainer(projectPartId)});
}
TEST_F(TranslationUnits, ThrowForGettingWithWrongFilePath)
{
ASSERT_THROW(translationUnits.translationUnit(nonExistingFilePath, projectPartId),
@@ -279,4 +283,193 @@ TEST_F(TranslationUnits, HasNotTranslationUnit)
ASSERT_FALSE(translationUnits.hasTranslationUnit(filePath));
}
TEST_F(TranslationUnits, isUsedByCurrentEditor)
{
translationUnits.create({fileContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnits.setCurrentEditor(filePath);
ASSERT_TRUE(translationUnit.isUsedByCurrentEditor());
}
TEST_F(TranslationUnits, IsNotCurrentEditor)
{
translationUnits.create({fileContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnits.setCurrentEditor(headerPath);
ASSERT_FALSE(translationUnit.isUsedByCurrentEditor());
}
TEST_F(TranslationUnits, IsNotCurrentEditorAfterBeingCurrent)
{
translationUnits.create({fileContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnits.setCurrentEditor(filePath);
translationUnits.setCurrentEditor(headerPath);
ASSERT_FALSE(translationUnit.isUsedByCurrentEditor());
}
TEST_F(TranslationUnits, IsVisibleEditor)
{
translationUnits.create({fileContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnits.setVisibleEditors({filePath});
ASSERT_TRUE(translationUnit.isVisibleInEditor());
}
TEST_F(TranslationUnits, IsNotVisibleEditor)
{
translationUnits.create({fileContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnits.setVisibleEditors({headerPath});
ASSERT_FALSE(translationUnit.isVisibleInEditor());
}
TEST_F(TranslationUnits, IsNotVisibleEditorAfterBeingVisible)
{
translationUnits.create({fileContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnits.setVisibleEditors({filePath});
translationUnits.setVisibleEditors({headerPath});
ASSERT_FALSE(translationUnit.isVisibleInEditor());
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsIfThereIsNothingToSend)
{
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
sendAllDiagnostics();
}
TEST_F(TranslationUnits, SendDiagnosticsAfterTranslationUnitCreation)
{
translationUnits.create({fileContainer, headerContainer});
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(2);
sendAllDiagnostics();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsAfterGettingDiagnostics)
{
translationUnits.create({fileContainer, headerContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnit.diagnostics();
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1);
sendAllDiagnostics();
}
TEST_F(TranslationUnits, SendDiagnosticsForCurrentEditor)
{
translationUnits.create({fileContainer, headerContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnit.setIsUsedByCurrentEditor(true);
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1);
sendAllCurrentEditorDiagnostics();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsForCurrentEditorIfThereIsNoCurrentEditor)
{
translationUnits.create({fileContainer, headerContainer});
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
sendAllCurrentEditorDiagnostics();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsForCurrentEditorAfterGettingDiagnostics)
{
translationUnits.create({fileContainer, headerContainer});
auto translationUnit = translationUnits.translationUnit(fileContainer);
translationUnit.setIsUsedByCurrentEditor(true);
translationUnit.diagnostics();
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
sendAllCurrentEditorDiagnostics();
}
TEST_F(TranslationUnits, DoNotSendDiagnosticsForVisibleEditorIfThereAreNoVisibleEditors)
{
translationUnits.create({fileContainer, headerContainer});
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0);
translationUnits.sendChangedDiagnosticsForVisibleEditors();
}
TEST_F(TranslationUnits, SendDiagnosticsForVisibleEditors)
{
translationUnits.create({fileContainer, headerContainer});
auto fileTranslationUnit = translationUnits.translationUnit(fileContainer);
fileTranslationUnit.setIsVisibleInEditor(true);
auto headerTranslationUnit = translationUnits.translationUnit(headerContainer);
headerTranslationUnit.setIsVisibleInEditor(true);
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(2);
sendAllVisibleEditorsDiagnostics();
}
TEST_F(TranslationUnits, SendOnlyOneDiagnosticsForVisibleEditor)
{
translationUnits.create({fileContainer, headerContainer});
auto fileTranslationUnit = translationUnits.translationUnit(fileContainer);
fileTranslationUnit.setIsVisibleInEditor(true);
auto headerTranslationUnit = translationUnits.translationUnit(headerContainer);
headerTranslationUnit.setIsVisibleInEditor(true);
headerTranslationUnit.diagnostics();
EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1);
sendAllVisibleEditorsDiagnostics();
}
void TranslationUnits::SetUp()
{
projects.createOrUpdate({ClangBackEnd::ProjectPartContainer(projectPartId)});
auto callback = [&] (const DiagnosticsChangedMessage &) { mockSendDiagnosticCallback.sendDiagnostic(); };
translationUnits.setSendChangeDiagnosticsCallback(callback);
}
void TranslationUnits::sendAllDiagnostics()
{
auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics;
while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics)
diagnosticSendState = translationUnits.sendChangedDiagnostics();
}
void TranslationUnits::sendAllCurrentEditorDiagnostics()
{
auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics;
while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics)
diagnosticSendState = translationUnits.sendChangedDiagnosticsForCurrentEditor();
}
void TranslationUnits::sendAllVisibleEditorsDiagnostics()
{
auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics;
while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics)
diagnosticSendState = translationUnits.sendChangedDiagnosticsForVisibleEditors();
}
}

View File

@@ -194,6 +194,38 @@ TEST_F(TranslationUnit, DependedFilePaths)
Contains(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"))));
}
TEST_F(TranslationUnit, NeedsNoReparseAfterCreation)
{
translationUnit.cxTranslationUnit();
ASSERT_FALSE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, HasNewDiagnosticsAfterCreation)
{
translationUnit.cxTranslationUnit();
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, NeedsReparseAfterChangeOfMainFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.isNeedingReparse());
}
TEST_F(TranslationUnit, HasNewDiagnosticsAfterChangeOfMainFile)
{
translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.hasNewDiagnostics());
}
TEST_F(TranslationUnit, NoNeedForReparsingForIndependendFile)
{
translationUnit.cxTranslationUnit();
@@ -234,6 +266,7 @@ TEST_F(TranslationUnit, NeedsNoReparsingAfterReparsing)
TEST_F(TranslationUnit, HasNoNewDiagnosticsForIndependendFile)
{
translationUnit.cxTranslationUnit();
translationUnit.diagnostics(); // Reset hasNewDiagnostics
translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/otherfiles.h"));

View File

@@ -63,6 +63,7 @@ HEADERS += \
mockipclient.h \
mockipcserver.h \
spydummy.h \
matcher-diagnosticcontainer.h
matcher-diagnosticcontainer.h \
mocksenddiagnosticscallback.h
OTHER_FILES += $$files(data/*)