forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.5'
Conflicts: scripts/deployqtHelper_mac.sh Change-Id: Ia0d5fef8c28e0bfb3b0c703ad3652e2d70d9e7d1
This commit is contained in:
2
dist/changes-3.5.0.md
vendored
2
dist/changes-3.5.0.md
vendored
@@ -127,7 +127,7 @@ FakeVim
|
||||
|
||||
Todo
|
||||
|
||||
* Added option to excluding file patterns from parsing
|
||||
* Added option to exclude file patterns from parsing
|
||||
|
||||
Beautifier
|
||||
|
||||
|
@@ -83,7 +83,7 @@
|
||||
#include <QMutableVectorIterator>
|
||||
#include <QQuickView>
|
||||
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
|
||||
namespace {
|
||||
|
@@ -63,7 +63,7 @@
|
||||
|
||||
#include "dummycontextobject.h"
|
||||
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
|
@@ -37,7 +37,7 @@
|
||||
#include "qt5rendernodeinstanceserver.h"
|
||||
#include "qt5testnodeinstanceserver.h"
|
||||
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
#include <unistd.h>
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#include <QQuickItem>
|
||||
#include <QQuickView>
|
||||
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
#include <addimportcontainer.h>
|
||||
#include <createscenecommand.h>
|
||||
#include <reparentinstancescommand.h>
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "nodeinstanceserver.h"
|
||||
#include "designersupport.h"
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QQuickItem;
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include "removesharedmemorycommand.h"
|
||||
#include <QQuickView>
|
||||
#include <QQuickItem>
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
|
@@ -63,7 +63,7 @@
|
||||
|
||||
#include "dummycontextobject.h"
|
||||
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
|
@@ -65,7 +65,7 @@
|
||||
|
||||
#include "dummycontextobject.h"
|
||||
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include "objectnodeinstance.h"
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
@@ -0,0 +1,5 @@
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
#include <private/qquickdesignersupport_p.h>
|
||||
#else
|
||||
#include <designersupport.h>
|
||||
#endif
|
@@ -57,7 +57,7 @@
|
||||
#include <private/qquickstateoperations_p.h>
|
||||
|
||||
|
||||
#include <designersupport.h>
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
|
39
share/qtcreator/static.pri
Normal file
39
share/qtcreator/static.pri
Normal file
@@ -0,0 +1,39 @@
|
||||
# This pri file is used to deploy files that are not compiled while building
|
||||
# Qt Creator. It handles copying of files into the build directory if using
|
||||
# a shadow build and adds the respective install target as well.
|
||||
#
|
||||
# Usage: Define variables (details below) and include this pri file afterwards.
|
||||
#
|
||||
# STATIC_BASE - base directory for the files listed in STATIC_FILES
|
||||
# STATIC_FILES - list of files to be deployed
|
||||
|
||||
include(../../qtcreator.pri)
|
||||
|
||||
# used in custom compilers which just copy files
|
||||
defineReplace(stripStaticBase) {
|
||||
return($$relative_path($$1, $$STATIC_BASE))
|
||||
}
|
||||
|
||||
# handle conditional copying; copydata will be set by qtcreator.pri
|
||||
!isEmpty(STATIC_FILES) {
|
||||
isEmpty(STATIC_BASE): \
|
||||
error("Using STATIC_FILES without having STATIC_BASE set")
|
||||
|
||||
!isEmpty(copydata) {
|
||||
copy2build.input += STATIC_FILES
|
||||
copy2build.output = $$IDE_DATA_PATH/${QMAKE_FUNC_FILE_IN_stripStaticBase}
|
||||
isEmpty(vcproj):copy2build.variable_out = PRE_TARGETDEPS
|
||||
win32:copy2build.commands = $$QMAKE_COPY \"${QMAKE_FILE_IN}\" \"${QMAKE_FILE_OUT}\"
|
||||
unix:copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
|
||||
copy2build.name = COPY ${QMAKE_FILE_IN}
|
||||
copy2build.config += no_link
|
||||
QMAKE_EXTRA_COMPILERS += copy2build
|
||||
}
|
||||
|
||||
!osx {
|
||||
static.files = $$STATIC_FILES
|
||||
static.base = $$STATIC_BASE
|
||||
static.path = $$QTC_PREFIX/share/qtcreator
|
||||
INSTALLS += static
|
||||
}
|
||||
}
|
@@ -1,5 +1,3 @@
|
||||
include(../../qtcreator.pri)
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET = phony_target
|
||||
CONFIG -= qt sdk separate_debug_info gdb_dwarf_index
|
||||
@@ -23,6 +21,9 @@ isEmpty(vcproj) {
|
||||
QMAKE_EXTRA_COMPILERS += phony_src
|
||||
}
|
||||
|
||||
STATIC_BASE = $$PWD
|
||||
|
||||
# files/folders that are conditionally "deployed" to the build directory
|
||||
DATA_DIRS = \
|
||||
welcomescreen \
|
||||
examplebrowser \
|
||||
@@ -46,28 +47,14 @@ macx: DATA_DIRS += scripts
|
||||
for(data_dir, DATA_DIRS) {
|
||||
files = $$files($$PWD/$$data_dir/*, true)
|
||||
# Info.plist.in are handled below
|
||||
for(file, files):!contains(file, ".*/Info\\.plist\\.in$"):!exists($$file/*):FILES += $$file
|
||||
for(file, files):!contains(file, ".*/Info\\.plist\\.in$"):!exists($$file/*): \
|
||||
STATIC_FILES += $$file
|
||||
}
|
||||
|
||||
# conditionally deployed data
|
||||
!isEmpty(copydata) {
|
||||
copy2build.input = FILES
|
||||
copy2build.output = $$IDE_DATA_PATH/${QMAKE_FUNC_FILE_IN_stripSrcDir}
|
||||
isEmpty(vcproj):copy2build.variable_out = PRE_TARGETDEPS
|
||||
win32:copy2build.commands = $$QMAKE_COPY \"${QMAKE_FILE_IN}\" \"${QMAKE_FILE_OUT}\"
|
||||
unix:copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
|
||||
copy2build.name = COPY ${QMAKE_FILE_IN}
|
||||
copy2build.CONFIG += no_link
|
||||
QMAKE_EXTRA_COMPILERS += copy2build
|
||||
}
|
||||
include(static.pri)
|
||||
|
||||
!macx {
|
||||
for(data_dir, DATA_DIRS) {
|
||||
eval($${data_dir}.files = $$quote($$PWD/$$data_dir))
|
||||
eval($${data_dir}.path = $$QTC_PREFIX/share/qtcreator)
|
||||
INSTALLS += $$data_dir
|
||||
}
|
||||
} else {
|
||||
# stuff that cannot be handled by static.pri
|
||||
osx {
|
||||
# do version magic for app bundles
|
||||
dumpinfo.input = qml/qmldump/Info.plist.in
|
||||
dumpinfo.output = $$IDE_DATA_PATH/qml/qmldump/Info.plist
|
||||
|
@@ -4,7 +4,7 @@ import QtQuick.Window %{QtQuickWindowVersion}
|
||||
Window {
|
||||
visible: true
|
||||
|
||||
@if %{QmlUISplit}
|
||||
@if %{IsUiFileInUse}
|
||||
MainForm {
|
||||
anchors.fill: parent
|
||||
mouseArea.onClicked: {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
@if %{QmlUISplit}
|
||||
@if %{IsUiFileInUse}
|
||||
<file>MainForm.ui.qml</file>
|
||||
@endif
|
||||
</qresource>
|
||||
|
@@ -16,7 +16,9 @@
|
||||
{ "key": "MainCppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" },
|
||||
{ "key": "QtQuickWindowVersion", "value": "%{JS: %{QtVersion}.qtQuickWindowVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "UiSupport", "value": "%{JS: '%{QtQuickVersion}' !== '2.3' }" },
|
||||
{ "key": "IsUiFileInUse", "value": "%{JS: %{UiSupport} && %{QmlUiSplit} }" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
@@ -69,12 +71,13 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "QmlUISplit",
|
||||
"name": "QmlUiSplit",
|
||||
"trDisplayName": "With ui.qml file",
|
||||
"type": "CheckBox",
|
||||
"visible": "%{UiSupport}",
|
||||
"data":
|
||||
{
|
||||
"checked": false
|
||||
"checked": true
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -115,7 +118,7 @@
|
||||
},
|
||||
{
|
||||
"source": "MainForm.ui.qml",
|
||||
"condition": "%{QmlUISplit}"
|
||||
"condition": "%{IsUiFileInUse}"
|
||||
},
|
||||
{
|
||||
"source": "qml.qrc"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import QtQuick %{QtQuickVersion}
|
||||
import QtQuick.Controls %{QtQuickControlsVersion}
|
||||
@if %{QmlUISplit}
|
||||
@if %{IsUiFileInUse}
|
||||
import QtQuick.Dialogs %{QtQuickDialogsVersion}
|
||||
@endif
|
||||
|
||||
@@ -24,7 +24,7 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
@if %{QmlUISplit}
|
||||
@if %{IsUiFileInUse}
|
||||
MainForm {
|
||||
anchors.fill: parent
|
||||
button1.onClicked: messageDialog.show(qsTr("Button 1 pressed"))
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
@if %{QmlUISplit}
|
||||
@if %{IsUiFileInUse}
|
||||
<file>MainForm.ui.qml</file>
|
||||
@endif
|
||||
</qresource>
|
||||
|
@@ -18,7 +18,9 @@
|
||||
{ "key": "QtQuickControlsVersion", "value": "%{JS: %{QtVersion}.qtQuickControlsVersion}" },
|
||||
{ "key": "QtQuickDialogsVersion", "value": "%{JS: %{QtVersion}.qtQuickDialogsVersion}" },
|
||||
{ "key": "QtQuickLayoutsVersion", "value": "%{JS: %{QtVersion}.qtQuickLayoutsVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "UiSupport", "value": "%{JS: '%{QtQuickVersion}' !== '2.3' }" },
|
||||
{ "key": "IsUiFileInUse", "value": "%{JS: %{UiSupport} && %{QmlUiSplit} }" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
@@ -77,9 +79,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "QmlUISplit",
|
||||
"name": "QmlUiSplit",
|
||||
"trDisplayName": "With ui.qml file",
|
||||
"type": "CheckBox",
|
||||
"visible": "%{UiSupport}",
|
||||
"data":
|
||||
{
|
||||
"checked": true
|
||||
@@ -132,7 +135,7 @@
|
||||
},
|
||||
{
|
||||
"source": "MainForm.ui.qml",
|
||||
"condition": "%{QmlUISplit}"
|
||||
"condition": "%{IsUiFileInUse}"
|
||||
},
|
||||
{
|
||||
"source": "qml.qrc"
|
||||
|
@@ -15,7 +15,9 @@
|
||||
{ "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'qmlproject')}" },
|
||||
{ "key": "MainQmlFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qml')}" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" },
|
||||
{ "key": "QtQuickWindowVersion", "value": "%{JS: %{QtVersion}.qtQuickWindowVersion}" }
|
||||
{ "key": "QtQuickWindowVersion", "value": "%{JS: %{QtVersion}.qtQuickWindowVersion}" },
|
||||
{ "key": "UiSupport", "value": "%{JS: '%{QtQuickVersion}' !== '2.3' }" },
|
||||
{ "key": "IsUiFileInUse", "value": "%{JS: %{UiSupport} && %{QmlUiSplit} }" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
@@ -67,9 +69,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "QmlUISplit",
|
||||
"name": "QmlUiSplit",
|
||||
"trDisplayName": "With ui.qml file",
|
||||
"type": "CheckBox",
|
||||
"visible": "%{UiSupport}",
|
||||
"data":
|
||||
{
|
||||
"checked": false
|
||||
@@ -102,7 +105,7 @@
|
||||
{
|
||||
"source": "../../qmake/qtquickapplication/MainForm.ui.qml",
|
||||
"target": "%{ProjectDirectory}/MainForm.ui.qml",
|
||||
"condition": "%{QmlUISplit}"
|
||||
"condition": "%{IsUiFileInUse}"
|
||||
},
|
||||
{
|
||||
"source": "../../git.ignore",
|
||||
|
@@ -17,7 +17,9 @@
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" },
|
||||
{ "key": "QtQuickControlsVersion", "value": "%{JS: %{QtVersion}.qtQuickControlsVersion}" },
|
||||
{ "key": "QtQuickDialogsVersion", "value": "%{JS: %{QtVersion}.qtQuickDialogsVersion}" },
|
||||
{ "key": "QtQuickLayoutsVersion", "value": "%{JS: %{QtVersion}.qtQuickLayoutsVersion}" }
|
||||
{ "key": "QtQuickLayoutsVersion", "value": "%{JS: %{QtVersion}.qtQuickLayoutsVersion}" },
|
||||
{ "key": "UiSupport", "value": "%{JS: '%{QtQuickVersion}' !== '2.3' }" },
|
||||
{ "key": "IsUiFileInUse", "value": "%{JS: %{UiSupport} && %{QmlUiSplit} }" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
@@ -75,9 +77,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "QmlUISplit",
|
||||
"name": "QmlUiSplit",
|
||||
"trDisplayName": "With ui.qml file",
|
||||
"type": "CheckBox",
|
||||
"visible": "%{UiSupport}",
|
||||
"data":
|
||||
{
|
||||
"checked": true
|
||||
@@ -110,7 +113,7 @@
|
||||
{
|
||||
"source": "../../qmake/qtquickcontrolsapplication/MainForm.ui.qml",
|
||||
"target": "%{ProjectDirectory}/MainForm.ui.qml",
|
||||
"condition": "%{QmlUISplit}"
|
||||
"condition": "%{IsUiFileInUse}"
|
||||
},
|
||||
{
|
||||
"source": "../../git.ignore",
|
||||
|
@@ -76,7 +76,7 @@ bool operator<(const RegisterProjectPartsForCodeCompletionCommand &first, const
|
||||
|
||||
QDebug operator<<(QDebug debug, const RegisterProjectPartsForCodeCompletionCommand &command)
|
||||
{
|
||||
debug.nospace() << "RegisterProjectPartsForCodeCompletion(";
|
||||
debug.nospace() << "RegisterProjectPartsForCodeCompletionCommand(";
|
||||
|
||||
for (const ProjectPartContainer &projectContainer : command.projectContainers())
|
||||
debug.nospace() << projectContainer<< ", ";
|
||||
@@ -88,7 +88,7 @@ QDebug operator<<(QDebug debug, const RegisterProjectPartsForCodeCompletionComma
|
||||
|
||||
void PrintTo(const RegisterProjectPartsForCodeCompletionCommand &command, ::std::ostream* os)
|
||||
{
|
||||
*os << "RegisterProjectPartsForCodeCompletion(";
|
||||
*os << "RegisterProjectPartsForCodeCompletionCommand(";
|
||||
|
||||
for (const ProjectPartContainer &projectContainer : command.projectContainers())
|
||||
PrintTo(projectContainer, os);
|
||||
|
@@ -42,44 +42,44 @@ namespace ClangBackEnd {
|
||||
|
||||
|
||||
UnregisterProjectPartsForCodeCompletionCommand::UnregisterProjectPartsForCodeCompletionCommand(const Utf8StringVector &filePaths)
|
||||
: filePaths_(filePaths)
|
||||
: projectPartIds_(filePaths)
|
||||
{
|
||||
}
|
||||
|
||||
const Utf8StringVector &UnregisterProjectPartsForCodeCompletionCommand::filePaths() const
|
||||
const Utf8StringVector &UnregisterProjectPartsForCodeCompletionCommand::projectPartIds() const
|
||||
{
|
||||
return filePaths_;
|
||||
return projectPartIds_;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const UnregisterProjectPartsForCodeCompletionCommand &command)
|
||||
{
|
||||
out << command.filePaths_;
|
||||
out << command.projectPartIds_;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, UnregisterProjectPartsForCodeCompletionCommand &command)
|
||||
{
|
||||
in >> command.filePaths_;
|
||||
in >> command.projectPartIds_;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
bool operator==(const UnregisterProjectPartsForCodeCompletionCommand &first, const UnregisterProjectPartsForCodeCompletionCommand &second)
|
||||
{
|
||||
return first.filePaths_ == second.filePaths_;
|
||||
return first.projectPartIds_ == second.projectPartIds_;
|
||||
}
|
||||
|
||||
bool operator<(const UnregisterProjectPartsForCodeCompletionCommand &first, const UnregisterProjectPartsForCodeCompletionCommand &second)
|
||||
{
|
||||
return compareContainer(first.filePaths_, second.filePaths_);
|
||||
return compareContainer(first.projectPartIds_, second.projectPartIds_);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const UnregisterProjectPartsForCodeCompletionCommand &command)
|
||||
{
|
||||
debug.nospace() << "UnregisterProjectPartsForCodeCompletionCommand(";
|
||||
|
||||
for (const Utf8String &fileNames_ : command.filePaths())
|
||||
for (const Utf8String &fileNames_ : command.projectPartIds())
|
||||
debug.nospace() << fileNames_ << ", ";
|
||||
|
||||
debug.nospace() << ")";
|
||||
@@ -91,7 +91,7 @@ void PrintTo(const UnregisterProjectPartsForCodeCompletionCommand &command, ::st
|
||||
{
|
||||
*os << "UnregisterProjectPartsForCodeCompletionCommand(";
|
||||
|
||||
for (const Utf8String &fileNames_ : command.filePaths())
|
||||
for (const Utf8String &fileNames_ : command.projectPartIds())
|
||||
*os << fileNames_.constData() << ", ";
|
||||
|
||||
*os << ")";
|
||||
|
@@ -49,12 +49,12 @@ class CMBIPC_EXPORT UnregisterProjectPartsForCodeCompletionCommand
|
||||
|
||||
public:
|
||||
UnregisterProjectPartsForCodeCompletionCommand() = default;
|
||||
UnregisterProjectPartsForCodeCompletionCommand(const Utf8StringVector &filePaths);
|
||||
UnregisterProjectPartsForCodeCompletionCommand(const Utf8StringVector &projectPartIds);
|
||||
|
||||
const Utf8StringVector &filePaths() const;
|
||||
const Utf8StringVector &projectPartIds() const;
|
||||
|
||||
private:
|
||||
Utf8StringVector filePaths_;
|
||||
Utf8StringVector projectPartIds_;
|
||||
};
|
||||
|
||||
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const UnregisterProjectPartsForCodeCompletionCommand &command);
|
||||
|
@@ -38,15 +38,11 @@
|
||||
namespace ClangBackEnd {
|
||||
|
||||
CodeCompletion::CodeCompletion(const Utf8String &text,
|
||||
const Utf8String &hint,
|
||||
const Utf8String &snippet,
|
||||
quint32 priority,
|
||||
Kind completionKind,
|
||||
Availability availability,
|
||||
bool hasParameters)
|
||||
: text_(text),
|
||||
hint_(hint),
|
||||
snippet_(snippet),
|
||||
priority_(priority),
|
||||
completionKind_(completionKind),
|
||||
availability_(availability),
|
||||
@@ -63,15 +59,6 @@ const Utf8String &CodeCompletion::text() const
|
||||
{
|
||||
return text_;
|
||||
}
|
||||
const Utf8String &CodeCompletion::hint() const
|
||||
{
|
||||
return hint_;
|
||||
}
|
||||
|
||||
const Utf8String &CodeCompletion::snippet() const
|
||||
{
|
||||
return snippet_;
|
||||
}
|
||||
|
||||
void CodeCompletion::setCompletionKind(CodeCompletion::Kind completionKind)
|
||||
{
|
||||
@@ -136,8 +123,6 @@ quint32 &CodeCompletion::availabilityAsInt()
|
||||
QDataStream &operator<<(QDataStream &out, const CodeCompletion &command)
|
||||
{
|
||||
out << command.text_;
|
||||
out << command.hint_;
|
||||
out << command.snippet_;
|
||||
out << command.chunks_;
|
||||
out << command.priority_;
|
||||
out << command.completionKind_;
|
||||
@@ -150,8 +135,6 @@ QDataStream &operator<<(QDataStream &out, const CodeCompletion &command)
|
||||
QDataStream &operator>>(QDataStream &in, CodeCompletion &command)
|
||||
{
|
||||
in >> command.text_;
|
||||
in >> command.hint_;
|
||||
in >> command.snippet_;
|
||||
in >> command.chunks_;
|
||||
in >> command.priority_;
|
||||
in >> command.completionKindAsInt();
|
||||
@@ -213,8 +196,6 @@ QDebug operator<<(QDebug debug, const CodeCompletion &command)
|
||||
debug.nospace() << "CodeCompletion(";
|
||||
|
||||
debug.nospace() << command.text_ << ", ";
|
||||
debug.nospace() << command.hint_ << ", ";
|
||||
debug.nospace() << command.snippet_ << ", ";
|
||||
debug.nospace() << command.priority_ << ", ";
|
||||
debug.nospace() << completionKindToString(command.completionKind_) << ", ";
|
||||
debug.nospace() << availabilityToString(command.availability_) << ", ";
|
||||
@@ -230,8 +211,6 @@ void PrintTo(const CodeCompletion &command, ::std::ostream* os)
|
||||
*os << "CodeCompletion(";
|
||||
|
||||
*os << command.text_.constData() << ", ";
|
||||
*os << command.hint_.constData() << ", ";
|
||||
*os << command.snippet_.constData() << ", ";
|
||||
*os << command.priority_ << ", ";
|
||||
*os << completionKindToString(command.completionKind_) << ", ";
|
||||
*os << availabilityToString(command.availability_) << ", ";
|
||||
|
@@ -80,8 +80,6 @@ public:
|
||||
public:
|
||||
CodeCompletion() = default;
|
||||
CodeCompletion(const Utf8String &text,
|
||||
const Utf8String &hint = Utf8String(),
|
||||
const Utf8String &snippet = Utf8String(),
|
||||
quint32 priority = 0,
|
||||
Kind completionKind = Other,
|
||||
Availability availability = Available,
|
||||
@@ -90,9 +88,6 @@ public:
|
||||
void setText(const Utf8String &text);
|
||||
const Utf8String &text() const;
|
||||
|
||||
const Utf8String &hint() const;
|
||||
const Utf8String &snippet() const;
|
||||
|
||||
void setCompletionKind(Kind completionKind);
|
||||
Kind completionKind() const;
|
||||
|
||||
@@ -114,8 +109,6 @@ private:
|
||||
|
||||
private:
|
||||
Utf8String text_;
|
||||
Utf8String hint_;
|
||||
Utf8String snippet_;
|
||||
QVector<CodeCompletionChunk> chunks_;
|
||||
quint32 priority_ = 0;
|
||||
Kind completionKind_ = Other;
|
||||
|
@@ -86,53 +86,83 @@ QList<FormattedText> AnsiEscapeCodeHandler::parseText(const FormattedText &input
|
||||
DefaultBackgroundColor = 49
|
||||
};
|
||||
|
||||
QList<FormattedText> outputData;
|
||||
|
||||
QTextCharFormat charFormat = m_previousFormatClosed ? input.format : m_previousFormat;
|
||||
|
||||
const QString escape = QLatin1String("\x1b[");
|
||||
const int escapePos = input.text.indexOf(escape);
|
||||
if (escapePos < 0) {
|
||||
outputData << FormattedText(input.text, charFormat);
|
||||
return outputData;
|
||||
} else if (escapePos != 0) {
|
||||
outputData << FormattedText(input.text.left(escapePos), charFormat);
|
||||
}
|
||||
|
||||
const QChar semicolon = QLatin1Char(';');
|
||||
const QChar colorTerminator = QLatin1Char('m');
|
||||
const QChar eraseToEol = QLatin1Char('K');
|
||||
// strippedText always starts with "\e["
|
||||
QString strippedText = input.text.mid(escapePos);
|
||||
|
||||
QList<FormattedText> outputData;
|
||||
QTextCharFormat charFormat = m_previousFormatClosed ? input.format : m_previousFormat;
|
||||
QString strippedText;
|
||||
if (m_pendingText.isEmpty()) {
|
||||
strippedText = input.text;
|
||||
} else {
|
||||
strippedText = m_pendingText.append(input.text);
|
||||
m_pendingText.clear();
|
||||
}
|
||||
|
||||
while (!strippedText.isEmpty()) {
|
||||
while (strippedText.startsWith(escape)) {
|
||||
strippedText.remove(0, 2);
|
||||
QTC_ASSERT(m_pendingText.isEmpty(), break);
|
||||
const int escapePos = strippedText.indexOf(escape[0]);
|
||||
if (escapePos < 0) {
|
||||
outputData << FormattedText(strippedText, charFormat);
|
||||
break;
|
||||
} else if (escapePos != 0) {
|
||||
outputData << FormattedText(strippedText.left(escapePos), charFormat);
|
||||
strippedText.remove(0, escapePos);
|
||||
}
|
||||
QTC_ASSERT(strippedText[0] == escape[0], break);
|
||||
|
||||
while (!strippedText.isEmpty() && escape[0] == strippedText[0]) {
|
||||
if (escape.startsWith(strippedText)) {
|
||||
// control secquence is not complete
|
||||
m_pendingText += strippedText;
|
||||
strippedText.clear();
|
||||
break;
|
||||
}
|
||||
if (!strippedText.startsWith(escape)) {
|
||||
// not a control sequence
|
||||
m_pendingText.clear();
|
||||
outputData << FormattedText(strippedText.left(1), charFormat);
|
||||
strippedText.remove(0, 1);
|
||||
continue;
|
||||
}
|
||||
m_pendingText += strippedText.mid(0, escape.length());
|
||||
strippedText.remove(0, escape.length());
|
||||
|
||||
// \e[K is not supported. Just strip it.
|
||||
if (strippedText.startsWith(eraseToEol)) {
|
||||
m_pendingText.clear();
|
||||
strippedText.remove(0, 1);
|
||||
continue;
|
||||
}
|
||||
// get the number
|
||||
QString strNumber;
|
||||
QStringList numbers;
|
||||
while (strippedText.at(0).isDigit() || strippedText.at(0) == semicolon) {
|
||||
while (!strippedText.isEmpty()) {
|
||||
if (strippedText.at(0).isDigit()) {
|
||||
strNumber += strippedText.at(0);
|
||||
} else {
|
||||
numbers << strNumber;
|
||||
if (!strNumber.isEmpty())
|
||||
numbers << strNumber;
|
||||
if (strNumber.isEmpty() || strippedText.at(0) != semicolon)
|
||||
break;
|
||||
strNumber.clear();
|
||||
}
|
||||
m_pendingText += strippedText.mid(0, 1);
|
||||
strippedText.remove(0, 1);
|
||||
}
|
||||
if (!strNumber.isEmpty())
|
||||
numbers << strNumber;
|
||||
if (strippedText.isEmpty())
|
||||
break;
|
||||
|
||||
// remove terminating char
|
||||
if (!strippedText.startsWith(colorTerminator)) {
|
||||
m_pendingText.clear();
|
||||
strippedText.remove(0, 1);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
// got consistent control sequence, ok to clear pending text
|
||||
m_pendingText.clear();
|
||||
strippedText.remove(0, 1);
|
||||
|
||||
if (numbers.isEmpty()) {
|
||||
@@ -224,17 +254,6 @@ QList<FormattedText> AnsiEscapeCodeHandler::parseText(const FormattedText &input
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strippedText.isEmpty())
|
||||
break;
|
||||
int index = strippedText.indexOf(escape);
|
||||
if (index > 0) {
|
||||
outputData << FormattedText(strippedText.left(index), charFormat);
|
||||
strippedText.remove(0, index);
|
||||
} else if (index == -1) {
|
||||
outputData << FormattedText(strippedText, charFormat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return outputData;
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@ private:
|
||||
|
||||
bool m_previousFormatClosed;
|
||||
QTextCharFormat m_previousFormat;
|
||||
QString m_pendingText;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -380,7 +380,7 @@ QList<EnvironmentItem> Environment::diff(const Environment &other) const
|
||||
if (thisIt == constEnd()) {
|
||||
result.append(EnvironmentItem(otherIt.key(), otherIt.value()));
|
||||
++otherIt;
|
||||
} else if (otherIt == constEnd()) {
|
||||
} else if (otherIt == other.constEnd()) {
|
||||
EnvironmentItem item(thisIt.key(), QString());
|
||||
item.unset = true;
|
||||
result.append(item);
|
||||
@@ -394,7 +394,8 @@ QList<EnvironmentItem> Environment::diff(const Environment &other) const
|
||||
result.append(EnvironmentItem(otherIt.key(), otherIt.value()));
|
||||
++otherIt;
|
||||
} else {
|
||||
result.append(EnvironmentItem(otherIt.key(), otherIt.value()));
|
||||
if (thisIt.value() != otherIt.value())
|
||||
result.append(EnvironmentItem(otherIt.key(), otherIt.value()));
|
||||
++otherIt;
|
||||
++thisIt;
|
||||
}
|
||||
|
@@ -274,7 +274,7 @@ QString MacroExpander::expand(const QString &stringWithVariables) const
|
||||
if (d->m_lockDepth == 0)
|
||||
d->m_aborted = false;
|
||||
|
||||
if (d->m_lockDepth > 3) { // Limit recursion.
|
||||
if (d->m_lockDepth > 10) { // Limit recursion.
|
||||
d->m_aborted = true;
|
||||
return QString();
|
||||
}
|
||||
|
@@ -770,15 +770,6 @@ QModelIndex TreeItem::index() const
|
||||
return m_model->indexForItem(this);
|
||||
}
|
||||
|
||||
void TreeItem::setModel(TreeModel *model)
|
||||
{
|
||||
if (m_model == model)
|
||||
return;
|
||||
m_model = model;
|
||||
foreach (TreeItem *item, m_children)
|
||||
item->setModel(model);
|
||||
}
|
||||
|
||||
void TreeItem::walkTree(TreeItemVisitor *visitor)
|
||||
{
|
||||
if (visitor->preVisit(this)) {
|
||||
@@ -972,6 +963,9 @@ int TreeModel::topLevelItemCount() const
|
||||
|
||||
void TreeModel::setRootItem(TreeItem *item)
|
||||
{
|
||||
QTC_ASSERT(item, return);
|
||||
QTC_ASSERT(item->m_model == 0, return);
|
||||
QTC_ASSERT(item->m_parent == 0, return);
|
||||
QTC_CHECK(m_root);
|
||||
if (m_root) {
|
||||
QTC_CHECK(m_root->m_parent == 0);
|
||||
@@ -980,7 +974,7 @@ void TreeModel::setRootItem(TreeItem *item)
|
||||
delete m_root;
|
||||
}
|
||||
m_root = item;
|
||||
item->setModel(this);
|
||||
item->propagateModel(this);
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
|
@@ -101,7 +101,6 @@ public:
|
||||
QModelIndex index() const;
|
||||
|
||||
TreeModel *model() const { return m_model; }
|
||||
void setModel(TreeModel *model);
|
||||
|
||||
void walkTree(TreeItemVisitor *visitor);
|
||||
void walkTree(std::function<void(TreeItem *)> f);
|
||||
@@ -117,7 +116,6 @@ private:
|
||||
TreeModel *m_model; // Not owned.
|
||||
QVector<TreeItem *> m_children; // Owned.
|
||||
QStringList *m_displays;
|
||||
mutable bool m_populated;
|
||||
Qt::ItemFlags m_flags;
|
||||
|
||||
friend class TreeModel;
|
||||
|
@@ -1302,7 +1302,7 @@ void AndroidConfigurations::updateAutomaticKitList()
|
||||
}
|
||||
|
||||
QHash<Abi, QList<QtSupport::BaseQtVersion *> > qtVersionsForArch;
|
||||
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::versions()) {
|
||||
foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::unsortedVersions()) {
|
||||
if (qtVersion->type() != QLatin1String(Constants::ANDROIDQT))
|
||||
continue;
|
||||
QList<Abi> qtAbis = qtVersion->qtAbis();
|
||||
|
@@ -30,10 +30,13 @@
|
||||
|
||||
#include "clangassistproposalitem.h"
|
||||
|
||||
#include "completionchunkstotextconverter.h"
|
||||
|
||||
#include <cplusplus/MatchingText.h>
|
||||
#include <cplusplus/Token.h>
|
||||
|
||||
#include <texteditor/completionsettings.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
|
||||
@@ -64,6 +67,21 @@ bool ClangAssistProposalItem::prematurelyApplies(const QChar &typedChar) const
|
||||
return applies;
|
||||
}
|
||||
|
||||
static bool hasOnlyBlanksBeforeCursorInLine(QTextCursor textCursor)
|
||||
{
|
||||
textCursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
|
||||
|
||||
const auto textBeforeCursor = textCursor.selectedText();
|
||||
|
||||
const auto nonSpace = std::find_if(textBeforeCursor.cbegin(),
|
||||
textBeforeCursor.cend(),
|
||||
[] (const QChar &signBeforeCursor) {
|
||||
return !signBeforeCursor.isSpace();
|
||||
});
|
||||
|
||||
return nonSpace == textBeforeCursor.cend();
|
||||
}
|
||||
|
||||
void ClangAssistProposalItem::applyContextualContent(TextEditor::TextEditorWidget *editorWidget,
|
||||
int basePosition) const
|
||||
{
|
||||
@@ -86,6 +104,17 @@ void ClangAssistProposalItem::applyContextualContent(TextEditor::TextEditorWidge
|
||||
if (m_typedChar == QLatin1Char('/')) // Eat the slash
|
||||
m_typedChar = QChar();
|
||||
}
|
||||
} else if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind) {
|
||||
CompletionChunksToTextConverter converter;
|
||||
converter.setAddPlaceHolderPositions(true);
|
||||
converter.setAddSpaces(true);
|
||||
converter.setAddExtraVerticalSpaceBetweenBraces(true);
|
||||
|
||||
converter.parseChunks(ccr.chunks());
|
||||
|
||||
toInsert = converter.text();
|
||||
if (converter.hasPlaceholderPositions())
|
||||
cursorOffset = converter.placeholderPositions().at(0) - converter.text().size();
|
||||
} else if (!ccr.text().isEmpty()) {
|
||||
const TextEditor::CompletionSettings &completionSettings =
|
||||
TextEditor::TextEditorSettings::instance()->completionSettings();
|
||||
@@ -165,7 +194,7 @@ void ClangAssistProposalItem::applyContextualContent(TextEditor::TextEditorWidge
|
||||
const int endsPosition = editorWidget->position(TextEditor::EndOfLinePosition);
|
||||
const QString existingText = editorWidget->textAt(editorWidget->position(), endsPosition - editorWidget->position());
|
||||
int existLength = 0;
|
||||
if (!existingText.isEmpty()) {
|
||||
if (!existingText.isEmpty() && ccr.completionKind() != CodeCompletion::KeywordCompletionKind) {
|
||||
// Calculate the exist length in front of the extra chars
|
||||
existLength = toInsert.length() - (editorWidget->position() - basePosition);
|
||||
while (!existingText.startsWith(toInsert.right(existLength))) {
|
||||
@@ -189,6 +218,18 @@ void ClangAssistProposalItem::applyContextualContent(TextEditor::TextEditorWidge
|
||||
editorWidget->replace(length, toInsert);
|
||||
if (cursorOffset)
|
||||
editorWidget->setCursorPosition(editorWidget->position() + cursorOffset);
|
||||
|
||||
// indent the statement
|
||||
if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind) {
|
||||
auto selectionCursor = editorWidget->textCursor();
|
||||
selectionCursor.setPosition(basePosition);
|
||||
selectionCursor.setPosition(basePosition + toInsert.size(), QTextCursor::KeepAnchor);
|
||||
|
||||
auto basePositionCursor = editorWidget->textCursor();
|
||||
basePositionCursor.setPosition(basePosition);
|
||||
if (hasOnlyBlanksBeforeCursorInLine(basePositionCursor))
|
||||
editorWidget->textDocument()->autoIndent(selectionCursor);
|
||||
}
|
||||
}
|
||||
|
||||
void ClangAssistProposalItem::keepCompletionOperator(unsigned compOp)
|
||||
|
@@ -39,15 +39,6 @@
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
namespace {
|
||||
|
||||
const ClangAssistProposalItem &toClangAssistProposalItem(TextEditor::AssistProposalItem *assistProposalItem)
|
||||
{
|
||||
return *static_cast<ClangAssistProposalItem*>(assistProposalItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool ClangAssistProposalModel::replaceDotForArrow(TextEditor::IAssistProposalModel *model)
|
||||
{
|
||||
auto clangAssistProposalModel = static_cast<ClangAssistProposalModel*>(model);
|
||||
|
@@ -157,7 +157,7 @@ void IpcReceiver::translationUnitDoesNotExist(const TranslationUnitDoesNotExistC
|
||||
|
||||
void IpcReceiver::projectPartsDoNotExist(const ProjectPartsDoNotExistCommand &command)
|
||||
{
|
||||
QTC_CHECK(!"Got ProjectDoesNotExistCommand");
|
||||
QTC_CHECK(!"Got ProjectPartsDoNotExistCommand");
|
||||
qCDebug(log) << "<<< ERROR:" << command;
|
||||
}
|
||||
|
||||
@@ -223,10 +223,8 @@ IpcCommunicator::IpcCommunicator()
|
||||
|
||||
connect(Core::EditorManager::instance(), &Core::EditorManager::editorAboutToClose,
|
||||
this, &IpcCommunicator::onEditorAboutToClose);
|
||||
|
||||
connect(Core::ICore::instance(), &Core::ICore::coreAboutToClose, [this]() {
|
||||
m_sendMode = IgnoreSendRequests;
|
||||
});
|
||||
connect(Core::ICore::instance(), &Core::ICore::coreAboutToClose,
|
||||
this, &IpcCommunicator::onCoreAboutToClose);
|
||||
|
||||
initializeBackend();
|
||||
}
|
||||
@@ -376,6 +374,11 @@ void IpcCommunicator::onEditorAboutToClose(Core::IEditor *editor)
|
||||
m_ipcReceiver.deleteProcessorsOfEditorWidget(textEditor->editorWidget());
|
||||
}
|
||||
|
||||
void IpcCommunicator::onCoreAboutToClose()
|
||||
{
|
||||
m_sendMode = IgnoreSendRequests;
|
||||
}
|
||||
|
||||
void IpcCommunicator::initializeBackendWithCurrentData()
|
||||
{
|
||||
registerEmptyProjectForProjectLessFiles();
|
||||
|
@@ -143,6 +143,7 @@ private:
|
||||
|
||||
void onBackendRestarted();
|
||||
void onEditorAboutToClose(Core::IEditor *editor);
|
||||
void onCoreAboutToClose();
|
||||
|
||||
IpcReceiver m_ipcReceiver;
|
||||
ClangBackEnd::ConnectionClient m_connection;
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "clangutils.h"
|
||||
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
#include <cpptools/cppworkingcopy.h>
|
||||
|
||||
#include <texteditor/texteditor.h>
|
||||
@@ -58,7 +59,9 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface(
|
||||
, m_languageFeatures(features)
|
||||
, m_textEditorWidget(textEditorWidget)
|
||||
{
|
||||
m_unsavedFiles = Utils::createUnsavedFiles(CppTools::CppModelManager::instance()->workingCopy());
|
||||
m_unsavedFiles = Utils::createUnsavedFiles(
|
||||
CppTools::CppModelManager::instance()->workingCopy(),
|
||||
CppTools::modifiedFiles());
|
||||
}
|
||||
|
||||
bool ClangCompletionAssistInterface::objcEnabled() const
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "clangcompletioncontextanalyzer.h"
|
||||
#include "clangfunctionhintmodel.h"
|
||||
#include "clangutils.h"
|
||||
#include "completionchunkstotextconverter.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -86,22 +87,25 @@ QList<AssistProposalItem *> toAssistProposalItems(const CodeCompletions &complet
|
||||
if (slotCompletion && ccr.completionKind() != CodeCompletion::SlotCompletionKind)
|
||||
continue;
|
||||
|
||||
const QString txt(ccr.text().toString());
|
||||
ClangAssistProposalItem *item = items.value(txt, 0);
|
||||
QString name;
|
||||
if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind)
|
||||
name = CompletionChunksToTextConverter::convertToName(ccr.chunks());
|
||||
else
|
||||
name = ccr.text().toString();
|
||||
|
||||
ClangAssistProposalItem *item = items.value(name, 0);
|
||||
if (item) {
|
||||
item->addOverload(ccr);
|
||||
} else {
|
||||
item = new ClangAssistProposalItem;
|
||||
items.insert(txt, item);
|
||||
item->setText(txt);
|
||||
item->setDetail(ccr.hint().toString());
|
||||
items.insert(name, item);
|
||||
item->setText(name);
|
||||
item->setOrder(ccr.priority());
|
||||
|
||||
const QString snippet = ccr.snippet().toString();
|
||||
if (!snippet.isEmpty())
|
||||
item->setData(snippet);
|
||||
else
|
||||
item->setData(qVariantFromValue(ccr));
|
||||
if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind)
|
||||
item->setDetail(CompletionChunksToTextConverter::convertToToolTip(ccr.chunks()));
|
||||
|
||||
item->setData(QVariant::fromValue(ccr));
|
||||
}
|
||||
|
||||
// FIXME: show the effective accessebility instead of availability
|
||||
|
@@ -88,24 +88,28 @@ ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
|
||||
{
|
||||
}
|
||||
|
||||
void ClangEditorDocumentParser::update(CppTools::WorkingCopy workingCopy)
|
||||
void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info)
|
||||
{
|
||||
QTC_ASSERT(m_marker, return);
|
||||
QMutexLocker lock(m_marker->mutex());
|
||||
QMutexLocker lock2(&m_mutex);
|
||||
|
||||
updateProjectPart();
|
||||
const QStringList options = createOptions(filePath(), projectPart(), true);
|
||||
// Determine project part
|
||||
State state_ = state();
|
||||
state_.projectPart = determineProjectPart(filePath(), configuration(), state_);
|
||||
setState(state_);
|
||||
|
||||
// Determine command line arguments
|
||||
const QStringList options = createOptions(filePath(), state_.projectPart, true);
|
||||
qCDebug(log, "Reparse options (cmd line equivalent): %s",
|
||||
commandLine(options, filePath()).toUtf8().constData());
|
||||
QTime t; t.start();
|
||||
|
||||
// Run
|
||||
QTime t; t.start();
|
||||
QMutexLocker lock(m_marker->mutex());
|
||||
m_marker->setFileName(filePath());
|
||||
m_marker->setCompilationOptions(options);
|
||||
const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(workingCopy);
|
||||
const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(info.workingCopy,
|
||||
info.modifiedFiles);
|
||||
m_marker->reparse(unsavedFiles);
|
||||
|
||||
qCDebug(log) << "Reparse took" << t.elapsed() << "ms.";
|
||||
}
|
||||
|
||||
|
@@ -46,13 +46,13 @@ class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser
|
||||
public:
|
||||
ClangEditorDocumentParser(const QString &filePath);
|
||||
|
||||
void update(CppTools::WorkingCopy workingCopy) override;
|
||||
|
||||
QList<Diagnostic> diagnostics() const;
|
||||
QList<SemanticMarker::Range> ifdefedOutBlocks() const;
|
||||
SemanticMarker::Ptr semanticMarker() const;
|
||||
|
||||
private:
|
||||
void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info) override;
|
||||
|
||||
SemanticMarker::Ptr m_marker;
|
||||
};
|
||||
|
||||
|
@@ -144,9 +144,6 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
|
||||
void ClangEditorDocumentProcessor::run()
|
||||
{
|
||||
// Run clang parser
|
||||
const CppTools::WorkingCopy workingCopy
|
||||
= CppTools::CppModelManager::instance()->workingCopy();
|
||||
|
||||
disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
||||
this, &ClangEditorDocumentProcessor::onParserFinished);
|
||||
m_parserWatcher.cancel();
|
||||
@@ -155,7 +152,9 @@ void ClangEditorDocumentProcessor::run()
|
||||
m_parserRevision = revision();
|
||||
connect(&m_parserWatcher, &QFutureWatcher<void>::finished,
|
||||
this, &ClangEditorDocumentProcessor::onParserFinished);
|
||||
const QFuture<void> future = QtConcurrent::run(&runParser, parser(), workingCopy);
|
||||
const QFuture<void> future = QtConcurrent::run(&runParser,
|
||||
parser(),
|
||||
ClangEditorDocumentParser::InMemoryInfo(true));
|
||||
m_parserWatcher.setFuture(future);
|
||||
|
||||
// Run builtin processor
|
||||
|
@@ -76,7 +76,7 @@ QString ClangFunctionHintModel::text(int index) const
|
||||
hintText += prettyMethod.mid(end).toHtmlEscaped());
|
||||
return hintText;
|
||||
#endif
|
||||
return CompletionChunksToTextConverter::convert(m_functionSymbols.at(index).chunks());
|
||||
return CompletionChunksToTextConverter::convertToFunctionSignature(m_functionSymbols.at(index).chunks());
|
||||
}
|
||||
|
||||
int ClangFunctionHintModel::activeArgument(const QString &prefix) const
|
||||
|
@@ -32,7 +32,6 @@
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
|
||||
@@ -58,15 +57,9 @@ namespace Utils {
|
||||
|
||||
Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun")
|
||||
|
||||
UnsavedFiles createUnsavedFiles(WorkingCopy workingCopy)
|
||||
UnsavedFiles createUnsavedFiles(const WorkingCopy &workingCopy,
|
||||
const ::Utils::FileNameList &modifiedFiles)
|
||||
{
|
||||
// TODO: change the modelmanager to hold one working copy, and amend it every time we ask for one.
|
||||
// TODO: Reason: the UnsavedFile needs a QByteArray.
|
||||
|
||||
QSet< ::Utils::FileName> modifiedFiles;
|
||||
foreach (IDocument *doc, DocumentManager::modifiedDocuments())
|
||||
modifiedFiles.insert(doc->filePath());
|
||||
|
||||
UnsavedFiles result;
|
||||
QHashIterator< ::Utils::FileName, QPair<QByteArray, unsigned> > wcIter = workingCopy.iterator();
|
||||
while (wcIter.hasNext()) {
|
||||
|
@@ -43,7 +43,9 @@ namespace Utils {
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(verboseRunLog)
|
||||
|
||||
ClangCodeModel::Internal::UnsavedFiles createUnsavedFiles(CppTools::WorkingCopy workingCopy);
|
||||
ClangCodeModel::Internal::UnsavedFiles createUnsavedFiles(
|
||||
const CppTools::WorkingCopy &workingCopy,
|
||||
const ::Utils::FileNameList &modifiedFiles);
|
||||
|
||||
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
||||
CppTools::ProjectFile::Kind fileKind);
|
||||
|
@@ -30,15 +30,53 @@
|
||||
|
||||
#include "completionchunkstotextconverter.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
void CompletionChunksToTextConverter::parseChunks(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks)
|
||||
{
|
||||
m_text.clear();
|
||||
m_placeholderPositions.clear();
|
||||
|
||||
for (const auto &codeCompletionChunk : codeCompletionChunks)
|
||||
parse(codeCompletionChunk);
|
||||
m_codeCompletionChunks = codeCompletionChunks;
|
||||
|
||||
addExtraVerticalSpaceBetweenBraces();
|
||||
|
||||
std::for_each(m_codeCompletionChunks.cbegin(),
|
||||
m_codeCompletionChunks.cend(),
|
||||
[this] (const ClangBackEnd::CodeCompletionChunk &chunk)
|
||||
{
|
||||
parse(chunk);
|
||||
m_previousCodeCompletionChunk = chunk;
|
||||
});
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::setAddPlaceHolderText(bool addPlaceHolderText)
|
||||
{
|
||||
m_addPlaceHolderText = addPlaceHolderText;
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::setAddPlaceHolderPositions(bool addPlaceHolderPositions)
|
||||
{
|
||||
m_addPlaceHolderPositions = addPlaceHolderPositions;
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::setAddResultType(bool addResultType)
|
||||
{
|
||||
m_addResultType = addResultType;
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::setAddSpaces(bool addSpaces)
|
||||
{
|
||||
m_addSpaces = addSpaces;
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::setAddExtraVerticalSpaceBetweenBraces(bool addExtraVerticalSpaceBetweenBraces)
|
||||
{
|
||||
m_addExtraVerticalSpaceBetweenBraces = addExtraVerticalSpaceBetweenBraces;
|
||||
}
|
||||
|
||||
const QString &CompletionChunksToTextConverter::text() const
|
||||
@@ -46,9 +84,42 @@ const QString &CompletionChunksToTextConverter::text() const
|
||||
return m_text;
|
||||
}
|
||||
|
||||
QString CompletionChunksToTextConverter::convert(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks)
|
||||
const std::vector<int> &CompletionChunksToTextConverter::placeholderPositions() const
|
||||
{
|
||||
return m_placeholderPositions;
|
||||
}
|
||||
|
||||
bool CompletionChunksToTextConverter::hasPlaceholderPositions() const
|
||||
{
|
||||
return m_placeholderPositions.size() > 0;
|
||||
}
|
||||
|
||||
QString CompletionChunksToTextConverter::convertToFunctionSignature(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks)
|
||||
{
|
||||
CompletionChunksToTextConverter converter;
|
||||
converter.setAddPlaceHolderText(true);
|
||||
converter.setAddResultType(true);
|
||||
|
||||
converter.parseChunks(codeCompletionChunks);
|
||||
|
||||
return converter.text();
|
||||
}
|
||||
|
||||
QString CompletionChunksToTextConverter::convertToName(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks)
|
||||
{
|
||||
CompletionChunksToTextConverter converter;
|
||||
|
||||
converter.parseChunks(codeCompletionChunks);
|
||||
|
||||
return converter.text();
|
||||
}
|
||||
|
||||
QString CompletionChunksToTextConverter::convertToToolTip(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks)
|
||||
{
|
||||
CompletionChunksToTextConverter converter;
|
||||
converter.setAddPlaceHolderText(true);
|
||||
converter.setAddSpaces(true);
|
||||
converter.setAddExtraVerticalSpaceBetweenBraces(true);
|
||||
|
||||
converter.parseChunks(codeCompletionChunks);
|
||||
|
||||
@@ -62,17 +133,26 @@ void CompletionChunksToTextConverter::parse(const ClangBackEnd::CodeCompletionCh
|
||||
switch (codeCompletionChunk.kind()) {
|
||||
case CodeCompletionChunk::ResultType: parseResultType(codeCompletionChunk.text()); break;
|
||||
case CodeCompletionChunk::Optional: parseOptional(codeCompletionChunk); break;
|
||||
case CodeCompletionChunk::Placeholder: parsePlaceHolder(codeCompletionChunk); break;
|
||||
case CodeCompletionChunk::LeftParen: parseLeftParen(codeCompletionChunk); break;
|
||||
case CodeCompletionChunk::LeftBrace: parseLeftBrace(codeCompletionChunk); break;
|
||||
default: parseText(codeCompletionChunk.text()); break;
|
||||
}
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::parseResultType(const Utf8String &resultTypeText)
|
||||
{
|
||||
m_text += resultTypeText.toString() + QChar(QChar::Space);
|
||||
if (m_addResultType)
|
||||
m_text += resultTypeText.toString() + QChar(QChar::Space);
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::parseText(const Utf8String &text)
|
||||
{
|
||||
if (canAddSpace()
|
||||
&& m_previousCodeCompletionChunk.kind() == ClangBackEnd::CodeCompletionChunk::RightBrace) {
|
||||
m_text += QChar(QChar::Space);
|
||||
}
|
||||
|
||||
m_text += text.toString();
|
||||
}
|
||||
|
||||
@@ -80,11 +160,91 @@ void CompletionChunksToTextConverter::parseOptional(const ClangBackEnd::CodeComp
|
||||
{
|
||||
m_text += QStringLiteral("<i>");
|
||||
|
||||
m_text += convert(optionalCodeCompletionChunk.optionalChunks());
|
||||
m_text += convertToFunctionSignature(optionalCodeCompletionChunk.optionalChunks());
|
||||
|
||||
m_text += QStringLiteral("</i>");
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::parsePlaceHolder(const ClangBackEnd::CodeCompletionChunk &codeCompletionChunk)
|
||||
{
|
||||
if (m_addPlaceHolderText)
|
||||
m_text += codeCompletionChunk.text().toString();
|
||||
|
||||
if (m_addPlaceHolderPositions)
|
||||
m_placeholderPositions.push_back(m_text.size());
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::parseLeftParen(const ClangBackEnd::CodeCompletionChunk &codeCompletionChunk)
|
||||
{
|
||||
if (canAddSpace())
|
||||
m_text += QChar(QChar::Space);
|
||||
|
||||
m_text += codeCompletionChunk.text().toString();
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::parseLeftBrace(const ClangBackEnd::CodeCompletionChunk &codeCompletionChunk)
|
||||
{
|
||||
if (canAddSpace())
|
||||
m_text += QChar(QChar::Space);
|
||||
|
||||
m_text += codeCompletionChunk.text().toString();
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::addExtraVerticalSpaceBetweenBraces()
|
||||
{
|
||||
if (m_addExtraVerticalSpaceBetweenBraces)
|
||||
addExtraVerticalSpaceBetweenBraces(m_codeCompletionChunks.begin());
|
||||
}
|
||||
|
||||
void CompletionChunksToTextConverter::addExtraVerticalSpaceBetweenBraces(const QVector<ClangBackEnd::CodeCompletionChunk>::iterator &begin)
|
||||
{
|
||||
using ClangBackEnd::CodeCompletionChunk;
|
||||
|
||||
const auto leftBraceCompare = [] (const CodeCompletionChunk &chunk) {
|
||||
return chunk.kind() == CodeCompletionChunk::LeftBrace;
|
||||
};
|
||||
|
||||
const auto rightBraceCompare = [] (const CodeCompletionChunk &chunk) {
|
||||
return chunk.kind() == CodeCompletionChunk::RightBrace;
|
||||
};
|
||||
|
||||
const auto verticalSpaceCompare = [] (const CodeCompletionChunk &chunk) {
|
||||
return chunk.kind() == CodeCompletionChunk::VerticalSpace;
|
||||
};
|
||||
|
||||
auto leftBrace = std::find_if(begin, m_codeCompletionChunks.end(), leftBraceCompare);
|
||||
|
||||
if (leftBrace != m_codeCompletionChunks.end()) {
|
||||
auto rightBrace = std::find_if(leftBrace, m_codeCompletionChunks.end(), rightBraceCompare);
|
||||
|
||||
if (rightBrace != m_codeCompletionChunks.end()) {
|
||||
auto verticalSpaceCount = std::count_if(leftBrace, rightBrace, verticalSpaceCompare);
|
||||
|
||||
if (verticalSpaceCount <= 1) {
|
||||
auto distance = std::distance(leftBrace, rightBrace);
|
||||
CodeCompletionChunk verticalSpaceChunck(CodeCompletionChunk::VerticalSpace,
|
||||
Utf8StringLiteral("\n"));
|
||||
auto verticalSpace = m_codeCompletionChunks.insert(std::next(leftBrace),
|
||||
verticalSpaceChunck);
|
||||
std::advance(verticalSpace, distance);
|
||||
rightBrace = verticalSpace;
|
||||
}
|
||||
|
||||
auto begin = std::next(rightBrace);
|
||||
|
||||
if (begin != m_codeCompletionChunks.end())
|
||||
addExtraVerticalSpaceBetweenBraces(begin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CompletionChunksToTextConverter::canAddSpace() const
|
||||
{
|
||||
return m_addSpaces
|
||||
&& m_previousCodeCompletionChunk.kind() != ClangBackEnd::CodeCompletionChunk::HorizontalSpace
|
||||
&& m_previousCodeCompletionChunk.kind() != ClangBackEnd::CodeCompletionChunk::RightAngle;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangCodeModel
|
||||
|
||||
|
@@ -37,6 +37,8 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
@@ -45,18 +47,42 @@ class CompletionChunksToTextConverter
|
||||
public:
|
||||
void parseChunks(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks);
|
||||
|
||||
void setAddPlaceHolderText(bool addPlaceHolderText);
|
||||
void setAddPlaceHolderPositions(bool addPlaceHolderPositions);
|
||||
void setAddResultType(bool addResultType);
|
||||
void setAddSpaces(bool addSpaces);
|
||||
void setAddExtraVerticalSpaceBetweenBraces(bool addExtraVerticalSpaceBetweenBraces);
|
||||
|
||||
const QString &text() const;
|
||||
const std::vector<int> &placeholderPositions() const;
|
||||
bool hasPlaceholderPositions() const;
|
||||
|
||||
static QString convert(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks);
|
||||
|
||||
static QString convertToFunctionSignature(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks);
|
||||
static QString convertToName(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks);
|
||||
static QString convertToToolTip(const QVector<ClangBackEnd::CodeCompletionChunk> &codeCompletionChunks);
|
||||
private:
|
||||
void parse(const ClangBackEnd::CodeCompletionChunk & codeCompletionChunk);
|
||||
void parseResultType(const Utf8String &text);
|
||||
void parseText(const Utf8String &text);
|
||||
void parseOptional(const ClangBackEnd::CodeCompletionChunk & optionalCodeCompletionChunk);
|
||||
void parseOptional(const ClangBackEnd::CodeCompletionChunk &optionalCodeCompletionChunk);
|
||||
void parsePlaceHolder(const ClangBackEnd::CodeCompletionChunk &codeCompletionChunk);
|
||||
void parseLeftParen(const ClangBackEnd::CodeCompletionChunk &codeCompletionChunk);
|
||||
void parseLeftBrace(const ClangBackEnd::CodeCompletionChunk &codeCompletionChunk);
|
||||
void addExtraVerticalSpaceBetweenBraces();
|
||||
void addExtraVerticalSpaceBetweenBraces(const QVector<ClangBackEnd::CodeCompletionChunk>::iterator &);
|
||||
|
||||
bool canAddSpace() const;
|
||||
|
||||
private:
|
||||
std::vector<int> m_placeholderPositions;
|
||||
QVector<ClangBackEnd::CodeCompletionChunk> m_codeCompletionChunks;
|
||||
ClangBackEnd::CodeCompletionChunk m_previousCodeCompletionChunk;
|
||||
QString m_text;
|
||||
bool m_addPlaceHolderText = false;
|
||||
bool m_addPlaceHolderPositions = false;
|
||||
bool m_addResultType = false;
|
||||
bool m_addSpaces = false;
|
||||
bool m_addExtraVerticalSpaceBetweenBraces = false;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -71,10 +71,15 @@ using namespace ClangCodeModel::Internal;
|
||||
|
||||
namespace {
|
||||
|
||||
QString _(const char text[]) { return QString::fromUtf8(text); }
|
||||
QString _(const char text[])
|
||||
{ return QString::fromUtf8(text); }
|
||||
|
||||
QString qrcPath(const QByteArray relativeFilePath)
|
||||
{ return QLatin1String(":/unittests/ClangCodeModel/") + QString::fromUtf8(relativeFilePath); }
|
||||
|
||||
QString fileName(const QString &filePath)
|
||||
{ return QFileInfo(filePath).fileName(); }
|
||||
|
||||
struct LogOutput
|
||||
{
|
||||
LogOutput(const QString &text) : text(text.toUtf8()) {}
|
||||
@@ -260,8 +265,8 @@ QString toString(const FileContainer &fileContainer)
|
||||
{
|
||||
QString out;
|
||||
QTextStream ts(&out);
|
||||
ts << " Path: " << QFileInfo(fileContainer.filePath().toString()).fileName()
|
||||
<< " ProjectPart: " << fileContainer.projectPartId().toString() << "\n";
|
||||
ts << " Path: " << fileName(fileContainer.filePath().toString())
|
||||
<< " ProjectPart: " << fileName(fileContainer.projectPartId().toString()) << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -279,7 +284,7 @@ QString toString(const ProjectPartContainer &projectPartContainer)
|
||||
QString out;
|
||||
QTextStream ts(&out);
|
||||
ts << " ProjectPartContainer"
|
||||
<< " id: " << QFileInfo(projectPartContainer.projectPartId().toString()).fileName();
|
||||
<< " id: " << fileName(projectPartContainer.projectPartId().toString());
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -330,7 +335,7 @@ QString toString(const UnregisterProjectPartsForCodeCompletionCommand &command)
|
||||
QTextStream ts(&out);
|
||||
|
||||
ts << "UnregisterProjectPartsForCodeCompletionCommand\n"
|
||||
<< command.filePaths().join(Utf8String::fromUtf8(",")).toByteArray() << "\n";
|
||||
<< command.projectPartIds().join(Utf8String::fromUtf8(",")).toByteArray() << "\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@@ -180,7 +180,7 @@ void EditorManagerPlaceHolder::currentModeChanged(IMode *mode)
|
||||
static EditorManager *m_instance = 0;
|
||||
static EditorManagerPrivate *d;
|
||||
|
||||
static int extractNumericSuffix(QString *fileName)
|
||||
static int extractNumericSuffix(QString *fileName, QString *postfix = 0)
|
||||
{
|
||||
int i = fileName->length() - 1;
|
||||
for (; i >= 0; --i) {
|
||||
@@ -195,6 +195,8 @@ static int extractNumericSuffix(QString *fileName)
|
||||
const QString suffix = fileName->mid(i + 1);
|
||||
const int result = suffix.toInt(&ok);
|
||||
if (suffix.isEmpty() || ok) {
|
||||
if (postfix)
|
||||
*postfix = fileName->mid(i);
|
||||
fileName->truncate(i);
|
||||
return result;
|
||||
}
|
||||
@@ -2552,25 +2554,15 @@ IEditor *EditorManager::openEditorAt(const QString &fileName, int line, int colu
|
||||
fileName, line, column, editorId, flags, newEditor);
|
||||
}
|
||||
|
||||
// Extract line number suffix. Return the suffix (e.g. ":132") and truncates the filename accordingly.
|
||||
QString EditorManager::splitLineNumber(QString *fileName)
|
||||
// Extract line and column number suffix. Return the suffix (e.g. ":132") and truncates the filename accordingly.
|
||||
QString EditorManager::splitLineAndColumnNumber(QString *fileName)
|
||||
{
|
||||
int i = fileName->length() - 1;
|
||||
for (; i >= 0; --i) {
|
||||
if (!fileName->at(i).isNumber())
|
||||
break;
|
||||
}
|
||||
if (i == -1)
|
||||
return QString();
|
||||
const QChar c = fileName->at(i);
|
||||
if (c == QLatin1Char(':') || c == QLatin1Char('+')) {
|
||||
const QString result = fileName->mid(i + 1);
|
||||
bool ok;
|
||||
result.toInt(&ok);
|
||||
if (result.isEmpty() || ok) {
|
||||
fileName->truncate(i);
|
||||
return QString(c) + result;
|
||||
}
|
||||
QString postfix;
|
||||
if (extractNumericSuffix(fileName, &postfix)) {
|
||||
QString previousPostfix;
|
||||
if (extractNumericSuffix(fileName, &previousPostfix))
|
||||
postfix.prepend(previousPostfix);
|
||||
return postfix;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
@@ -109,7 +109,7 @@ public:
|
||||
};
|
||||
Q_DECLARE_FLAGS(OpenEditorFlags, OpenEditorFlag)
|
||||
|
||||
static QString splitLineNumber(QString *fileName);
|
||||
static QString splitLineAndColumnNumber(QString *fileName);
|
||||
static IEditor *openEditor(const QString &fileName, Id editorId = Id(),
|
||||
OpenEditorFlags flags = NoFlags, bool *newEditor = 0);
|
||||
static IEditor *openEditorAt(const QString &fileName, int line, int column = 0,
|
||||
|
@@ -103,7 +103,7 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
|
||||
QList<LocatorFilterEntry> betterEntries;
|
||||
QList<LocatorFilterEntry> goodEntries;
|
||||
QString needle = trimWildcards(QDir::fromNativeSeparators(origEntry));
|
||||
const QString lineNoSuffix = EditorManager::splitLineNumber(&needle);
|
||||
const QString lineNoSuffix = EditorManager::splitLineAndColumnNumber(&needle);
|
||||
QStringMatcher matcher(needle, Qt::CaseInsensitive);
|
||||
const QChar asterisk = QLatin1Char('*');
|
||||
QRegExp regexp(asterisk + needle+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
||||
|
@@ -119,7 +119,7 @@ QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<LocatorF
|
||||
}
|
||||
// file names can match with +linenumber or :linenumber
|
||||
name = entry;
|
||||
const QString lineNoSuffix = EditorManager::splitLineNumber(&name);
|
||||
const QString lineNoSuffix = EditorManager::splitLineAndColumnNumber(&name);
|
||||
name = QFileInfo(name).fileName();
|
||||
foreach (const QString &file, files) {
|
||||
if (future.isCanceled())
|
||||
|
@@ -64,7 +64,7 @@ QList<LocatorFilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locat
|
||||
QList<LocatorFilterEntry> goodEntries;
|
||||
QList<LocatorFilterEntry> betterEntries;
|
||||
QString entry = entry_;
|
||||
const QString lineNoSuffix = EditorManager::splitLineNumber(&entry);
|
||||
const QString lineNoSuffix = EditorManager::splitLineAndColumnNumber(&entry);
|
||||
const QChar asterisk = QLatin1Char('*');
|
||||
QString pattern = QString(asterisk);
|
||||
pattern += entry;
|
||||
|
@@ -268,9 +268,11 @@ void CppEditorDocument::setPreprocessorSettings(const CppTools::ProjectPart::Ptr
|
||||
{
|
||||
CppTools::BaseEditorDocumentParser *parser = processor()->parser();
|
||||
QTC_ASSERT(parser, return);
|
||||
if (parser->projectPart() != projectPart || parser->editorDefines() != defines) {
|
||||
parser->setProjectPart(projectPart);
|
||||
parser->setEditorDefines(defines);
|
||||
if (parser->projectPart() != projectPart || parser->configuration().editorDefines != defines) {
|
||||
CppTools::BaseEditorDocumentParser::Configuration config = parser->configuration();
|
||||
config.manuallySetProjectPart = projectPart;
|
||||
config.editorDefines = defines;
|
||||
parser->setConfiguration(config);
|
||||
|
||||
emit preprocessorSettingsChanged(!defines.trimmed().isEmpty());
|
||||
}
|
||||
|
@@ -1832,7 +1832,7 @@ NameAST *nameUnderCursor(const QList<AST *> &path)
|
||||
|
||||
bool canLookupDefinition(const CppQuickFixInterface &interface, const NameAST *nameAst)
|
||||
{
|
||||
QTC_ASSERT(nameAst, return false);
|
||||
QTC_ASSERT(nameAst && nameAst->name, return false);
|
||||
|
||||
// Find the enclosing scope
|
||||
unsigned line, column;
|
||||
@@ -1909,7 +1909,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
|
||||
QuickFixOperations &result)
|
||||
{
|
||||
const NameAST *nameAst = nameUnderCursor(interface.path());
|
||||
if (!nameAst)
|
||||
if (!nameAst || !nameAst->name)
|
||||
return;
|
||||
|
||||
if (canLookupDefinition(interface, nameAst))
|
||||
@@ -5852,7 +5852,7 @@ bool onConnectOrDisconnectCall(AST *ast, const ExpressionListAST **arguments)
|
||||
return false;
|
||||
|
||||
const IdExpressionAST *idExpr = call->base_expression->asIdExpression();
|
||||
if (!idExpr)
|
||||
if (!idExpr || !idExpr->name || !idExpr->name->name)
|
||||
return false;
|
||||
|
||||
const ExpressionListAST *args = call->expression_list;
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "baseeditordocumentparser.h"
|
||||
#include "baseeditordocumentprocessor.h"
|
||||
|
||||
#include "cpptoolsreuse.h"
|
||||
#include "editordocumenthandle.h"
|
||||
|
||||
namespace CppTools {
|
||||
@@ -44,15 +45,18 @@ namespace CppTools {
|
||||
It's meant to be used in the C++ editor to get precise results by using
|
||||
the "best" project part for a file.
|
||||
|
||||
Derived classes are expected to implement update() by using the protected
|
||||
mutex, updateProjectPart() and by respecting the options set by the client.
|
||||
Derived classes are expected to implement updateHelper() this way:
|
||||
|
||||
\list
|
||||
\li Get a copy of the configuration and the last state.
|
||||
\li Work on the data and do whatever is necessary. At least, update
|
||||
the project part with the help of determineProjectPart().
|
||||
\li Ensure the new state is set before updateHelper() returns.
|
||||
\endlist
|
||||
*/
|
||||
|
||||
BaseEditorDocumentParser::BaseEditorDocumentParser(const QString &filePath)
|
||||
: m_mutex(QMutex::Recursive)
|
||||
, m_filePath(filePath)
|
||||
, m_usePrecompiledHeaders(false)
|
||||
, m_editorDefinesChangedSinceLastUpdate(false)
|
||||
: m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,44 +69,39 @@ QString BaseEditorDocumentParser::filePath() const
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
BaseEditorDocumentParser::Configuration BaseEditorDocumentParser::configuration() const
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
return m_configuration;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setConfiguration(const Configuration &configuration)
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
m_configuration = configuration;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::update(const InMemoryInfo &info)
|
||||
{
|
||||
QMutexLocker locker(&m_updateIsRunning);
|
||||
updateHelper(info);
|
||||
}
|
||||
|
||||
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setState(const State &state)
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
ProjectPart::Ptr BaseEditorDocumentParser::projectPart() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_projectPart;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setProjectPart(ProjectPart::Ptr projectPart)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_manuallySetProjectPart = projectPart;
|
||||
}
|
||||
|
||||
bool BaseEditorDocumentParser::usePrecompiledHeaders() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_usePrecompiledHeaders;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setUsePrecompiledHeaders(bool usePrecompiledHeaders)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_usePrecompiledHeaders = usePrecompiledHeaders;
|
||||
}
|
||||
|
||||
QByteArray BaseEditorDocumentParser::editorDefines() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_editorDefines;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::setEditorDefines(const QByteArray &editorDefines)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (editorDefines != m_editorDefines) {
|
||||
m_editorDefines = editorDefines;
|
||||
m_editorDefinesChangedSinceLastUpdate = true;
|
||||
}
|
||||
return state().projectPart;
|
||||
}
|
||||
|
||||
BaseEditorDocumentParser *BaseEditorDocumentParser::get(const QString &filePath)
|
||||
@@ -115,43 +114,44 @@ BaseEditorDocumentParser *BaseEditorDocumentParser::get(const QString &filePath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::updateProjectPart()
|
||||
ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &filePath,
|
||||
const Configuration &config,
|
||||
const State &state)
|
||||
{
|
||||
if (m_manuallySetProjectPart) {
|
||||
m_projectPart = m_manuallySetProjectPart;
|
||||
return;
|
||||
}
|
||||
if (config.manuallySetProjectPart)
|
||||
return config.manuallySetProjectPart;
|
||||
|
||||
ProjectPart::Ptr projectPart = state.projectPart;
|
||||
|
||||
CppModelManager *cmm = CppModelManager::instance();
|
||||
QList<ProjectPart::Ptr> projectParts = cmm->projectPart(m_filePath);
|
||||
QList<ProjectPart::Ptr> projectParts = cmm->projectPart(filePath);
|
||||
if (projectParts.isEmpty()) {
|
||||
if (m_projectPart)
|
||||
if (projectPart)
|
||||
// File is not directly part of any project, but we got one before. We will re-use it,
|
||||
// because re-calculating this can be expensive when the dependency table is big.
|
||||
return;
|
||||
return projectPart;
|
||||
|
||||
// Fall-back step 1: Get some parts through the dependency table:
|
||||
projectParts = cmm->projectPartFromDependencies(Utils::FileName::fromString(m_filePath));
|
||||
projectParts = cmm->projectPartFromDependencies(Utils::FileName::fromString(filePath));
|
||||
if (projectParts.isEmpty())
|
||||
// Fall-back step 2: Use fall-back part from the model manager:
|
||||
m_projectPart = cmm->fallbackProjectPart();
|
||||
projectPart = cmm->fallbackProjectPart();
|
||||
else
|
||||
m_projectPart = projectParts.first();
|
||||
projectPart = projectParts.first();
|
||||
} else {
|
||||
if (!projectParts.contains(m_projectPart))
|
||||
if (!projectParts.contains(projectPart))
|
||||
// Apparently the project file changed, so update our project part.
|
||||
m_projectPart = projectParts.first();
|
||||
projectPart = projectParts.first();
|
||||
}
|
||||
|
||||
return projectPart;
|
||||
}
|
||||
|
||||
bool BaseEditorDocumentParser::editorDefinesChanged() const
|
||||
BaseEditorDocumentParser::InMemoryInfo::InMemoryInfo(bool withModifiedFiles)
|
||||
: workingCopy(CppTools::CppModelManager::instance()->workingCopy())
|
||||
{
|
||||
return m_editorDefinesChangedSinceLastUpdate;
|
||||
}
|
||||
|
||||
void BaseEditorDocumentParser::resetEditorDefinesChanged()
|
||||
{
|
||||
m_editorDefinesChangedSinceLastUpdate = false;
|
||||
if (withModifiedFiles)
|
||||
modifiedFiles = CppTools::modifiedFiles();
|
||||
}
|
||||
|
||||
} // namespace CppTools
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cpptools_global.h"
|
||||
#include "cppworkingcopy.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@@ -42,45 +43,54 @@ class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static BaseEditorDocumentParser *get(const QString &filePath);
|
||||
|
||||
struct Configuration {
|
||||
bool usePrecompiledHeaders = false;
|
||||
QByteArray editorDefines;
|
||||
ProjectPart::Ptr manuallySetProjectPart;
|
||||
};
|
||||
|
||||
public:
|
||||
BaseEditorDocumentParser(const QString &filePath);
|
||||
virtual ~BaseEditorDocumentParser();
|
||||
|
||||
QString filePath() const;
|
||||
Configuration configuration() const;
|
||||
void setConfiguration(const Configuration &configuration);
|
||||
|
||||
virtual void update(WorkingCopy workingCopy) = 0;
|
||||
struct CPPTOOLS_EXPORT InMemoryInfo {
|
||||
InMemoryInfo(bool withModifiedFiles);
|
||||
|
||||
WorkingCopy workingCopy;
|
||||
Utils::FileNameList modifiedFiles;
|
||||
};
|
||||
void update(const InMemoryInfo &info);
|
||||
|
||||
ProjectPart::Ptr projectPart() const;
|
||||
void setProjectPart(ProjectPart::Ptr projectPart);
|
||||
|
||||
bool usePrecompiledHeaders() const;
|
||||
void setUsePrecompiledHeaders(bool usePrecompiledHeaders);
|
||||
|
||||
QByteArray editorDefines() const;
|
||||
void setEditorDefines(const QByteArray &editorDefines);
|
||||
|
||||
public:
|
||||
static BaseEditorDocumentParser *get(const QString &filePath);
|
||||
|
||||
protected:
|
||||
void updateProjectPart();
|
||||
struct State {
|
||||
QByteArray editorDefines;
|
||||
ProjectPart::Ptr projectPart;
|
||||
};
|
||||
State state() const;
|
||||
void setState(const State &state);
|
||||
|
||||
bool editorDefinesChanged() const;
|
||||
void resetEditorDefinesChanged();
|
||||
static ProjectPart::Ptr determineProjectPart(const QString &filePath,
|
||||
const Configuration &config,
|
||||
const State &state);
|
||||
|
||||
protected:
|
||||
mutable QMutex m_mutex;
|
||||
mutable QMutex m_stateAndConfigurationMutex;
|
||||
|
||||
private:
|
||||
virtual void updateHelper(const InMemoryInfo &inMemoryInfo) = 0;
|
||||
|
||||
const QString m_filePath;
|
||||
|
||||
ProjectPart::Ptr m_projectPart;
|
||||
ProjectPart::Ptr m_manuallySetProjectPart;
|
||||
|
||||
bool m_usePrecompiledHeaders;
|
||||
|
||||
QByteArray m_editorDefines;
|
||||
bool m_editorDefinesChangedSinceLastUpdate;
|
||||
Configuration m_configuration;
|
||||
State m_state;
|
||||
mutable QMutex m_updateIsRunning;
|
||||
};
|
||||
|
||||
} // namespace CppTools
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "baseeditordocumentprocessor.h"
|
||||
#include "cppworkingcopy.h"
|
||||
|
||||
#include "cpptoolsreuse.h"
|
||||
#include "editordocumenthandle.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -118,7 +119,7 @@ QList<QTextEdit::ExtraSelection> BaseEditorDocumentProcessor::toTextEditorSelect
|
||||
|
||||
void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
|
||||
BaseEditorDocumentParser *parser,
|
||||
WorkingCopy workingCopy)
|
||||
BaseEditorDocumentParser::InMemoryInfo info)
|
||||
{
|
||||
future.setProgressRange(0, 1);
|
||||
if (future.isCanceled()) {
|
||||
@@ -126,7 +127,7 @@ void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
|
||||
return;
|
||||
}
|
||||
|
||||
parser->update(workingCopy);
|
||||
parser->update(info);
|
||||
CppModelManager::instance()
|
||||
->finishedRefreshingSourceFiles(QSet<QString>() << parser->filePath());
|
||||
|
||||
|
@@ -86,7 +86,7 @@ protected:
|
||||
|
||||
static void runParser(QFutureInterface<void> &future,
|
||||
CppTools::BaseEditorDocumentParser *parser,
|
||||
CppTools::WorkingCopy workingCopy);
|
||||
BaseEditorDocumentParser::InMemoryInfo info);
|
||||
|
||||
// Convenience
|
||||
QString filePath() const { return m_baseTextDocument->filePath().toString(); }
|
||||
|
@@ -40,19 +40,22 @@ using namespace CppTools::Internal;
|
||||
|
||||
BuiltinEditorDocumentParser::BuiltinEditorDocumentParser(const QString &filePath)
|
||||
: BaseEditorDocumentParser(filePath)
|
||||
, m_forceSnapshotInvalidation(false)
|
||||
, m_releaseSourceAndAST(true)
|
||||
{
|
||||
qRegisterMetaType<CPlusPlus::Snapshot>("CPlusPlus::Snapshot");
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
|
||||
void BuiltinEditorDocumentParser::updateHelper(const InMemoryInfo &info)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (filePath().isEmpty())
|
||||
return;
|
||||
|
||||
const Configuration baseConfig = configuration();
|
||||
const bool releaseSourceAndAST_ = releaseSourceAndAST();
|
||||
|
||||
State baseState = state();
|
||||
ExtraState state = extraState();
|
||||
WorkingCopy workingCopy = info.workingCopy;
|
||||
|
||||
bool invalidateSnapshot = false, invalidateConfig = false, editorDefinesChanged_ = false;
|
||||
|
||||
CppModelManager *modelManager = CppModelManager::instance();
|
||||
@@ -62,52 +65,52 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
|
||||
QString projectConfigFile;
|
||||
LanguageFeatures features = LanguageFeatures::defaultFeatures();
|
||||
|
||||
updateProjectPart();
|
||||
baseState.projectPart = determineProjectPart(filePath(), baseConfig, baseState);
|
||||
|
||||
if (m_forceSnapshotInvalidation) {
|
||||
if (state.forceSnapshotInvalidation) {
|
||||
invalidateSnapshot = true;
|
||||
m_forceSnapshotInvalidation = false;
|
||||
state.forceSnapshotInvalidation = false;
|
||||
}
|
||||
|
||||
if (const ProjectPart::Ptr part = projectPart()) {
|
||||
if (const ProjectPart::Ptr part = baseState.projectPart) {
|
||||
configFile += part->toolchainDefines;
|
||||
configFile += part->projectDefines;
|
||||
headerPaths = part->headerPaths;
|
||||
projectConfigFile = part->projectConfigFile;
|
||||
if (usePrecompiledHeaders())
|
||||
if (baseConfig.usePrecompiledHeaders)
|
||||
precompiledHeaders = part->precompiledHeaders;
|
||||
features = part->languageFeatures;
|
||||
}
|
||||
|
||||
if (configFile != m_configFile) {
|
||||
m_configFile = configFile;
|
||||
if (configFile != state.configFile) {
|
||||
state.configFile = configFile;
|
||||
invalidateSnapshot = true;
|
||||
invalidateConfig = true;
|
||||
}
|
||||
|
||||
if (editorDefinesChanged()) {
|
||||
if (baseConfig.editorDefines != baseState.editorDefines) {
|
||||
baseState.editorDefines = baseConfig.editorDefines;
|
||||
invalidateSnapshot = true;
|
||||
editorDefinesChanged_ = true;
|
||||
resetEditorDefinesChanged();
|
||||
}
|
||||
|
||||
if (headerPaths != m_headerPaths) {
|
||||
m_headerPaths = headerPaths;
|
||||
if (headerPaths != state.headerPaths) {
|
||||
state.headerPaths = headerPaths;
|
||||
invalidateSnapshot = true;
|
||||
}
|
||||
|
||||
if (projectConfigFile != m_projectConfigFile) {
|
||||
m_projectConfigFile = projectConfigFile;
|
||||
if (projectConfigFile != state.projectConfigFile) {
|
||||
state.projectConfigFile = projectConfigFile;
|
||||
invalidateSnapshot = true;
|
||||
}
|
||||
|
||||
if (precompiledHeaders != m_precompiledHeaders) {
|
||||
m_precompiledHeaders = precompiledHeaders;
|
||||
if (precompiledHeaders != state.precompiledHeaders) {
|
||||
state.precompiledHeaders = precompiledHeaders;
|
||||
invalidateSnapshot = true;
|
||||
}
|
||||
|
||||
unsigned rev = 0;
|
||||
if (Document::Ptr doc = document())
|
||||
if (Document::Ptr doc = state.snapshot.document(filePath()))
|
||||
rev = doc->revision();
|
||||
else
|
||||
invalidateSnapshot = true;
|
||||
@@ -115,26 +118,26 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
|
||||
Snapshot globalSnapshot = modelManager->snapshot();
|
||||
|
||||
if (invalidateSnapshot) {
|
||||
m_snapshot = Snapshot();
|
||||
state.snapshot = Snapshot();
|
||||
} else {
|
||||
// Remove changed files from the snapshot
|
||||
QSet<Utils::FileName> toRemove;
|
||||
foreach (const Document::Ptr &doc, m_snapshot) {
|
||||
foreach (const Document::Ptr &doc, state.snapshot) {
|
||||
const Utils::FileName fileName = Utils::FileName::fromString(doc->fileName());
|
||||
if (workingCopy.contains(fileName)) {
|
||||
if (workingCopy.get(fileName).second != doc->editorRevision())
|
||||
addFileAndDependencies(&toRemove, fileName);
|
||||
addFileAndDependencies(&state.snapshot, &toRemove, fileName);
|
||||
continue;
|
||||
}
|
||||
Document::Ptr otherDoc = globalSnapshot.document(fileName);
|
||||
if (!otherDoc.isNull() && otherDoc->revision() != doc->revision())
|
||||
addFileAndDependencies(&toRemove, fileName);
|
||||
addFileAndDependencies(&state.snapshot, &toRemove, fileName);
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
invalidateSnapshot = true;
|
||||
foreach (const Utils::FileName &fileName, toRemove)
|
||||
m_snapshot.remove(fileName);
|
||||
state.snapshot.remove(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,19 +145,19 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
|
||||
if (invalidateSnapshot) {
|
||||
const QString configurationFileName = modelManager->configurationFileName();
|
||||
if (invalidateConfig)
|
||||
m_snapshot.remove(configurationFileName);
|
||||
if (!m_snapshot.contains(configurationFileName))
|
||||
workingCopy.insert(configurationFileName, m_configFile);
|
||||
m_snapshot.remove(filePath());
|
||||
state.snapshot.remove(configurationFileName);
|
||||
if (!state.snapshot.contains(configurationFileName))
|
||||
workingCopy.insert(configurationFileName, state.configFile);
|
||||
state.snapshot.remove(filePath());
|
||||
|
||||
static const QString editorDefinesFileName
|
||||
= CppModelManager::editorConfigurationFileName();
|
||||
if (editorDefinesChanged_) {
|
||||
m_snapshot.remove(editorDefinesFileName);
|
||||
workingCopy.insert(editorDefinesFileName, editorDefines());
|
||||
state.snapshot.remove(editorDefinesFileName);
|
||||
workingCopy.insert(editorDefinesFileName, baseState.editorDefines);
|
||||
}
|
||||
|
||||
CppSourceProcessor sourceProcessor(m_snapshot, [&](const Document::Ptr &doc) {
|
||||
CppSourceProcessor sourceProcessor(state.snapshot, [&](const Document::Ptr &doc) {
|
||||
const QString fileName = doc->fileName();
|
||||
const bool isInEditor = fileName == filePath();
|
||||
Document::Ptr otherDoc = modelManager->document(fileName);
|
||||
@@ -163,68 +166,64 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
|
||||
newRev = qMax(rev + 1, newRev);
|
||||
doc->setRevision(newRev);
|
||||
modelManager->emitDocumentUpdated(doc);
|
||||
if (m_releaseSourceAndAST)
|
||||
if (releaseSourceAndAST_)
|
||||
doc->releaseSourceAndAST();
|
||||
});
|
||||
Snapshot globalSnapshot = modelManager->snapshot();
|
||||
globalSnapshot.remove(filePath());
|
||||
sourceProcessor.setGlobalSnapshot(globalSnapshot);
|
||||
sourceProcessor.setWorkingCopy(workingCopy);
|
||||
sourceProcessor.setHeaderPaths(m_headerPaths);
|
||||
sourceProcessor.setHeaderPaths(state.headerPaths);
|
||||
sourceProcessor.setLanguageFeatures(features);
|
||||
sourceProcessor.run(configurationFileName);
|
||||
if (!m_projectConfigFile.isEmpty())
|
||||
sourceProcessor.run(m_projectConfigFile);
|
||||
if (usePrecompiledHeaders()) {
|
||||
foreach (const QString &precompiledHeader, m_precompiledHeaders)
|
||||
if (!state.projectConfigFile.isEmpty())
|
||||
sourceProcessor.run(state.projectConfigFile);
|
||||
if (baseConfig.usePrecompiledHeaders) {
|
||||
foreach (const QString &precompiledHeader, state.precompiledHeaders)
|
||||
sourceProcessor.run(precompiledHeader);
|
||||
}
|
||||
if (!editorDefines().isEmpty())
|
||||
if (!baseState.editorDefines.isEmpty())
|
||||
sourceProcessor.run(editorDefinesFileName);
|
||||
sourceProcessor.run(filePath(), usePrecompiledHeaders() ? m_precompiledHeaders
|
||||
: QStringList());
|
||||
m_snapshot = sourceProcessor.snapshot();
|
||||
Snapshot newSnapshot = m_snapshot.simplified(document());
|
||||
for (Snapshot::const_iterator i = m_snapshot.begin(), ei = m_snapshot.end(); i != ei; ++i) {
|
||||
sourceProcessor.run(filePath(), baseConfig.usePrecompiledHeaders ? state.precompiledHeaders
|
||||
: QStringList());
|
||||
state.snapshot = sourceProcessor.snapshot();
|
||||
Snapshot newSnapshot = state.snapshot.simplified(state.snapshot.document(filePath()));
|
||||
for (Snapshot::const_iterator i = state.snapshot.begin(), ei = state.snapshot.end(); i != ei; ++i) {
|
||||
if (Client::isInjectedFile(i.key().toString()))
|
||||
newSnapshot.insert(i.value());
|
||||
}
|
||||
m_snapshot = newSnapshot;
|
||||
m_snapshot.updateDependencyTable();
|
||||
|
||||
emit finished(document(), m_snapshot);
|
||||
state.snapshot = newSnapshot;
|
||||
state.snapshot.updateDependencyTable();
|
||||
}
|
||||
|
||||
setState(baseState);
|
||||
setExtraState(state);
|
||||
|
||||
if (invalidateSnapshot)
|
||||
emit finished(state.snapshot.document(filePath()), state.snapshot);
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentParser::releaseResources()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_snapshot = Snapshot();
|
||||
m_forceSnapshotInvalidation = true;
|
||||
ExtraState s = extraState();
|
||||
s.snapshot = Snapshot();
|
||||
s.forceSnapshotInvalidation = true;
|
||||
setExtraState(s);
|
||||
}
|
||||
|
||||
Document::Ptr BuiltinEditorDocumentParser::document() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_snapshot.document(filePath());
|
||||
return extraState().snapshot.document(filePath());
|
||||
}
|
||||
|
||||
Snapshot BuiltinEditorDocumentParser::snapshot() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_snapshot;
|
||||
return extraState().snapshot;
|
||||
}
|
||||
|
||||
ProjectPart::HeaderPaths BuiltinEditorDocumentParser::headerPaths() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_headerPaths;
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentParser::setReleaseSourceAndAST(bool onoff)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_releaseSourceAndAST = onoff;
|
||||
return extraState().headerPaths;
|
||||
}
|
||||
|
||||
BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &filePath)
|
||||
@@ -234,12 +233,39 @@ BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &fil
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<Utils::FileName> *toRemove,
|
||||
void BuiltinEditorDocumentParser::addFileAndDependencies(Snapshot *snapshot,
|
||||
QSet<Utils::FileName> *toRemove,
|
||||
const Utils::FileName &fileName) const
|
||||
{
|
||||
QTC_ASSERT(snapshot, return);
|
||||
|
||||
toRemove->insert(fileName);
|
||||
if (fileName != Utils::FileName::fromString(filePath())) {
|
||||
Utils::FileNameList deps = m_snapshot.filesDependingOn(fileName);
|
||||
Utils::FileNameList deps = snapshot->filesDependingOn(fileName);
|
||||
toRemove->unite(QSet<Utils::FileName>::fromList(deps));
|
||||
}
|
||||
}
|
||||
|
||||
BuiltinEditorDocumentParser::ExtraState BuiltinEditorDocumentParser::extraState() const
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
return m_extraState;
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentParser::setExtraState(const ExtraState &extraState)
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
m_extraState = extraState;
|
||||
}
|
||||
|
||||
bool BuiltinEditorDocumentParser::releaseSourceAndAST() const
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
return m_releaseSourceAndAST;
|
||||
}
|
||||
|
||||
void BuiltinEditorDocumentParser::setReleaseSourceAndAST(bool release)
|
||||
{
|
||||
QMutexLocker locker(&m_stateAndConfigurationMutex);
|
||||
m_releaseSourceAndAST = release;
|
||||
}
|
||||
|
@@ -37,7 +37,6 @@
|
||||
|
||||
#include <cplusplus/CppDocument.h>
|
||||
|
||||
#include <QMutex>
|
||||
#include <QString>
|
||||
|
||||
namespace CppTools {
|
||||
@@ -49,14 +48,14 @@ class CPPTOOLS_EXPORT BuiltinEditorDocumentParser : public BaseEditorDocumentPar
|
||||
public:
|
||||
BuiltinEditorDocumentParser(const QString &filePath);
|
||||
|
||||
void update(WorkingCopy workingCopy) override;
|
||||
void releaseResources();
|
||||
bool releaseSourceAndAST() const;
|
||||
void setReleaseSourceAndAST(bool release);
|
||||
|
||||
CPlusPlus::Document::Ptr document() const;
|
||||
CPlusPlus::Snapshot snapshot() const;
|
||||
ProjectPart::HeaderPaths headerPaths() const;
|
||||
|
||||
void setReleaseSourceAndAST(bool onoff);
|
||||
void releaseResources();
|
||||
|
||||
signals:
|
||||
void finished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot);
|
||||
@@ -65,18 +64,26 @@ public:
|
||||
static BuiltinEditorDocumentParser *get(const QString &filePath);
|
||||
|
||||
private:
|
||||
void addFileAndDependencies(QSet<Utils::FileName> *toRemove, const Utils::FileName &fileName) const;
|
||||
void updateHelper(const InMemoryInfo &info) override;
|
||||
void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
|
||||
QSet<Utils::FileName> *toRemove,
|
||||
const Utils::FileName &fileName) const;
|
||||
|
||||
private:
|
||||
QByteArray m_configFile;
|
||||
struct ExtraState {
|
||||
QByteArray configFile;
|
||||
|
||||
ProjectPart::HeaderPaths m_headerPaths;
|
||||
QString m_projectConfigFile;
|
||||
QStringList m_precompiledHeaders;
|
||||
ProjectPart::HeaderPaths headerPaths;
|
||||
QString projectConfigFile;
|
||||
QStringList precompiledHeaders;
|
||||
|
||||
CPlusPlus::Snapshot m_snapshot;
|
||||
bool m_forceSnapshotInvalidation;
|
||||
bool m_releaseSourceAndAST;
|
||||
CPlusPlus::Snapshot snapshot;
|
||||
bool forceSnapshotInvalidation = false;
|
||||
};
|
||||
ExtraState extraState() const;
|
||||
void setExtraState(const ExtraState &extraState);
|
||||
|
||||
bool m_releaseSourceAndAST = true;
|
||||
ExtraState m_extraState;
|
||||
};
|
||||
|
||||
} // namespace CppTools
|
||||
|
@@ -43,8 +43,8 @@
|
||||
#include <cplusplus/CppDocument.h>
|
||||
#include <cplusplus/SimpleLexer.h>
|
||||
|
||||
#include <utils/QtConcurrentTools>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/runextensions.h>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
@@ -134,7 +134,10 @@ BuiltinEditorDocumentProcessor::BuiltinEditorDocumentProcessor(
|
||||
using namespace Internal;
|
||||
|
||||
QSharedPointer<CppCodeModelSettings> cms = CppToolsPlugin::instance()->codeModelSettings();
|
||||
m_parser.setUsePrecompiledHeaders(cms->pchUsage() != CppCodeModelSettings::PchUse_None);
|
||||
|
||||
BaseEditorDocumentParser::Configuration config = m_parser.configuration();
|
||||
config.usePrecompiledHeaders = cms->pchUsage() != CppCodeModelSettings::PchUse_None;
|
||||
m_parser.setConfiguration(config);
|
||||
|
||||
if (m_semanticHighlighter) {
|
||||
m_semanticHighlighter->setHighlightingRunner(
|
||||
@@ -163,7 +166,9 @@ BuiltinEditorDocumentProcessor::~BuiltinEditorDocumentProcessor()
|
||||
|
||||
void BuiltinEditorDocumentProcessor::run()
|
||||
{
|
||||
m_parserFuture = QtConcurrent::run(&runParser, parser(), CppTools::CppModelManager::instance()->workingCopy());
|
||||
m_parserFuture = QtConcurrent::run(&runParser,
|
||||
parser(),
|
||||
BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||
}
|
||||
|
||||
BaseEditorDocumentParser *BuiltinEditorDocumentProcessor::parser()
|
||||
|
@@ -162,7 +162,7 @@ void indexFindErrors(QFutureInterface<void> &future, const ParseParams params)
|
||||
// Parse the file as precisely as possible
|
||||
BuiltinEditorDocumentParser parser(file);
|
||||
parser.setReleaseSourceAndAST(false);
|
||||
parser.update(params.workingCopy);
|
||||
parser.update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||
CPlusPlus::Document::Ptr document = parser.document();
|
||||
QTC_ASSERT(document, return);
|
||||
|
||||
|
@@ -2188,7 +2188,7 @@ void CppCompletionAssistInterface::getCppSpecifics() const
|
||||
m_gotCppSpecifics = true;
|
||||
|
||||
if (BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName())) {
|
||||
parser->update(m_workingCopy);
|
||||
parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||
m_snapshot = parser->snapshot();
|
||||
m_headerPaths = parser->headerPaths();
|
||||
if (Document::Ptr document = parser->document())
|
||||
|
@@ -167,13 +167,11 @@ private:
|
||||
const QString &m_filePath;
|
||||
};
|
||||
|
||||
void waitForProcessedEditorDocument(const QString &filePath)
|
||||
ProjectPart::Ptr projectPartOfEditorDocument(const QString &filePath)
|
||||
{
|
||||
CppEditorDocumentHandle *editorDocument
|
||||
= CppModelManager::instance()->cppEditorDocument(filePath);
|
||||
QVERIFY(editorDocument);
|
||||
while (editorDocument->processor()->isParserRunning())
|
||||
QCoreApplication::processEvents();
|
||||
auto *editorDocument = CppModelManager::instance()->cppEditorDocument(filePath);
|
||||
QTC_ASSERT(editorDocument, return ProjectPart::Ptr());
|
||||
return editorDocument->processor()->parser()->projectPart();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@@ -914,8 +912,10 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
|
||||
|
||||
auto *parser = BuiltinEditorDocumentParser::get(fileName);
|
||||
QVERIFY(parser);
|
||||
parser->setUsePrecompiledHeaders(true);
|
||||
parser->update(mm->workingCopy());
|
||||
BaseEditorDocumentParser::Configuration config = parser->configuration();
|
||||
config.usePrecompiledHeaders = true;
|
||||
parser->setConfiguration(config);
|
||||
parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||
|
||||
// Check if defines from pch are considered
|
||||
Document::Ptr document = mm->document(fileName);
|
||||
@@ -995,8 +995,10 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
|
||||
|
||||
const QString filePath = editor->document()->filePath().toString();
|
||||
BaseEditorDocumentParser *parser = BaseEditorDocumentParser::get(filePath);
|
||||
parser->setEditorDefines(editorDefines.toUtf8());
|
||||
parser->update(mm->workingCopy());
|
||||
BaseEditorDocumentParser::Configuration config = parser->configuration();
|
||||
config.editorDefines = editorDefines.toUtf8();
|
||||
parser->setConfiguration(config);
|
||||
parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
|
||||
|
||||
Document::Ptr doc = mm->document(main1File);
|
||||
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);
|
||||
@@ -1006,7 +1008,6 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
|
||||
void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
|
||||
{
|
||||
ModelManagerTestHelper helper;
|
||||
CppModelManager *mm = CppModelManager::instance();
|
||||
|
||||
MyTestDataDir testDataDirectory(_("testdata_defines"));
|
||||
const QString fileA = testDataDirectory.file(_("main1.cpp")); // content not relevant
|
||||
@@ -1017,10 +1018,8 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
|
||||
QVERIFY(editorA);
|
||||
EditorCloser closerA(editorA);
|
||||
QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1);
|
||||
|
||||
CppEditorDocumentHandle *editorDocumentA = mm->cppEditorDocument(fileA);
|
||||
QVERIFY(editorDocumentA);
|
||||
ProjectPart::Ptr documentAProjectPart = editorDocumentA->processor()->parser()->projectPart();
|
||||
QVERIFY(TestCase::waitForProcessedEditorDocument(fileA));
|
||||
ProjectPart::Ptr documentAProjectPart = projectPartOfEditorDocument(fileA);
|
||||
QVERIFY(!documentAProjectPart->project);
|
||||
|
||||
// Open file B in editor
|
||||
@@ -1028,10 +1027,8 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
|
||||
QVERIFY(editorB);
|
||||
EditorCloser closerB(editorB);
|
||||
QCOMPARE(Core::DocumentModel::openedDocuments().size(), 2);
|
||||
|
||||
CppEditorDocumentHandle *editorDocumentB = mm->cppEditorDocument(fileB);
|
||||
QVERIFY(editorDocumentB);
|
||||
ProjectPart::Ptr documentBProjectPart = editorDocumentB->processor()->parser()->projectPart();
|
||||
QVERIFY(TestCase::waitForProcessedEditorDocument(fileB));
|
||||
ProjectPart::Ptr documentBProjectPart = projectPartOfEditorDocument(fileB);
|
||||
QVERIFY(!documentBProjectPart->project);
|
||||
|
||||
// Switch back to document A
|
||||
@@ -1053,16 +1050,14 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
|
||||
helper.updateProjectInfo(pi);
|
||||
|
||||
// ... and check for updated editor document A
|
||||
while (editorDocumentA->processor()->isParserRunning())
|
||||
QCoreApplication::processEvents();
|
||||
documentAProjectPart = editorDocumentA->processor()->parser()->projectPart();
|
||||
QVERIFY(TestCase::waitForProcessedEditorDocument(fileA));
|
||||
documentAProjectPart = projectPartOfEditorDocument(fileA);
|
||||
QCOMPARE(documentAProjectPart->project, project);
|
||||
|
||||
// Switch back to document B and check if that's updated, too
|
||||
Core::EditorManager::activateEditor(editorB);
|
||||
while (editorDocumentB->processor()->isParserRunning())
|
||||
QCoreApplication::processEvents();
|
||||
documentBProjectPart = editorDocumentB->processor()->parser()->projectPart();
|
||||
QVERIFY(TestCase::waitForProcessedEditorDocument(fileB));
|
||||
documentBProjectPart = projectPartOfEditorDocument(fileB);
|
||||
QCOMPARE(documentBProjectPart->project, project);
|
||||
}
|
||||
|
||||
@@ -1131,7 +1126,7 @@ void CppToolsPlugin::test_modelmanager_documentsAndRevisions()
|
||||
TextEditor::BaseTextEditor *editor1;
|
||||
QVERIFY(helper.openBaseTextEditor(filePath1, &editor1));
|
||||
helper.closeEditorAtEndOfTestCase(editor1);
|
||||
waitForProcessedEditorDocument(filePath1);
|
||||
QVERIFY(TestCase::waitForProcessedEditorDocument(filePath1));
|
||||
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 2U);
|
||||
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 1U);
|
||||
|
||||
@@ -1144,7 +1139,7 @@ void CppToolsPlugin::test_modelmanager_documentsAndRevisions()
|
||||
TextEditor::BaseTextEditor *editor2;
|
||||
QVERIFY(helper.openBaseTextEditor(filePath2, &editor2));
|
||||
helper.closeEditorAtEndOfTestCase(editor2);
|
||||
waitForProcessedEditorDocument(filePath2);
|
||||
QVERIFY(TestCase::waitForProcessedEditorDocument(filePath2));
|
||||
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 3U);
|
||||
VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 3U);
|
||||
|
||||
|
@@ -137,6 +137,7 @@ void CppToolsPlugin::test_cppsourceprocessor_includes_cyclic()
|
||||
const QString filePath = editor->document()->filePath().toString();
|
||||
auto *processor = BaseEditorDocumentProcessor::get(filePath);
|
||||
QVERIFY(processor);
|
||||
QVERIFY(TestCase::waitForProcessedEditorDocument(filePath));
|
||||
Snapshot snapshot = processor->snapshot();
|
||||
QCOMPARE(snapshot.size(), 3); // Configuration file included
|
||||
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "cpptoolsplugin.h"
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <texteditor/convenience.h>
|
||||
@@ -287,4 +288,13 @@ bool skipFileDueToSizeLimit(const QFileInfo &fileInfo, int limitInMB)
|
||||
return false;
|
||||
}
|
||||
|
||||
Utils::FileNameList modifiedFiles()
|
||||
{
|
||||
Utils::FileNameList files;
|
||||
foreach (Core::IDocument *doc, Core::DocumentManager::modifiedDocuments())
|
||||
files.append(doc->filePath());
|
||||
files.removeDuplicates();
|
||||
return files;
|
||||
}
|
||||
|
||||
} // CppTools
|
||||
|
@@ -44,6 +44,10 @@ class QStringRef;
|
||||
class QTextCursor;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
class FileNameList;
|
||||
} // namespace Utils
|
||||
|
||||
namespace CPlusPlus {
|
||||
class Macro;
|
||||
class Symbol;
|
||||
@@ -52,6 +56,8 @@ class LookupContext;
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
Utils::FileNameList CPPTOOLS_EXPORT modifiedFiles();
|
||||
|
||||
void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
|
||||
void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);
|
||||
|
||||
|
@@ -29,6 +29,10 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "cpptoolstestcase.h"
|
||||
|
||||
#include "baseeditordocumentparser.h"
|
||||
#include "baseeditordocumentprocessor.h"
|
||||
#include "editordocumenthandle.h"
|
||||
#include "cppmodelmanager.h"
|
||||
#include "cppworkingcopy.h"
|
||||
|
||||
@@ -140,6 +144,31 @@ bool TestCase::garbageCollectGlobalSnapshot()
|
||||
return globalSnapshot().isEmpty();
|
||||
}
|
||||
|
||||
static bool waitForProcessedEditorDocument_internal(CppEditorDocumentHandle *editorDocument,
|
||||
int timeOutInMs)
|
||||
{
|
||||
QTC_ASSERT(editorDocument, return false);
|
||||
|
||||
QTime timer;
|
||||
timer.start();
|
||||
|
||||
forever {
|
||||
if (!editorDocument->processor()->isParserRunning())
|
||||
return true;
|
||||
if (timer.elapsed() > timeOutInMs)
|
||||
return false;
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
QThread::msleep(20);
|
||||
}
|
||||
}
|
||||
|
||||
bool TestCase::waitForProcessedEditorDocument(const QString &filePath, int timeOutInMs)
|
||||
{
|
||||
auto *editorDocument = CppModelManager::instance()->cppEditorDocument(filePath);
|
||||
return waitForProcessedEditorDocument_internal(editorDocument, timeOutInMs);
|
||||
}
|
||||
|
||||
bool TestCase::parseFiles(const QSet<QString> &filePaths)
|
||||
{
|
||||
CppModelManager::instance()->updateSourceFiles(filePaths).waitForFinished();
|
||||
|
@@ -95,6 +95,8 @@ public:
|
||||
static CPlusPlus::Snapshot globalSnapshot();
|
||||
static bool garbageCollectGlobalSnapshot();
|
||||
|
||||
static bool waitForProcessedEditorDocument(const QString &filePath, int timeOutInMs = 5000);
|
||||
|
||||
enum { defaultTimeOutInMs = 30 * 1000 /*= 30 secs*/ };
|
||||
static bool waitUntilCppModelManagerIsAwareOf(
|
||||
ProjectExplorer::Project *project,
|
||||
|
@@ -802,6 +802,7 @@ bool Breakpoint::isOneShot() const { return parameters().oneShot; }
|
||||
|
||||
void Breakpoint::removeAlienBreakpoint()
|
||||
{
|
||||
b->m_state = BreakpointRemoveProceeding;
|
||||
b->deleteThis();
|
||||
}
|
||||
|
||||
|
@@ -137,23 +137,23 @@ enum BreakpointPathUsage
|
||||
|
||||
enum BreakpointParts
|
||||
{
|
||||
NoParts = 0,
|
||||
FileAndLinePart = 0x1,
|
||||
FunctionPart = 0x2,
|
||||
AddressPart = 0x4,
|
||||
ExpressionPart = 0x8,
|
||||
ConditionPart = 0x10,
|
||||
IgnoreCountPart = 0x20,
|
||||
ThreadSpecPart = 0x40,
|
||||
ModulePart = 0x80,
|
||||
TracePointPart = 0x100,
|
||||
NoParts = 0,
|
||||
FileAndLinePart = (1 << 0),
|
||||
FunctionPart = (1 << 1),
|
||||
AddressPart = (1 << 2),
|
||||
ExpressionPart = (1 << 3),
|
||||
ConditionPart = (1 << 4),
|
||||
IgnoreCountPart = (1 << 5),
|
||||
ThreadSpecPart = (1 << 6),
|
||||
ModulePart = (1 << 7),
|
||||
TracePointPart = (1 << 8),
|
||||
|
||||
EnabledPart = 0x200,
|
||||
TypePart = 0x400,
|
||||
PathUsagePart = 0x800,
|
||||
CommandPart = 0x1000,
|
||||
MessagePart = 0x2000,
|
||||
OneShotPart = 0x4000,
|
||||
EnabledPart = (1 << 9),
|
||||
TypePart = (1 << 10),
|
||||
PathUsagePart = (1 << 11),
|
||||
CommandPart = (1 << 12),
|
||||
MessagePart = (1 << 13),
|
||||
OneShotPart = (1 << 14),
|
||||
|
||||
AllConditionParts = ConditionPart|IgnoreCountPart|ThreadSpecPart
|
||||
|OneShotPart,
|
||||
|
@@ -383,13 +383,17 @@ void BreakpointDialog::setPartsEnabled(unsigned partsMask)
|
||||
m_lineEditModule->setEnabled(partsMask & ModulePart);
|
||||
|
||||
m_labelTracepoint->setEnabled(partsMask & TracePointPart);
|
||||
m_labelTracepoint->hide();
|
||||
m_checkBoxTracepoint->setEnabled(partsMask & TracePointPart);
|
||||
m_checkBoxTracepoint->hide();
|
||||
|
||||
m_labelCommands->setEnabled(partsMask & TracePointPart);
|
||||
m_textEditCommands->setEnabled(partsMask & TracePointPart);
|
||||
m_labelCommands->setEnabled(partsMask & CommandPart);
|
||||
m_textEditCommands->setEnabled(partsMask & CommandPart);
|
||||
|
||||
m_labelMessage->setEnabled(partsMask & TracePointPart);
|
||||
m_labelMessage->hide();
|
||||
m_lineEditMessage->setEnabled(partsMask & TracePointPart);
|
||||
m_lineEditMessage->hide();
|
||||
}
|
||||
|
||||
void BreakpointDialog::clearOtherParts(unsigned partsMask)
|
||||
@@ -420,9 +424,10 @@ void BreakpointDialog::clearOtherParts(unsigned partsMask)
|
||||
|
||||
if (partsMask & OneShotPart)
|
||||
m_checkBoxOneShot->setChecked(false);
|
||||
if (invertedPartsMask & CommandPart)
|
||||
m_textEditCommands->clear();
|
||||
if (invertedPartsMask & TracePointPart) {
|
||||
m_checkBoxTracepoint->setChecked(false);
|
||||
m_textEditCommands->clear();
|
||||
m_lineEditMessage->clear();
|
||||
}
|
||||
}
|
||||
@@ -456,9 +461,10 @@ void BreakpointDialog::getParts(unsigned partsMask, BreakpointParameters *data)
|
||||
|
||||
if (partsMask & OneShotPart)
|
||||
data->oneShot = m_checkBoxOneShot->isChecked();
|
||||
if (partsMask & CommandPart)
|
||||
data->command = m_textEditCommands->toPlainText().trimmed();
|
||||
if (partsMask & TracePointPart) {
|
||||
data->tracepoint = m_checkBoxTracepoint->isChecked();
|
||||
data->command = m_textEditCommands->toPlainText().trimmed();
|
||||
data->message = m_lineEditMessage->text();
|
||||
}
|
||||
}
|
||||
@@ -467,7 +473,6 @@ void BreakpointDialog::setParts(unsigned mask, const BreakpointParameters &data)
|
||||
{
|
||||
m_checkBoxEnabled->setChecked(data.enabled);
|
||||
m_comboBoxPathUsage->setCurrentIndex(data.pathUsage);
|
||||
m_textEditCommands->setPlainText(data.command);
|
||||
m_lineEditMessage->setText(data.message);
|
||||
|
||||
if (mask & FileAndLinePart) {
|
||||
@@ -508,6 +513,8 @@ void BreakpointDialog::setParts(unsigned mask, const BreakpointParameters &data)
|
||||
m_checkBoxOneShot->setChecked(data.oneShot);
|
||||
if (mask & TracePointPart)
|
||||
m_checkBoxTracepoint->setChecked(data.tracepoint);
|
||||
if (mask & CommandPart)
|
||||
m_textEditCommands->setPlainText(data.command);
|
||||
}
|
||||
|
||||
void BreakpointDialog::typeChanged(int)
|
||||
@@ -521,10 +528,10 @@ void BreakpointDialog::typeChanged(int)
|
||||
case LastBreakpointType:
|
||||
break;
|
||||
case BreakpointByFileAndLine:
|
||||
getParts(FileAndLinePart|ModulePart|AllConditionParts|TracePointPart, &m_savedParameters);
|
||||
getParts(FileAndLinePart|ModulePart|AllConditionParts|TracePointPart|CommandPart, &m_savedParameters);
|
||||
break;
|
||||
case BreakpointByFunction:
|
||||
getParts(FunctionPart|ModulePart|AllConditionParts|TracePointPart, &m_savedParameters);
|
||||
getParts(FunctionPart|ModulePart|AllConditionParts|TracePointPart|CommandPart, &m_savedParameters);
|
||||
break;
|
||||
case BreakpointAtThrow:
|
||||
case BreakpointAtCatch:
|
||||
@@ -537,10 +544,10 @@ void BreakpointDialog::typeChanged(int)
|
||||
break;
|
||||
case BreakpointByAddress:
|
||||
case WatchpointAtAddress:
|
||||
getParts(AddressPart|AllConditionParts|TracePointPart, &m_savedParameters);
|
||||
getParts(AddressPart|AllConditionParts|TracePointPart|CommandPart, &m_savedParameters);
|
||||
break;
|
||||
case WatchpointAtExpression:
|
||||
getParts(ExpressionPart|AllConditionParts|TracePointPart, &m_savedParameters);
|
||||
getParts(ExpressionPart|AllConditionParts|TracePointPart|CommandPart, &m_savedParameters);
|
||||
break;
|
||||
case BreakpointOnQmlSignalEmit:
|
||||
getParts(FunctionPart, &m_savedParameters);
|
||||
@@ -552,14 +559,14 @@ void BreakpointDialog::typeChanged(int)
|
||||
case LastBreakpointType:
|
||||
break;
|
||||
case BreakpointByFileAndLine:
|
||||
setParts(FileAndLinePart|AllConditionParts|ModulePart|TracePointPart, m_savedParameters);
|
||||
setPartsEnabled(FileAndLinePart|AllConditionParts|ModulePart|TracePointPart);
|
||||
clearOtherParts(FileAndLinePart|AllConditionParts|ModulePart|TracePointPart);
|
||||
setParts(FileAndLinePart|AllConditionParts|ModulePart|TracePointPart|CommandPart, m_savedParameters);
|
||||
setPartsEnabled(FileAndLinePart|AllConditionParts|ModulePart|TracePointPart|CommandPart);
|
||||
clearOtherParts(FileAndLinePart|AllConditionParts|ModulePart|TracePointPart|CommandPart);
|
||||
break;
|
||||
case BreakpointByFunction:
|
||||
setParts(FunctionPart|AllConditionParts|ModulePart|TracePointPart, m_savedParameters);
|
||||
setPartsEnabled(FunctionPart|AllConditionParts|ModulePart|TracePointPart);
|
||||
clearOtherParts(FunctionPart|AllConditionParts|ModulePart|TracePointPart);
|
||||
setParts(FunctionPart|AllConditionParts|ModulePart|TracePointPart|CommandPart, m_savedParameters);
|
||||
setPartsEnabled(FunctionPart|AllConditionParts|ModulePart|TracePointPart|CommandPart);
|
||||
clearOtherParts(FunctionPart|AllConditionParts|ModulePart|TracePointPart|CommandPart);
|
||||
break;
|
||||
case BreakpointAtThrow:
|
||||
case BreakpointAtCatch:
|
||||
@@ -567,8 +574,8 @@ void BreakpointDialog::typeChanged(int)
|
||||
case BreakpointAtExec:
|
||||
//case BreakpointAtVFork:
|
||||
case BreakpointAtSysCall:
|
||||
clearOtherParts(AllConditionParts|ModulePart|TracePointPart);
|
||||
setPartsEnabled(AllConditionParts|TracePointPart);
|
||||
clearOtherParts(AllConditionParts|ModulePart|TracePointPart|CommandPart);
|
||||
setPartsEnabled(AllConditionParts|TracePointPart|CommandPart);
|
||||
break;
|
||||
case BreakpointAtJavaScriptThrow:
|
||||
clearOtherParts(AllParts);
|
||||
@@ -581,14 +588,14 @@ void BreakpointDialog::typeChanged(int)
|
||||
break;
|
||||
case BreakpointByAddress:
|
||||
case WatchpointAtAddress:
|
||||
setParts(AddressPart|AllConditionParts|TracePointPart, m_savedParameters);
|
||||
setPartsEnabled(AddressPart|AllConditionParts|TracePointPart);
|
||||
clearOtherParts(AddressPart|AllConditionParts|TracePointPart);
|
||||
setParts(AddressPart|AllConditionParts|TracePointPart|CommandPart, m_savedParameters);
|
||||
setPartsEnabled(AddressPart|AllConditionParts|TracePointPart|CommandPart);
|
||||
clearOtherParts(AddressPart|AllConditionParts|TracePointPart|CommandPart);
|
||||
break;
|
||||
case WatchpointAtExpression:
|
||||
setParts(ExpressionPart|AllConditionParts|TracePointPart, m_savedParameters);
|
||||
setPartsEnabled(ExpressionPart|AllConditionParts|TracePointPart);
|
||||
clearOtherParts(ExpressionPart|AllConditionParts|TracePointPart);
|
||||
setParts(ExpressionPart|AllConditionParts|TracePointPart|CommandPart, m_savedParameters);
|
||||
setPartsEnabled(ExpressionPart|AllConditionParts|TracePointPart|CommandPart);
|
||||
clearOtherParts(ExpressionPart|AllConditionParts|TracePointPart|CommandPart);
|
||||
break;
|
||||
case BreakpointOnQmlSignalEmit:
|
||||
setParts(FunctionPart, m_savedParameters);
|
||||
|
@@ -134,6 +134,29 @@ Location::Location(const StackFrame &frame, bool marker)
|
||||
}
|
||||
|
||||
|
||||
class LocationMark : public TextMark
|
||||
{
|
||||
public:
|
||||
LocationMark(DebuggerEngine *engine, const QString &file, int line)
|
||||
: TextMark(file, line, Constants::TEXT_MARK_CATEGORY_LOCATION), m_engine(engine)
|
||||
{}
|
||||
|
||||
private:
|
||||
bool isDraggable() const { return true; }
|
||||
|
||||
void dragToLine(int line)
|
||||
{
|
||||
if (m_engine) {
|
||||
ContextData data;
|
||||
data.fileName = fileName();
|
||||
data.lineNumber = line;
|
||||
m_engine->executeJumpToLine(data);
|
||||
}
|
||||
}
|
||||
|
||||
QPointer<DebuggerEngine> m_engine;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DebuggerEnginePrivate
|
||||
@@ -319,7 +342,7 @@ public:
|
||||
|
||||
DisassemblerAgent m_disassemblerAgent;
|
||||
MemoryAgent m_memoryAgent;
|
||||
QScopedPointer<TextMark> m_locationMark;
|
||||
QScopedPointer<LocationMark> m_locationMark;
|
||||
QTimer m_locationTimer;
|
||||
|
||||
bool m_isStateDebugging;
|
||||
@@ -610,7 +633,7 @@ void DebuggerEngine::gotoLocation(const Location &loc)
|
||||
editor->document()->setProperty(Constants::OPENED_BY_DEBUGGER, true);
|
||||
|
||||
if (loc.needsMarker()) {
|
||||
d->m_locationMark.reset(new TextMark(file, line, Constants::TEXT_MARK_CATEGORY_LOCATION));
|
||||
d->m_locationMark.reset(new LocationMark(this, file, line));
|
||||
d->m_locationMark->setIcon(Internal::locationMarkIcon());
|
||||
d->m_locationMark->setPriority(TextMark::HighPriority);
|
||||
}
|
||||
@@ -1976,13 +1999,18 @@ bool DebuggerEngine::canHandleToolTip(const DebuggerToolTipContext &context) con
|
||||
return state() == InferiorStopOk && context.isCppEditor;
|
||||
}
|
||||
|
||||
void DebuggerEngine::updateWatchData(const QByteArray &iname)
|
||||
void DebuggerEngine::updateItem(const QByteArray &iname)
|
||||
{
|
||||
UpdateParameters params;
|
||||
params.partialVariable = iname;
|
||||
doUpdateLocals(params);
|
||||
}
|
||||
|
||||
void DebuggerEngine::expandItem(const QByteArray &iname)
|
||||
{
|
||||
updateItem(iname);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
|
@@ -65,6 +65,7 @@ class MemoryAgent;
|
||||
class WatchData;
|
||||
class WatchItem;
|
||||
class BreakHandler;
|
||||
class LocationMark;
|
||||
class ModulesHandler;
|
||||
class RegisterHandler;
|
||||
class StackHandler;
|
||||
@@ -191,7 +192,8 @@ public:
|
||||
DebuggerRunParameters &runParameters();
|
||||
|
||||
virtual bool canHandleToolTip(const DebuggerToolTipContext &) const;
|
||||
virtual void updateWatchData(const QByteArray &iname);
|
||||
virtual void expandItem(const QByteArray &iname); // Called when item in tree gets expanded.
|
||||
virtual void updateItem(const QByteArray &iname); // Called for fresh watch items.
|
||||
virtual void selectWatchData(const QByteArray &iname);
|
||||
|
||||
virtual void startDebugger(DebuggerRunControl *runControl);
|
||||
@@ -440,6 +442,7 @@ private:
|
||||
virtual void setState(DebuggerState state, bool forced = false);
|
||||
|
||||
friend class DebuggerEnginePrivate;
|
||||
friend class LocationMark;
|
||||
DebuggerEnginePrivate *d;
|
||||
};
|
||||
|
||||
|
@@ -252,8 +252,10 @@ void DebuggerItemManager::autoDetectGdbOrLldbDebuggers()
|
||||
foreach (const QString &base, path) {
|
||||
dir.setPath(base);
|
||||
foreach (const QString &entry, dir.entryList()) {
|
||||
if (entry.startsWith(QLatin1String("lldb-platform-")))
|
||||
if (entry.startsWith(QLatin1String("lldb-platform-"))
|
||||
|| entry.startsWith(QLatin1String("lldb-gdbserver-"))) {
|
||||
continue;
|
||||
}
|
||||
suspects.append(FileName::fromString(dir.absoluteFilePath(entry)));
|
||||
}
|
||||
}
|
||||
|
@@ -782,6 +782,16 @@ void DebuggerCommand::arg(const char *name, const char *value)
|
||||
args.append("\",");
|
||||
}
|
||||
|
||||
void DebuggerCommand::arg(const char *name, const QList<int> &list)
|
||||
{
|
||||
beginList(name);
|
||||
foreach (int item, list) {
|
||||
args.append(QByteArray::number(item));
|
||||
args.append(',');
|
||||
}
|
||||
endList();
|
||||
}
|
||||
|
||||
void DebuggerCommand::arg(const char *value)
|
||||
{
|
||||
args.append("\"");
|
||||
@@ -823,5 +833,13 @@ void DebuggerCommand::endGroup()
|
||||
args += "},";
|
||||
}
|
||||
|
||||
QByteArray DebuggerCommand::arguments() const
|
||||
{
|
||||
QByteArray result = args;
|
||||
if (result.endsWith(','))
|
||||
result.chop(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#define DEBUGGER_PROTOCOL_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#include <functional>
|
||||
@@ -64,10 +65,13 @@ public:
|
||||
void arg(const char *name, const QString &value);
|
||||
void arg(const char *name, const QByteArray &value);
|
||||
void arg(const char *name, const char *value);
|
||||
void arg(const char *name, const QList<int> &list);
|
||||
|
||||
void beginList(const char *name = 0);
|
||||
void endList();
|
||||
void beginGroup(const char *name = 0);
|
||||
void endGroup();
|
||||
QByteArray arguments() const;
|
||||
|
||||
QByteArray function;
|
||||
QByteArray args;
|
||||
|
@@ -1222,7 +1222,7 @@ static void slotTooltipOverrideRequested
|
||||
m_tooltips.push_back(tooltip);
|
||||
tooltip->setState(PendingUnshown);
|
||||
if (engine->canHandleToolTip(context)) {
|
||||
engine->updateWatchData(context.iname);
|
||||
engine->updateItem(context.iname);
|
||||
} else {
|
||||
ToolTip::show(point, DebuggerToolTipManager::tr("Expression too complex"),
|
||||
Internal::mainWindow());
|
||||
|
@@ -59,8 +59,6 @@ void GdbAttachEngine::setupEngine()
|
||||
|
||||
if (!runParameters().workingDirectory.isEmpty())
|
||||
m_gdbProc.setWorkingDirectory(runParameters().workingDirectory);
|
||||
if (runParameters().environment.size())
|
||||
m_gdbProc.setEnvironment(runParameters().environment);
|
||||
|
||||
startGdb();
|
||||
}
|
||||
|
@@ -130,7 +130,6 @@ GdbCoreEngine::readExecutableNameFromCore(const QString &debuggerCommand, const
|
||||
CoreInfo cinfo;
|
||||
#if 0
|
||||
ElfReader reader(coreFile);
|
||||
cinfo.isCore = false;
|
||||
cinfo.rawStringFromCore = QString::fromLocal8Bit(reader.readCoreName(&cinfo.isCore));
|
||||
cinfo.foundExecutableName = findExecutableFromName(cinfo.rawStringFromCore, coreFile);
|
||||
#else
|
||||
@@ -161,7 +160,6 @@ GdbCoreEngine::readExecutableNameFromCore(const QString &debuggerCommand, const
|
||||
}
|
||||
}
|
||||
}
|
||||
cinfo.isCore = false;
|
||||
#endif
|
||||
return cinfo;
|
||||
}
|
||||
|
@@ -50,7 +50,7 @@ public:
|
||||
{
|
||||
QString rawStringFromCore;
|
||||
QString foundExecutableName; // empty if no corresponding exec could be found
|
||||
bool isCore;
|
||||
bool isCore = false;
|
||||
};
|
||||
static CoreInfo readExecutableNameFromCore(const QString &debuggerCmd, const QString &coreFile);
|
||||
|
||||
|
@@ -598,8 +598,9 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
||||
// This also triggers when a temporary breakpoint is hit.
|
||||
// We do not really want that, as this loses all information.
|
||||
// FIXME: Use a special marker for this case?
|
||||
if (!bp.isOneShot())
|
||||
bp.removeAlienBreakpoint();
|
||||
// if (!bp.isOneShot()) ... is not sufficient.
|
||||
// It keeps temporary "Jump" breakpoints alive.
|
||||
bp.removeAlienBreakpoint();
|
||||
}
|
||||
} else if (asyncClass == "cmd-param-changed") {
|
||||
// New since 2012-08-09
|
||||
@@ -4260,6 +4261,18 @@ void GdbEngine::loadInitScript()
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::setEnvironmentVariables()
|
||||
{
|
||||
Environment sysEnv = Environment::systemEnvironment();
|
||||
Environment runEnv = runParameters().environment;
|
||||
foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) {
|
||||
if (item.unset)
|
||||
postCommand("unset environment " + item.name.toUtf8());
|
||||
else
|
||||
postCommand("-gdb-set environment " + item.name.toUtf8() + '=' + item.value.toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::reloadDebuggingHelpers()
|
||||
{
|
||||
runCommand("reloadDumpers");
|
||||
@@ -4570,7 +4583,7 @@ bool GdbEngine::prepareCommand()
|
||||
QtcProcess::SplitError perr;
|
||||
rp.processArgs = QtcProcess::prepareArgs(rp.processArgs, &perr,
|
||||
HostOsInfo::hostOs(),
|
||||
&rp.environment, &rp.workingDirectory).toWindowsArgs();
|
||||
nullptr, &rp.workingDirectory).toWindowsArgs();
|
||||
if (perr != QtcProcess::SplitOk) {
|
||||
// perr == BadQuoting is never returned on Windows
|
||||
// FIXME? QTCREATORBUG-2809
|
||||
|
@@ -103,6 +103,7 @@ protected: ////////// Gdb Process Management //////////
|
||||
void handleGdbExit(const DebuggerResponse &response);
|
||||
|
||||
void loadInitScript();
|
||||
void setEnvironmentVariables();
|
||||
|
||||
// Something went wrong with the adapter *before* adapterStarted() was emitted.
|
||||
// Make sure to clean up everything before emitting this signal.
|
||||
|
@@ -57,6 +57,7 @@ GdbPlainEngine::GdbPlainEngine(const DebuggerRunParameters &startParameters)
|
||||
void GdbPlainEngine::setupInferior()
|
||||
{
|
||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
||||
setEnvironmentVariables();
|
||||
if (!runParameters().processArgs.isEmpty()) {
|
||||
QString args = runParameters().processArgs;
|
||||
postCommand("-exec-arguments " + toLocalEncoding(args));
|
||||
@@ -127,9 +128,6 @@ void GdbPlainEngine::setupEngine()
|
||||
|
||||
if (!runParameters().workingDirectory.isEmpty())
|
||||
m_gdbProc.setWorkingDirectory(runParameters().workingDirectory);
|
||||
Utils::Environment env = runParameters().environment;
|
||||
if (env.size())
|
||||
m_gdbProc.setEnvironment(env);
|
||||
|
||||
startGdb(gdbArgs);
|
||||
}
|
||||
|
@@ -91,8 +91,6 @@ void GdbRemoteServerEngine::setupEngine()
|
||||
}
|
||||
if (!runParameters().workingDirectory.isEmpty())
|
||||
m_gdbProc.setWorkingDirectory(runParameters().workingDirectory);
|
||||
if (runParameters().environment.size())
|
||||
m_gdbProc.setEnvironment(runParameters().environment);
|
||||
|
||||
if (runParameters().remoteSetupNeeded)
|
||||
notifyEngineRequestRemoteSetup();
|
||||
@@ -186,6 +184,8 @@ void GdbRemoteServerEngine::setupInferior()
|
||||
if (!args.isEmpty())
|
||||
postCommand("-exec-arguments " + args.toLocal8Bit());
|
||||
|
||||
setEnvironmentVariables();
|
||||
|
||||
// This has to be issued before 'target remote'. On pre-7.0 the
|
||||
// command is not present and will result in ' No symbol table is
|
||||
// loaded. Use the "file" command.' as gdb tries to set the
|
||||
|
@@ -182,7 +182,7 @@ bool LldbEngine::prepareCommand()
|
||||
QtcProcess::SplitError perr;
|
||||
rp.processArgs = QtcProcess::prepareArgs(rp.processArgs, &perr,
|
||||
HostOsInfo::hostOs(),
|
||||
&rp.environment, &rp.workingDirectory).toWindowsArgs();
|
||||
nullptr, &rp.workingDirectory).toWindowsArgs();
|
||||
if (perr != QtcProcess::SplitOk) {
|
||||
// perr == BadQuoting is never returned on Windows
|
||||
// FIXME? QTCREATORBUG-2809
|
||||
@@ -290,6 +290,17 @@ void LldbEngine::startLldbStage2()
|
||||
|
||||
void LldbEngine::setupInferior()
|
||||
{
|
||||
Environment sysEnv = Environment::systemEnvironment();
|
||||
Environment runEnv = runParameters().environment;
|
||||
foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) {
|
||||
DebuggerCommand cmd("executeDebuggerCommand");
|
||||
if (item.unset)
|
||||
cmd.arg("command", "settings remove target.env-vars " + item.name.toUtf8());
|
||||
else
|
||||
cmd.arg("command", "settings set target.env-vars " + item.name.toUtf8() + '=' + item.value.toUtf8());
|
||||
runCommand(cmd);
|
||||
}
|
||||
|
||||
const QString path = stringSetting(ExtraDumperFile);
|
||||
if (!path.isEmpty() && QFileInfo(path).isReadable()) {
|
||||
DebuggerCommand cmd("addDumperModule");
|
||||
@@ -300,7 +311,7 @@ void LldbEngine::setupInferior()
|
||||
const QString commands = stringSetting(ExtraDumperCommands);
|
||||
if (!commands.isEmpty()) {
|
||||
DebuggerCommand cmd("executeDebuggerCommand");
|
||||
cmd.arg("commands", commands.toUtf8());
|
||||
cmd.arg("command", commands.toUtf8());
|
||||
runCommand(cmd);
|
||||
}
|
||||
|
||||
|
@@ -394,7 +394,7 @@ void PdbEngine::assignValueInDebugger(WatchItem *, const QString &expression, co
|
||||
updateLocals();
|
||||
}
|
||||
|
||||
void PdbEngine::updateWatchData(const QByteArray &iname)
|
||||
void PdbEngine::updateItem(const QByteArray &iname)
|
||||
{
|
||||
Q_UNUSED(iname);
|
||||
updateAll();
|
||||
|
@@ -96,7 +96,7 @@ private:
|
||||
|
||||
bool supportsThreads() const { return true; }
|
||||
bool isSynchronous() const { return true; }
|
||||
void updateWatchData(const QByteArray &iname);
|
||||
void updateItem(const QByteArray &iname);
|
||||
|
||||
QString mainPythonFile() const;
|
||||
QString pythonInterpreter() const;
|
||||
|
@@ -114,12 +114,20 @@ bool QmlCppEngine::canHandleToolTip(const DebuggerToolTipContext &ctx) const
|
||||
return success;
|
||||
}
|
||||
|
||||
void QmlCppEngine::updateWatchData(const QByteArray &iname)
|
||||
void QmlCppEngine::updateItem(const QByteArray &iname)
|
||||
{
|
||||
if (iname.startsWith("inspect."))
|
||||
m_qmlEngine->updateWatchData(iname);
|
||||
m_qmlEngine->updateItem(iname);
|
||||
else
|
||||
m_activeEngine->updateWatchData(iname);
|
||||
m_activeEngine->updateItem(iname);
|
||||
}
|
||||
|
||||
void QmlCppEngine::expandItem(const QByteArray &iname)
|
||||
{
|
||||
if (iname.startsWith("inspect."))
|
||||
m_qmlEngine->expandItem(iname);
|
||||
else
|
||||
m_activeEngine->expandItem(iname);
|
||||
}
|
||||
|
||||
void QmlCppEngine::selectWatchData(const QByteArray &iname)
|
||||
|
@@ -48,7 +48,8 @@ public:
|
||||
|
||||
bool canDisplayTooltip() const;
|
||||
bool canHandleToolTip(const DebuggerToolTipContext &) const;
|
||||
void updateWatchData(const QByteArray &iname);
|
||||
void updateItem(const QByteArray &iname);
|
||||
void expandItem(const QByteArray &iname);
|
||||
void selectWatchData(const QByteArray &iname);
|
||||
|
||||
void watchPoint(const QPoint &);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -77,8 +77,6 @@ private slots:
|
||||
void appStartupFailed(const QString &errorMessage);
|
||||
void appendMessage(const QString &msg, Utils::OutputFormat);
|
||||
|
||||
void synchronizeWatchers();
|
||||
|
||||
private:
|
||||
void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
|
||||
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
||||
@@ -131,7 +129,9 @@ private:
|
||||
void reloadSourceFiles();
|
||||
void reloadFullStack() {}
|
||||
|
||||
void updateWatchData(const QByteArray &iname);
|
||||
void updateAll();
|
||||
void updateItem(const QByteArray &iname);
|
||||
void expandItem(const QByteArray &iname);
|
||||
void selectWatchData(const QByteArray &iname);
|
||||
void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
|
||||
bool evaluateScript(const QString &expression);
|
||||
|
@@ -645,7 +645,12 @@ template <class T>
|
||||
void readNumericVectorHelper(std::vector<double> *v, const QByteArray &ba)
|
||||
{
|
||||
const T *p = (const T *) ba.data();
|
||||
std::copy(p, p + ba.size() / sizeof(T), std::back_insert_iterator<std::vector<double> >(*v));
|
||||
const int n = ba.size() / sizeof(T);
|
||||
v->resize(n);
|
||||
// Losing precision in case of 64 bit ints is ok here, as the result
|
||||
// is only used to plot data.
|
||||
for (int i = 0; i != n; ++i)
|
||||
(*v)[i] = static_cast<double>(p[i]);
|
||||
}
|
||||
|
||||
void readNumericVector(std::vector<double> *v, const QByteArray &rawData, DebuggerEncoding encoding)
|
||||
|
@@ -301,7 +301,6 @@ public:
|
||||
SeparatedView *m_separatedView; // Not owned.
|
||||
|
||||
QSet<QByteArray> m_expandedINames;
|
||||
QSet<QByteArray> m_fetchTriggered;
|
||||
QTimer m_requestUpdateTimer;
|
||||
|
||||
QHash<QString, DisplayFormats> m_reportedTypeFormats; // Type name -> Dumper Formats
|
||||
@@ -331,7 +330,7 @@ WatchModel::WatchModel(WatchHandler *handler, DebuggerEngine *engine)
|
||||
this, &WatchModel::updateStarted);
|
||||
|
||||
connect(action(SortStructMembers), &SavedAction::valueChanged,
|
||||
m_engine, &DebuggerEngine::updateAll);
|
||||
m_engine, &DebuggerEngine::updateLocals);
|
||||
connect(action(ShowStdNamespace), &SavedAction::valueChanged,
|
||||
m_engine, &DebuggerEngine::updateAll);
|
||||
connect(action(ShowQtNamespace), &SavedAction::valueChanged,
|
||||
@@ -670,20 +669,16 @@ bool WatchItem::canFetchMore() const
|
||||
return false;
|
||||
if (!model->m_contentsValid && !isInspect())
|
||||
return false;
|
||||
return !model->m_fetchTriggered.contains(iname);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WatchItem::fetchMore()
|
||||
{
|
||||
WatchModel *model = watchModel();
|
||||
if (model->m_fetchTriggered.contains(iname))
|
||||
return;
|
||||
|
||||
model->m_expandedINames.insert(iname);
|
||||
model->m_fetchTriggered.insert(iname);
|
||||
if (children().isEmpty()) {
|
||||
setChildrenNeeded();
|
||||
model->m_engine->updateWatchData(iname);
|
||||
model->m_engine->expandItem(iname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,12 +935,12 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
|
||||
|
||||
case LocalsTypeFormatRole:
|
||||
setTypeFormat(item->type, value.toInt());
|
||||
m_engine->updateWatchData(item->iname);
|
||||
m_engine->updateLocals();
|
||||
break;
|
||||
|
||||
case LocalsIndividualFormatRole: {
|
||||
setIndividualFormat(item->iname, value.toInt());
|
||||
m_engine->updateWatchData(item->iname);
|
||||
m_engine->updateLocals();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1177,6 +1172,8 @@ void WatchModel::insertItem(WatchItem *item)
|
||||
if (!found)
|
||||
parent->appendChild(item);
|
||||
|
||||
item->update();
|
||||
|
||||
item->walkTree([this](TreeItem *sub) { showEditValue(static_cast<WatchItem *>(sub)); });
|
||||
}
|
||||
|
||||
@@ -1304,14 +1301,14 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name)
|
||||
item->exp = exp;
|
||||
item->name = name.isEmpty() ? exp0 : name;
|
||||
item->iname = watcherName(exp);
|
||||
m_model->insertItem(item);
|
||||
saveWatchers();
|
||||
|
||||
if (m_model->m_engine->state() == DebuggerNotReady) {
|
||||
item->setAllUnneeded();
|
||||
item->setValue(QString(QLatin1Char(' ')));
|
||||
m_model->insertItem(item);
|
||||
} else {
|
||||
m_model->m_engine->updateWatchData(item->iname);
|
||||
m_model->m_engine->updateItem(item->iname);
|
||||
}
|
||||
updateWatchersWindow();
|
||||
}
|
||||
@@ -1665,7 +1662,6 @@ QString WatchHandler::editorContents()
|
||||
|
||||
void WatchHandler::scheduleResetLocation()
|
||||
{
|
||||
m_model->m_fetchTriggered.clear();
|
||||
m_model->m_contentsValid = false;
|
||||
m_model->m_resetLocationScheduled = true;
|
||||
}
|
||||
|
@@ -240,7 +240,7 @@ private:
|
||||
bool m_submitActionTriggered;
|
||||
};
|
||||
|
||||
} // namespace Git
|
||||
} // namespace Internal
|
||||
} // namespace Git
|
||||
|
||||
#endif // GITPLUGIN_H
|
||||
|
@@ -60,7 +60,7 @@ QVariant QtKitInformation::defaultValue(ProjectExplorer::Kit *k) const
|
||||
Q_UNUSED(k);
|
||||
|
||||
// find "Qt in PATH":
|
||||
QList<BaseQtVersion *> versionList = QtVersionManager::versions();
|
||||
QList<BaseQtVersion *> versionList = QtVersionManager::unsortedVersions();
|
||||
BaseQtVersion *result = findOrDefault(versionList, [](const BaseQtVersion *v) {
|
||||
return v->autodetectionSource() == QLatin1String("PATH");
|
||||
});
|
||||
@@ -174,7 +174,7 @@ int QtKitInformation::qtVersionId(const ProjectExplorer::Kit *k)
|
||||
id = -1;
|
||||
} else {
|
||||
QString source = data.toString();
|
||||
foreach (BaseQtVersion *v, QtVersionManager::versions()) {
|
||||
foreach (BaseQtVersion *v, QtVersionManager::unsortedVersions()) {
|
||||
if (v->autodetectionSource() != source)
|
||||
continue;
|
||||
id = v->uniqueId();
|
||||
|
@@ -354,7 +354,7 @@ void QtVersionManager::updateFromInstaller(bool emitSignal)
|
||||
qDebug() << "";
|
||||
}
|
||||
}
|
||||
foreach (BaseQtVersion *qtVersion, QtVersionManager::versions()) {
|
||||
foreach (BaseQtVersion *qtVersion, m_versions) {
|
||||
if (qtVersion->autodetectionSource().startsWith(QLatin1String("SDK."))) {
|
||||
if (!sdkVersions.contains(qtVersion->autodetectionSource())) {
|
||||
if (debug)
|
||||
@@ -515,6 +515,13 @@ int QtVersionManager::getUniqueId()
|
||||
return m_idcount++;
|
||||
}
|
||||
|
||||
QList<BaseQtVersion *> QtVersionManager::unsortedVersions()
|
||||
{
|
||||
QList<BaseQtVersion *> versions;
|
||||
QTC_ASSERT(isLoaded(), return versions);
|
||||
return m_versions.values();
|
||||
}
|
||||
|
||||
QList<BaseQtVersion *> QtVersionManager::versions()
|
||||
{
|
||||
QList<BaseQtVersion *> versions;
|
||||
|
@@ -56,6 +56,9 @@ public:
|
||||
static QList<BaseQtVersion *> versions();
|
||||
static QList<BaseQtVersion *> validVersions();
|
||||
|
||||
// Sorting is slow due to needing to potentially run qmake --query for each version
|
||||
static QList<BaseQtVersion *> unsortedVersions();
|
||||
|
||||
// Note: DO NOT STORE THIS POINTER!
|
||||
// The QtVersionManager will delete it at random times and you will
|
||||
// need to get a new pointer by calling this function again!
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user